From 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb Mon Sep 17 00:00:00 2001 From: onefang Date: Sun, 19 May 2019 21:24:15 +1000 Subject: Dump OpenSim 0.9.0.1 into it's own branch. --- .../Avatar/Attachments/AttachmentsModule.cs | 367 +++++++++++++++------ 1 file changed, 261 insertions(+), 106 deletions(-) (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2f67c4e..9f52a14 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -41,6 +41,8 @@ using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Services.Interfaces; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Avatar.Attachments { @@ -60,7 +62,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// A value of 0 will apply no pause. The pause is specified in milliseconds. /// public int ThrottlePer100PrimsRezzed { get; set; } - + private Scene m_scene; private IInventoryAccessModule m_invAccessModule; @@ -68,7 +70,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// Are attachments enabled? /// public bool Enabled { get; private set; } - + public string Name { get { return "Attachments Module"; } } public Type ReplaceableInterface { get { return null; } } @@ -86,14 +88,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments Enabled = true; } } - + public void AddRegion(Scene scene) { m_scene = scene; if (Enabled) { // Only register module with scene if it is enabled. All callers check for a null attachments module. - // Ideally, there should be a null attachments module for when this core attachments module has been + // Ideally, there should be a null attachments module for when this core attachments module has been // disabled. Registering only when enabled allows for other attachments module implementations. m_scene.RegisterModuleInterface(this); m_scene.EventManager.OnNewClient += SubscribeToClientEvents; @@ -180,7 +182,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private void HandleScriptStateChange(uint localID, bool started) { SceneObjectGroup sog = m_scene.GetGroupByPrim(localID); - if (sog != null && sog.IsAttachment) + if (sog != null && sog.IsAttachment) { if (!started) { @@ -197,21 +199,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } } - - public void RemoveRegion(Scene scene) + + public void RemoveRegion(Scene scene) { m_scene.UnregisterModuleInterface(this); if (Enabled) m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; } - + public void RegionLoaded(Scene scene) { m_invAccessModule = m_scene.RequestModuleInterface(); } - - public void Close() + + public void Close() { RemoveRegion(m_scene); } @@ -269,7 +271,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); // m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}", +// "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}", // ad.AttachmentObjectStates[i].Length, so.Name, sp.Name, m_scene.Name); so.SetState(ad.AttachmentObjectStates[i++], m_scene); @@ -294,7 +296,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { if (DebugLevel > 0) m_log.DebugFormat( - "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", + "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", m_scene.Name, sp.Name); return; @@ -303,6 +305,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (DebugLevel > 0) m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); + XmlDocument doc = new XmlDocument(); + doc.XmlResolver=null; + string stateData = String.Empty; + + IAttachmentsService attServ = m_scene.RequestModuleInterface(); + if (attServ != null) + { + m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); + stateData = attServ.Get(sp.UUID.ToString()); + if (stateData != String.Empty) + { + try + { + doc.LoadXml(stateData); + } + catch { } + } + } + + Dictionary itemData = new Dictionary(); + + XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); + if (nodes.Count > 0) + { + foreach (XmlNode n in nodes) + { + XmlElement elem = (XmlElement)n; + string itemID = elem.GetAttribute("ItemID"); + string xml = elem.InnerXml; + + itemData[new UUID(itemID)] = xml; + } + } + + List attachments = sp.Appearance.GetAttachments(); // Let's get all items at once, so they get cached @@ -322,7 +359,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down // But they're not used anyway, the item is being looked up for now, so let's proceed. - //if (UUID.Zero == assetID) + //if (UUID.Zero == assetID) //{ // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); // continue; @@ -330,10 +367,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments try { + string xmlData; + XmlDocument d = null; + UUID asset; + if (itemData.TryGetValue(attach.ItemID, out xmlData)) + { + d = new XmlDocument(); + d.XmlResolver=null; + d.LoadXml(xmlData); + m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", attach.ItemID); + } + // If we're an NPC then skip all the item checks and manipulations since we don't have an // inventory right now. RezSingleAttachmentFromInventoryInternal( - sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true); + sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true, d); } catch (Exception e) { @@ -361,26 +409,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments Dictionary scriptStates = new Dictionary(); - foreach (SceneObjectGroup so in attachments) + + if (sp.PresenceType != PresenceType.Npc) { - // Scripts MUST be snapshotted before the object is - // removed from the scene because doing otherwise will - // clobber the run flag - // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from - // scripts performing attachment operations at the same time. Getting object states stops the scripts. - scriptStates[so] = PrepareScriptInstanceForSave(so, false); + foreach (SceneObjectGroup so in attachments) + { + // Scripts MUST be snapshotted before the object is + // removed from the scene because doing otherwise will + // clobber the run flag + // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from + // scripts performing attachment operations at the same time. Getting object states stops the scripts. + scriptStates[so] = PrepareScriptInstanceForSave(so, false); + } -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: For object {0} for {1} in {2} got saved state {3}", -// so.Name, sp.Name, m_scene.Name, scriptStates[so]); + lock (sp.AttachmentsSyncLock) + { + foreach (SceneObjectGroup so in attachments) + UpdateDetachedObject(sp, so, scriptStates[so]); + sp.ClearAttachments(); + } } - - lock (sp.AttachmentsSyncLock) + else { - foreach (SceneObjectGroup so in attachments) - UpdateDetachedObject(sp, so, scriptStates[so]); - - sp.ClearAttachments(); + lock (sp.AttachmentsSyncLock) + { + foreach (SceneObjectGroup so in attachments) + UpdateDetachedObject(sp, so, String.Empty); + sp.ClearAttachments(); + } } } @@ -392,7 +448,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (DebugLevel > 0) m_log.DebugFormat( "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", - m_scene.RegionInfo.RegionName, sp.Name, silent); + m_scene.RegionInfo.RegionName, sp.Name, silent); foreach (SceneObjectGroup sop in sp.GetAttachments()) { @@ -401,21 +457,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments sp.ClearAttachments(); } - - public bool AttachObject( - IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool append) + + public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, + bool addToInventory, bool append) { if (!Enabled) return false; - group.DetachFromBackup(); - - bool success = AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append); - - if (!success) - group.AttachToBackup(); - - return success; + return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append); } /// @@ -428,10 +477,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// If true then add object to user inventory. /// If true then scripts are resumed on the attached object. - /// Append to attachment point rather than replace. - private bool AttachObjectInternal( - IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool resumeScripts, bool append) + private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, + bool silent, bool addToInventory, bool resumeScripts, bool append) { +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", +// group.Name, group.LocalId, sp.Name, attachmentPt, silent); + + if (group.GetSittingAvatarsCount() != 0) { if (DebugLevel > 0) @@ -442,7 +495,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return false; } + List attachments = sp.GetAttachments(attachmentPt); + if (attachments.Contains(group)) + { +// if (DebugLevel > 0) +// m_log.WarnFormat( +// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", +// group.Name, group.LocalId, sp.Name, attachmentPt); + + return false; + } + Vector3 attachPos = group.AbsolutePosition; + + // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should + // be removed when that functionality is implemented in opensim + attachmentPt &= 0x7f; + // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. @@ -470,7 +539,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint; attachPos = group.RootPart.AttachedPos; - group.HasGroupChanged = true; } // if we still didn't find a suitable attachment point....... @@ -481,21 +549,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments attachPos = Vector3.Zero; } - group.AttachmentPoint = attachmentPt; - group.AbsolutePosition = attachPos; - - List attachments = sp.GetAttachments(attachmentPt); - - if (attachments.Contains(group)) - { - if (DebugLevel > 0) - m_log.WarnFormat( - "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", - group.Name, group.LocalId, sp.Name, attachmentPt); - - return false; - } - // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones while (attachments.Count >= 5) { @@ -514,11 +567,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } + group.DetachFromBackup(); + lock (sp.AttachmentsSyncLock) { + group.AttachmentPoint = attachmentPt; + group.RootPart.AttachedPos = attachPos; + if (addToInventory && sp.PresenceType != PresenceType.Npc) UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); - + AttachToAgent(sp, group, attachmentPt, attachPos, silent); if (resumeScripts) @@ -529,8 +587,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments group.ResumeScripts(); } + else // Do this last so that event listeners have access to all the effects of the attachment - m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); + // this can't be done when creating scripts: + // scripts do internal enqueue of attach event + // and not all scripts are loaded at this point + m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); } return true; @@ -546,7 +608,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); } - public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) + public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) + { + return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null); + } + + public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc) { if (!Enabled) return null; @@ -557,8 +624,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); // We check the attachments in the avatar appearance here rather than the objects attached to the - // ScenePresence itself so that we can ignore calls by viewer 2/3 to attach objects on startup. We are - // already doing this in ScenePresence.MakeRootAgent(). Simulator-side attaching needs to be done + // ScenePresence itself so that we can ignore calls by viewer 2/3 to attach objects on startup. We are + // already doing this in ScenePresence.MakeRootAgent(). Simulator-side attaching needs to be done // because pre-outfit folder viewers (most version 1 viewers) require it. bool alreadyOn = false; List existingAttachments = sp.Appearance.GetAttachments(); @@ -584,7 +651,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments bool append = (AttachmentPt & 0x80) != 0; AttachmentPt &= 0x7f; - return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); + return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append, doc); } public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) @@ -594,7 +661,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (DebugLevel > 0) m_log.DebugFormat( - "[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}", + "[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}", rezlist.Count, sp.Name, m_scene.Name); foreach (KeyValuePair rez in rezlist) @@ -605,7 +672,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) { - DetachSingleAttachmentToGround(sp, soLocalId, sp.AbsolutePosition, Quaternion.Identity); + Vector3 pos = new Vector3(2.5f, 0f, 0f); + pos *= ((ScenePresence)sp).Rotation; + pos += sp.AbsolutePosition; + DetachSingleAttachmentToGround(sp, soLocalId, pos, Quaternion.Identity); } public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId, Vector3 absolutePos, Quaternion absoluteRot) @@ -649,26 +719,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); + so.RootPart.Shape.LastAttachPoint = (byte)so.AttachmentPoint; + sp.RemoveAttachment(so); so.FromItemID = UUID.Zero; + so.AttachedAvatar = UUID.Zero; + so.ClearPartAttachmentData(); + SceneObjectPart rootPart = so.RootPart; + + rootPart.SetParentLocalId(0); so.AbsolutePosition = absolutePos; if (absoluteRot != Quaternion.Identity) { so.UpdateGroupRotationR(absoluteRot); } - so.AttachedAvatar = UUID.Zero; - rootPart.SetParentLocalId(0); - so.ClearPartAttachmentData(); - rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); - so.HasGroupChanged = true; - so.RootPart.Shape.LastAttachPoint = (byte)so.AttachmentPoint; - rootPart.Rezzed = DateTime.Now; + rootPart.RemFlag(PrimFlags.TemporaryOnRez); + + so.ApplyPhysics(); + + rootPart.Rezzed = DateTime.Now; so.AttachToBackup(); m_scene.EventManager.TriggerParcelPrimCountTainted(); - rootPart.ScheduleFullUpdate(); + rootPart.ClearUndoState(); List uuids = new List(); @@ -678,6 +753,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); + + // Attach (NULL) stops scripts. We don't want that. Resume them. + so.ResumeScripts(); + so.HasGroupChanged = true; + so.RootPart.ScheduleFullUpdate(); + so.ScheduleGroupForTerseUpdate(); } public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) @@ -691,9 +772,32 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } + // If this didn't come from inventory, it also shouldn't go there + // on detach. It's likely a temp attachment. + if (so.FromItemID == UUID.Zero) + { + // Retirn value is ignored + PrepareScriptInstanceForSave(so, true); + + lock (sp.AttachmentsSyncLock) + { + bool changed = sp.Appearance.DetachAttachment(so.FromItemID); + if (changed && m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); + + sp.RemoveAttachment(so); + } + + m_scene.DeleteSceneObject(so, false, false); + so.RemoveScriptInstances(true); + so.Clear(); + + return; + } + if (DebugLevel > 0) m_log.DebugFormat( - "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", + "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); // Scripts MUST be snapshotted before the object is @@ -716,14 +820,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments UpdateDetachedObject(sp, so, scriptedState); } } - + public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos) { if (!Enabled) return; sog.UpdateGroupPosition(pos); - sog.HasGroupChanged = true; + sog.HasGroupChanged = true; } #endregion @@ -732,7 +836,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // This is public but is not part of the IAttachmentsModule interface. // RegionCombiner module needs to poke at it to deliver client events. - // This breaks the encapsulation of the module and should get fixed somehow. + // This breaks the encapsulation of the module and should get fixed somehow. public void SubscribeToClientEvents(IClientAPI client) { client.OnRezSingleAttachmentFromInv += Client_OnRezSingleAttachmentFromInv; @@ -745,7 +849,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // This is public but is not part of the IAttachmentsModule interface. // RegionCombiner module needs to poke at it to deliver client events. - // This breaks the encapsulation of the module and should get fixed somehow. + // This breaks the encapsulation of the module and should get fixed somehow. public void UnsubscribeFromClientEvents(IClientAPI client) { client.OnRezSingleAttachmentFromInv -= Client_OnRezSingleAttachmentFromInv; @@ -791,11 +895,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState); - InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID); - item = m_scene.InventoryService.GetItem(item); + InventoryItemBase item = m_scene.InventoryService.GetItem(sp.UUID, grp.FromItemID); if (item != null) { + // attach is rez, need to update permissions + item.Flags &= ~(uint)(InventoryItemFlags.ObjectSlamPerm | InventoryItemFlags.ObjectOverwriteBase | + InventoryItemFlags.ObjectOverwriteOwner | InventoryItemFlags.ObjectOverwriteGroup | + InventoryItemFlags.ObjectOverwriteEveryone | InventoryItemFlags.ObjectOverwriteNextOwner); + + uint permsBase = (uint)(PermissionMask.Copy | PermissionMask.Transfer | + PermissionMask.Modify | PermissionMask.Move | + PermissionMask.Export | PermissionMask.FoldedMask); + + permsBase &= grp.CurrentAndFoldedNextPermissions(); + permsBase |= (uint)PermissionMask.Move; + item.BasePermissions = permsBase; + item.CurrentPermissions = permsBase; + item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask | (uint)PermissionMask.Move; + item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask; + item.GroupPermissions = permsBase & grp.RootPart.GroupMask; + item.CurrentPermissions &= + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify | + (uint)PermissionMask.Move | + (uint)PermissionMask.Export | + (uint)PermissionMask.FoldedMask); // Preserve folded permissions ?? + AssetBase asset = m_scene.CreateAsset( grp.GetPartName(grp.LocalId), grp.GetPartDescription(grp.LocalId), @@ -826,7 +953,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// Attach this scene object to the given avatar. /// /// - /// This isn't publicly available since attachments should always perform the corresponding inventory + /// This isn't publicly available since attachments should always perform the corresponding inventory /// operation (to show the attach in user inventory and update the asset with positional information). /// /// @@ -846,16 +973,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.DeleteFromStorage(so.UUID); m_scene.EventManager.TriggerParcelPrimCountTainted(); - so.AttachedAvatar = sp.UUID; - if (so.RootPart.PhysActor != null) - so.RootPart.RemoveFromPhysics(); + foreach (SceneObjectPart part in so.Parts) + { +// if (part.KeyframeMotion != null) +// part.KeyframeMotion.Suspend(); + + if (part.PhysActor != null) + { + part.RemoveFromPhysics(); + } + } - so.AbsolutePosition = attachOffset; - so.RootPart.AttachedPos = attachOffset; - so.IsAttachment = true; so.RootPart.SetParentLocalId(sp.LocalId); + so.AttachedAvatar = sp.UUID; so.AttachmentPoint = attachmentpoint; + so.RootPart.AttachedPos = attachOffset; + so.AbsolutePosition = attachOffset; + so.IsAttachment = true; sp.AddAttachment(so); @@ -879,7 +1014,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Fudge below is an extremely unhelpful comment. It's probably here so that the scheduled full update // will succeed, as that will not update if an attachment is selected. - so.IsSelected = false; // fudge.... + so.IsSelected = false; // fudge.... so.ScheduleGroupForFullUpdate(); } @@ -923,7 +1058,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// This involves triggering the detach event and getting the script state (which also stops the script) - /// This MUST be done outside sp.AttachmentsSyncLock, since otherwise there is a chance of deadlock if a + /// This MUST be done outside sp.AttachmentsSyncLock, since otherwise there is a chance of deadlock if a /// running script is performing attachment operations. /// /// @@ -939,7 +1074,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (fireDetachEvent) { m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero); - // Allow detach event time to do some work before stopping the script Thread.Sleep(2); } @@ -971,6 +1105,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Remove the object from the scene so no more updates // are sent. Doing this before the below changes will ensure // updates can't cause "HUD artefacts" + m_scene.DeleteSceneObject(so, false, false); // Prepare sog for storage @@ -989,23 +1124,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Now, remove the scripts so.RemoveScriptInstances(true); + so.Clear(); } protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) + IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc) { if (m_invAccessModule == null) return null; SceneObjectGroup objatt; + UUID rezGroupID; + + // This will fail if the user aborts login. sp will exist + // but ControllintClient will be null. + try + { + rezGroupID = sp.ControllingClient.ActiveGroupId; + } + catch + { + return null; + } + if (itemID != UUID.Zero) objatt = m_invAccessModule.RezObject(sp.ControllingClient, - itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + itemID, rezGroupID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, false, false, sp.UUID, true); else objatt = m_invAccessModule.RezObject(sp.ControllingClient, - null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + null, rezGroupID, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, false, false, sp.UUID, true); if (objatt == null) @@ -1018,7 +1167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } else if (itemID == UUID.Zero) { - // We need to have a FromItemID for multiple attachments on a single attach point to appear. This is + // We need to have a FromItemID for multiple attachments on a single attach point to appear. This is // true on Singularity 1.8.5 and quite possibly other viewers as well. As NPCs don't have an inventory // we will satisfy this requirement by inserting a random UUID. objatt.FromItemID = UUID.Random(); @@ -1043,6 +1192,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // This will throw if the attachment fails try { + if (doc != null) + { + objatt.LoadScriptState(doc); + objatt.ResetOwnerChangeFlag(); + } + AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append); } catch (Exception e) @@ -1058,7 +1213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } if (tainted) - objatt.HasGroupChanged = true; + objatt.HasGroupChanged = true; if (ThrottlePer100PrimsRezzed > 0) { @@ -1100,8 +1255,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } - InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); - item = m_scene.InventoryService.GetItem(item); + InventoryItemBase item = m_scene.InventoryService.GetItem(sp.UUID, itemID); if (item == null) return; @@ -1185,7 +1339,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (part == null) return; - if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) + SceneObjectGroup group = part.ParentGroup; + + if (!m_scene.Permissions.CanTakeObject(group, sp)) { remoteClient.SendAgentAlertMessage( "You don't have sufficient permissions to attach this object", false); @@ -1197,7 +1353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments AttachmentPt &= 0x7f; // Calls attach with a Zero position - if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, append)) + if (AttachObject(sp, group , AttachmentPt, false, true, append)) { if (DebugLevel > 0) m_log.Debug( @@ -1205,7 +1361,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments + ", AttachmentPoint: " + AttachmentPt); // Save avatar attachment information - m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); } } catch (Exception e) @@ -1222,7 +1378,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); - if (sp != null && group != null && group.FromItemID != UUID.Zero) + if (sp != null && group != null) DetachSingleAttachmentToInv(sp, group); } @@ -1256,7 +1412,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (sp != null) DetachSingleAttachmentToGround(sp, soLocalId); } - #endregion } } -- cgit v1.1