aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Attachments
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-05-23 01:58:10 +0100
committerJustin Clark-Casey (justincc)2012-05-23 01:58:10 +0100
commitff429a259b41f1205a6b153bb6da383d9a9f5daf (patch)
tree70d7a495cc6d846ef593f8bb0ed608c31b78f079 /OpenSim/Region/CoreModules/Avatar/Attachments
parentSetting 'in transit' on a local teleport as well as inter-region teleports. (diff)
downloadopensim-SC_OLD-ff429a259b41f1205a6b153bb6da383d9a9f5daf.zip
opensim-SC_OLD-ff429a259b41f1205a6b153bb6da383d9a9f5daf.tar.gz
opensim-SC_OLD-ff429a259b41f1205a6b153bb6da383d9a9f5daf.tar.bz2
opensim-SC_OLD-ff429a259b41f1205a6b153bb6da383d9a9f5daf.tar.xz
Fix bug where an avatar that had an object they owned attached through llAttachToAvatar() or osForceAttachToAvatar() would wrongly have next permissions come into play when they detached that object and rezzed it in scene.
This is because the attachments module code was setting the 'object slam' bit by using PermissionMask.All Solution here is to route the attachment item creation call through the existing inventory code in BasicInventoryAccessModule rather than copy/pasted code in AttachmentsModule itself.
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs206
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs13
2 files changed, 82 insertions, 137 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 2e1948d..d099511 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -49,6 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
49 49
50 private Scene m_scene; 50 private Scene m_scene;
51 private IDialogModule m_dialogModule; 51 private IDialogModule m_dialogModule;
52 private IInventoryAccessModule m_invAccessModule;
52 53
53 /// <summary> 54 /// <summary>
54 /// Are attachments enabled? 55 /// Are attachments enabled?
@@ -87,7 +88,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
87 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; 88 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
88 } 89 }
89 90
90 public void RegionLoaded(Scene scene) {} 91 public void RegionLoaded(Scene scene)
92 {
93 m_invAccessModule = m_scene.RequestModuleInterface<IInventoryAccessModule>();
94 }
91 95
92 public void Close() 96 public void Close()
93 { 97 {
@@ -578,90 +582,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
578 /// <returns>The user inventory item created that holds the attachment.</returns> 582 /// <returns>The user inventory item created that holds the attachment.</returns>
579 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) 583 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp)
580 { 584 {
585 if (m_invAccessModule == null)
586 return null;
587
581 // m_log.DebugFormat( 588 // m_log.DebugFormat(
582 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", 589 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
583 // grp.Name, grp.LocalId, remoteClient.Name); 590 // grp.Name, grp.LocalId, remoteClient.Name);
584 591
585 Vector3 inventoryStoredPosition = new Vector3 592 InventoryItemBase newItem = m_invAccessModule.CopyToInventory(
586 (((grp.AbsolutePosition.X > (int)Constants.RegionSize) 593 DeRezAction.TakeCopy,
587 ? Constants.RegionSize - 6 594 m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID,
588 : grp.AbsolutePosition.X) 595 new List<SceneObjectGroup> { grp },
589 , 596 sp.ControllingClient, true)[0];
590 (grp.AbsolutePosition.Y > (int)Constants.RegionSize)
591 ? Constants.RegionSize - 6
592 : grp.AbsolutePosition.Y,
593 grp.AbsolutePosition.Z);
594
595 Vector3 originalPosition = grp.AbsolutePosition;
596
597 grp.AbsolutePosition = inventoryStoredPosition;
598
599 // If we're being called from a script, then trying to serialize that same script's state will not complete
600 // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
601 // the client/server crashes rather than logging out normally, the attachment's scripts will resume
602 // without state on relog. Arguably, this is what we want anyway.
603 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false);
604
605 grp.AbsolutePosition = originalPosition;
606
607 AssetBase asset = m_scene.CreateAsset(
608 grp.GetPartName(grp.LocalId),
609 grp.GetPartDescription(grp.LocalId),
610 (sbyte)AssetType.Object,
611 Utils.StringToBytes(sceneObjectXml),
612 sp.UUID);
613
614 m_scene.AssetService.Store(asset);
615
616 InventoryItemBase item = new InventoryItemBase();
617 item.CreatorId = grp.RootPart.CreatorID.ToString();
618 item.CreatorData = grp.RootPart.CreatorData;
619 item.Owner = sp.UUID;
620 item.ID = UUID.Random();
621 item.AssetID = asset.FullID;
622 item.Description = asset.Description;
623 item.Name = asset.Name;
624 item.AssetType = asset.Type;
625 item.InvType = (int)InventoryType.Object;
626
627 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
628 if (folder != null)
629 item.Folder = folder.ID;
630 else // oopsies
631 item.Folder = UUID.Zero;
632
633 if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
634 {
635 item.BasePermissions = grp.RootPart.NextOwnerMask;
636 item.CurrentPermissions = grp.RootPart.NextOwnerMask;
637 item.NextPermissions = grp.RootPart.NextOwnerMask;
638 item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
639 item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
640 }
641 else
642 {
643 item.BasePermissions = grp.RootPart.BaseMask;
644 item.CurrentPermissions = grp.RootPart.OwnerMask;
645 item.NextPermissions = grp.RootPart.NextOwnerMask;
646 item.EveryOnePermissions = grp.RootPart.EveryoneMask;
647 item.GroupPermissions = grp.RootPart.GroupMask;
648 }
649 item.CreationDate = Util.UnixTimeSinceEpoch();
650 597
651 // sets itemID so client can show item as 'attached' in inventory 598 // sets itemID so client can show item as 'attached' in inventory
652 grp.FromItemID = item.ID; 599 grp.FromItemID = newItem.ID;
653 600
654 if (m_scene.AddInventoryItem(item)) 601 return newItem;
655 {
656 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
657 }
658 else
659 {
660 if (m_dialogModule != null)
661 m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed");
662 }
663
664 return item;
665 } 602 }
666 603
667 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. 604 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
@@ -709,70 +646,69 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
709 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 646 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
710 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 647 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt)
711 { 648 {
712 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 649 if (m_invAccessModule == null)
713 if (invAccess != null) 650 return null;
651
652 lock (sp.AttachmentsSyncLock)
714 { 653 {
715 lock (sp.AttachmentsSyncLock) 654 SceneObjectGroup objatt;
655
656 if (itemID != UUID.Zero)
657 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
658 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
659 false, false, sp.UUID, true);
660 else
661 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
662 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
663 false, false, sp.UUID, true);
664
665 // m_log.DebugFormat(
666 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
667 // objatt.Name, remoteClient.Name, AttachmentPt);
668
669 if (objatt != null)
716 { 670 {
717 SceneObjectGroup objatt; 671 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
718 672 objatt.HasGroupChanged = false;
719 if (itemID != UUID.Zero) 673 bool tainted = false;
720 objatt = invAccess.RezObject(sp.ControllingClient, 674 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
721 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, 675 tainted = true;
722 false, false, sp.UUID, true); 676
723 else 677 // This will throw if the attachment fails
724 objatt = invAccess.RezObject(sp.ControllingClient, 678 try
725 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
726 false, false, sp.UUID, true);
727
728 // m_log.DebugFormat(
729 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
730 // objatt.Name, remoteClient.Name, AttachmentPt);
731
732 if (objatt != null)
733 { 679 {
734 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. 680 AttachObject(sp, objatt, attachmentPt, false);
735 objatt.HasGroupChanged = false; 681 }
736 bool tainted = false; 682 catch (Exception e)
737 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) 683 {
738 tainted = true; 684 m_log.ErrorFormat(
739 685 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
740 // This will throw if the attachment fails 686 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
741 try 687
742 { 688 // Make sure the object doesn't stick around and bail
743 AttachObject(sp, objatt, attachmentPt, false); 689 sp.RemoveAttachment(objatt);
744 } 690 m_scene.DeleteSceneObject(objatt, false);
745 catch (Exception e) 691 return null;
746 { 692 }
747 m_log.ErrorFormat(
748 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
749 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
750
751 // Make sure the object doesn't stick around and bail
752 sp.RemoveAttachment(objatt);
753 m_scene.DeleteSceneObject(objatt, false);
754 return null;
755 }
756 693
757 if (tainted) 694 if (tainted)
758 objatt.HasGroupChanged = true; 695 objatt.HasGroupChanged = true;
759 696
760 // Fire after attach, so we don't get messy perms dialogs 697 // Fire after attach, so we don't get messy perms dialogs
761 // 4 == AttachedRez 698 // 4 == AttachedRez
762 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); 699 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
763 objatt.ResumeScripts(); 700 objatt.ResumeScripts();
764 701
765 // Do this last so that event listeners have access to all the effects of the attachment 702 // Do this last so that event listeners have access to all the effects of the attachment
766 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); 703 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
767 704
768 return objatt; 705 return objatt;
769 } 706 }
770 else 707 else
771 { 708 {
772 m_log.WarnFormat( 709 m_log.WarnFormat(
773 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", 710 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
774 itemID, sp.Name, attachmentPt); 711 itemID, sp.Name, attachmentPt);
775 }
776 } 712 }
777 } 713 }
778 714
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 42d07fd..5e89eec 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -99,12 +99,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
99 public void TestAddAttachmentFromGround() 99 public void TestAddAttachmentFromGround()
100 { 100 {
101 TestHelpers.InMethod(); 101 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure(); 102// TestHelpers.EnableLogging();
103 103
104 AddPresence(); 104 AddPresence();
105 string attName = "att"; 105 string attName = "att";
106 106
107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; 107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup;
108 108
109 m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false); 109 m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
110 110
@@ -123,6 +123,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
123 Assert.That( 123 Assert.That(
124 m_presence.Appearance.GetAttachpoint(attSo.FromItemID), 124 m_presence.Appearance.GetAttachpoint(attSo.FromItemID),
125 Is.EqualTo((int)AttachmentPoint.Chest)); 125 Is.EqualTo((int)AttachmentPoint.Chest));
126
127 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
128 Assert.That(attachmentItem, Is.Not.Null);
129 Assert.That(attachmentItem.Name, Is.EqualTo(attName));
130
131 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(m_presence.UUID, AssetType.Object);
132 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
133
134// TestHelpers.DisableLogging();
126 } 135 }
127 136
128 [Test] 137 [Test]