diff options
author | Justin Clark-Casey (justincc) | 2012-05-23 01:58:10 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-05-23 01:58:10 +0100 |
commit | ff429a259b41f1205a6b153bb6da383d9a9f5daf (patch) | |
tree | 70d7a495cc6d846ef593f8bb0ed608c31b78f079 /OpenSim/Region/CoreModules/Avatar | |
parent | Setting 'in transit' on a local teleport as well as inter-region teleports. (diff) | |
download | opensim-SC-ff429a259b41f1205a6b153bb6da383d9a9f5daf.zip opensim-SC-ff429a259b41f1205a6b153bb6da383d9a9f5daf.tar.gz opensim-SC-ff429a259b41f1205a6b153bb6da383d9a9f5daf.tar.bz2 opensim-SC-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')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 206 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 13 |
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] |