aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-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]