aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.Inventory.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs948
1 files changed, 597 insertions, 351 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index e384632..b3303a0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -106,12 +106,12 @@ namespace OpenSim.Region.Framework.Scenes
106 engine.StartProcessing(); 106 engine.StartProcessing();
107 } 107 }
108 108
109 public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) 109 public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item, uint cost)
110 { 110 {
111 IMoneyModule money = RequestModuleInterface<IMoneyModule>(); 111 IMoneyModule money = RequestModuleInterface<IMoneyModule>();
112 if (money != null) 112 if (money != null)
113 { 113 {
114 money.ApplyUploadCharge(agentID, money.UploadCharge, "Asset upload"); 114 money.ApplyUploadCharge(agentID, (int)cost, "Asset upload");
115 } 115 }
116 116
117 AddInventoryItem(item); 117 AddInventoryItem(item);
@@ -149,7 +149,7 @@ namespace OpenSim.Region.Framework.Scenes
149 userlevel = 1; 149 userlevel = 1;
150 } 150 }
151 if (trigger) 151 if (trigger)
152 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel); 152 EventManager.TriggerOnNewInventoryItemUploadComplete(item, userlevel);
153 153
154 return true; 154 return true;
155 } 155 }
@@ -164,7 +164,7 @@ namespace OpenSim.Region.Framework.Scenes
164 m_log.DebugFormat( 164 m_log.DebugFormat(
165 "[AGENT INVENTORY]: Found folder {0} type {1} for item {2}", 165 "[AGENT INVENTORY]: Found folder {0} type {1} for item {2}",
166 f.Name, (AssetType)f.Type, item.Name); 166 f.Name, (AssetType)f.Type, item.Name);
167 167
168 item.Folder = f.ID; 168 item.Folder = f.ID;
169 } 169 }
170 else 170 else
@@ -182,7 +182,7 @@ namespace OpenSim.Region.Framework.Scenes
182 return false; 182 return false;
183 } 183 }
184 } 184 }
185 185
186 if (InventoryService.AddItem(item)) 186 if (InventoryService.AddItem(item))
187 { 187 {
188 int userlevel = 0; 188 int userlevel = 0;
@@ -191,7 +191,7 @@ namespace OpenSim.Region.Framework.Scenes
191 userlevel = 1; 191 userlevel = 1;
192 } 192 }
193 if (trigger) 193 if (trigger)
194 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel); 194 EventManager.TriggerOnNewInventoryItemUploadComplete(item, userlevel);
195 195
196 if (originalFolder != UUID.Zero) 196 if (originalFolder != UUID.Zero)
197 { 197 {
@@ -223,8 +223,7 @@ namespace OpenSim.Region.Framework.Scenes
223 223
224 if (core.TryGet<IClientInventory>(out inv)) 224 if (core.TryGet<IClientInventory>(out inv))
225 { 225 {
226 InventoryFolderBase parent = new InventoryFolderBase(f.ParentID, f.Owner); 226 InventoryFolderBase parent = InventoryService.GetFolder(f.Owner, f.ParentID);
227 parent = InventoryService.GetFolder(parent);
228 inv.SendRemoveInventoryItems(new UUID[] { item.ID }); 227 inv.SendRemoveInventoryItems(new UUID[] { item.ID });
229 inv.SendBulkUpdateInventory(new InventoryFolderBase[0], new InventoryItemBase[] { item }); 228 inv.SendBulkUpdateInventory(new InventoryFolderBase[0], new InventoryItemBase[] { item });
230 string message = "The item was placed in folder " + f.Name; 229 string message = "The item was placed in folder " + f.Name;
@@ -338,9 +337,9 @@ namespace OpenSim.Region.Framework.Scenes
338 337
339 // Update item with new asset 338 // Update item with new asset
340 item.AssetID = asset.FullID; 339 item.AssetID = asset.FullID;
341 if (group.UpdateInventoryItem(item)) 340 group.UpdateInventoryItem(item);
342 remoteClient.SendAlertMessage("Script saved"); 341 group.InvalidateEffectivePerms();
343 342
344 part.SendPropertiesToClient(remoteClient); 343 part.SendPropertiesToClient(remoteClient);
345 344
346 // Trigger rerunning of script (use TriggerRezScript event, see RezScript) 345 // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
@@ -350,12 +349,7 @@ namespace OpenSim.Region.Framework.Scenes
350 { 349 {
351 // Needs to determine which engine was running it and use that 350 // Needs to determine which engine was running it and use that
352 // 351 //
353 part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0); 352 errors = part.Inventory.CreateScriptInstanceEr(item.ItemID, 0, false, DefaultScriptEngine, 1);
354 errors = part.Inventory.GetScriptErrors(item.ItemID);
355 }
356 else
357 {
358 remoteClient.SendAlertMessage("Script saved");
359 } 353 }
360 354
361 // Tell anyone managing scripts that a script has been reloaded/changed 355 // Tell anyone managing scripts that a script has been reloaded/changed
@@ -413,14 +407,14 @@ namespace OpenSim.Region.Framework.Scenes
413 // inventory. Rut-Roh. Whatever. Make this secure. Yeah. 407 // inventory. Rut-Roh. Whatever. Make this secure. Yeah.
414 // 408 //
415 // Passing something to another avatar or a an object will already 409 // Passing something to another avatar or a an object will already
416 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 410 InventoryItemBase item = InventoryService.GetItem(remoteClient.AgentId, itemID);
417 item = InventoryService.GetItem(item);
418 411
419 if (item != null) 412 if (item != null)
420 { 413 {
421 if (item.Owner != remoteClient.AgentId) 414 if (item.Owner != remoteClient.AgentId)
422 return; 415 return;
423 416
417 item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
424 item.Name = itemUpd.Name; 418 item.Name = itemUpd.Name;
425 item.Description = itemUpd.Description; 419 item.Description = itemUpd.Description;
426 420
@@ -526,7 +520,7 @@ namespace OpenSim.Region.Framework.Scenes
526 // needs to be found. If inventory item flags are updated 520 // needs to be found. If inventory item flags are updated
527 // the viewer's notion of the item needs to be refreshed. 521 // the viewer's notion of the item needs to be refreshed.
528 // 522 //
529 // In other situations we cannot send out a bulk update here, since this will cause editing of clothing to start 523 // In other situations we cannot send out a bulk update here, since this will cause editing of clothing to start
530 // failing frequently. Possibly this is a race with a separate transaction that uploads the asset. 524 // failing frequently. Possibly this is a race with a separate transaction that uploads the asset.
531 if (sendUpdate) 525 if (sendUpdate)
532 remoteClient.SendBulkUpdateInventory(item); 526 remoteClient.SendBulkUpdateInventory(item);
@@ -590,8 +584,7 @@ namespace OpenSim.Region.Framework.Scenes
590 return null; 584 return null;
591 } 585 }
592 586
593 InventoryItemBase item = new InventoryItemBase(itemId, senderId); 587 InventoryItemBase item = InventoryService.GetItem(senderId, itemId);
594 item = InventoryService.GetItem(item);
595 588
596 if (item == null) 589 if (item == null)
597 { 590 {
@@ -635,6 +628,7 @@ namespace OpenSim.Region.Framework.Scenes
635 itemCopy.AssetType = item.AssetType; 628 itemCopy.AssetType = item.AssetType;
636 itemCopy.InvType = item.InvType; 629 itemCopy.InvType = item.InvType;
637 itemCopy.Folder = recipientFolderId; 630 itemCopy.Folder = recipientFolderId;
631 itemCopy.Flags = item.Flags;
638 632
639 if (Permissions.PropagatePermissions() && recipient != senderId) 633 if (Permissions.PropagatePermissions() && recipient != senderId)
640 { 634 {
@@ -651,10 +645,11 @@ namespace OpenSim.Region.Framework.Scenes
651 // 645 //
652 // Transfer 646 // Transfer
653 // Copy 647 // Copy
654 // Modufy 648 // Modify
655 uint permsMask = ~ ((uint)PermissionMask.Copy | 649 uint permsMask = ~ ((uint)PermissionMask.Copy |
656 (uint)PermissionMask.Transfer | 650 (uint)PermissionMask.Transfer |
657 (uint)PermissionMask.Modify); 651 (uint)PermissionMask.Modify |
652 (uint)PermissionMask.Export);
658 653
659 // Now, reduce the next perms to the mask bits 654 // Now, reduce the next perms to the mask bits
660 // relevant to the operation 655 // relevant to the operation
@@ -684,18 +679,40 @@ namespace OpenSim.Region.Framework.Scenes
684 (uint)PermissionMask.Move; 679 (uint)PermissionMask.Move;
685 uint ownerPerms = item.CurrentPermissions; 680 uint ownerPerms = item.CurrentPermissions;
686 681
682 // These will be applied to the root prim at next rez.
683 // The legacy slam bit (bit 3) and folded permission (bits 0-2)
684 // are preserved due to the above mangling
685// ownerPerms &= nextPerms;
686
687 // Mask the base permissions. This is a conservative
688 // approach altering only the three main perms
689// basePerms &= nextPerms;
690
691 // Mask out the folded portion of the base mask.
692 // While the owner mask carries the actual folded
693 // permissions, the base mask carries the original
694 // base mask, before masking with the folded perms.
695 // We need this later for rezzing.
696// basePerms &= ~(uint)PermissionMask.FoldedMask;
697// basePerms |= ((basePerms >> 13) & 7) | (((basePerms & (uint)PermissionMask.Export) != 0) ? (uint)PermissionMask.FoldedExport : 0);
698
687 // If this is an object, root prim perms may be more 699 // If this is an object, root prim perms may be more
688 // permissive than folded perms. Use folded perms as 700 // permissive than folded perms. Use folded perms as
689 // a mask 701 // a mask
690 if (item.InvType == (int)InventoryType.Object) 702 uint foldedPerms = (item.CurrentPermissions & (uint)PermissionMask.FoldedMask) << (int)PermissionMask.FoldingShift;
703 if (foldedPerms != 0 && item.InvType == (int)InventoryType.Object)
691 { 704 {
705 foldedPerms |= permsMask;
706
692 bool isRootMod = (item.CurrentPermissions & 707 bool isRootMod = (item.CurrentPermissions &
693 (uint)PermissionMask.Modify) != 0 ? 708 (uint)PermissionMask.Modify) != 0 ?
694 true : false; 709 true : false;
695 710
696 // Mask the owner perms to the folded perms 711 // Mask the owner perms to the folded perms
697 PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref ownerPerms); 712 // Note that this is only to satisfy the viewer.
698 PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref basePerms); 713 // The effect of this will be reversed on rez.
714 ownerPerms &= foldedPerms;
715 basePerms &= foldedPerms;
699 716
700 // If the root was mod, let the mask reflect that 717 // If the root was mod, let the mask reflect that
701 // We also need to adjust the base here, because 718 // We also need to adjust the base here, because
@@ -708,20 +725,20 @@ namespace OpenSim.Region.Framework.Scenes
708 } 725 }
709 } 726 }
710 727
711 // These will be applied to the root prim at next rez. 728 // move here so nextperms are mandatory
712 // The slam bit (bit 3) and folded permission (bits 0-2)
713 // are preserved due to the above mangling
714 ownerPerms &= nextPerms; 729 ownerPerms &= nextPerms;
715
716 // Mask the base permissions. This is a conservative
717 // approach altering only the three main perms
718 basePerms &= nextPerms; 730 basePerms &= nextPerms;
719 731 basePerms &= ~(uint)PermissionMask.FoldedMask;
732 basePerms |= ((basePerms >> 13) & 7) | (((basePerms & (uint)PermissionMask.Export) != 0) ? (uint)PermissionMask.FoldedExport : 0);
720 // Assign to the actual item. Make sure the slam bit is 733 // Assign to the actual item. Make sure the slam bit is
721 // set, if it wasn't set before. 734 // set, if it wasn't set before.
722 itemCopy.BasePermissions = basePerms; 735 itemCopy.BasePermissions = basePerms;
723 itemCopy.CurrentPermissions = ownerPerms; 736 itemCopy.CurrentPermissions = ownerPerms;
724 itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; 737 itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
738 // Need to clear the other inventory slam options.
739 // That is so we can handle the case where the recipient
740 // changes the bits in inventory before rezzing
741 itemCopy.Flags &= ~(uint)(InventoryItemFlags.ObjectOverwriteBase | InventoryItemFlags.ObjectOverwriteOwner | InventoryItemFlags.ObjectOverwriteGroup | InventoryItemFlags.ObjectOverwriteEveryone | InventoryItemFlags.ObjectOverwriteNextOwner);
725 742
726 itemCopy.NextPermissions = item.NextPermissions; 743 itemCopy.NextPermissions = item.NextPermissions;
727 744
@@ -742,7 +759,7 @@ namespace OpenSim.Region.Framework.Scenes
742 itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; 759 itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
743 itemCopy.BasePermissions = item.BasePermissions; 760 itemCopy.BasePermissions = item.BasePermissions;
744 } 761 }
745 762
746 if (itemCopy.Folder == UUID.Zero) 763 if (itemCopy.Folder == UUID.Zero)
747 { 764 {
748 InventoryFolderBase folder = null; 765 InventoryFolderBase folder = null;
@@ -771,9 +788,8 @@ namespace OpenSim.Region.Framework.Scenes
771 788
772 itemCopy.GroupID = UUID.Zero; 789 itemCopy.GroupID = UUID.Zero;
773 itemCopy.GroupOwned = false; 790 itemCopy.GroupOwned = false;
774 itemCopy.Flags = item.Flags; 791 itemCopy.SalePrice = 0; //item.SalePrice;
775 itemCopy.SalePrice = item.SalePrice; 792 itemCopy.SaleType = 0; //item.SaleType;
776 itemCopy.SaleType = item.SaleType;
777 793
778 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 794 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
779 if (invAccess != null) 795 if (invAccess != null)
@@ -812,7 +828,7 @@ namespace OpenSim.Region.Framework.Scenes
812 UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId) 828 UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId)
813 { 829 {
814 //// Retrieve the folder from the sender 830 //// Retrieve the folder from the sender
815 InventoryFolderBase folder = InventoryService.GetFolder(new InventoryFolderBase(folderId, senderId)); 831 InventoryFolderBase folder = InventoryService.GetFolder(senderId, folderId);
816 if (null == folder) 832 if (null == folder)
817 { 833 {
818 m_log.ErrorFormat( 834 m_log.ErrorFormat(
@@ -834,7 +850,7 @@ namespace OpenSim.Region.Framework.Scenes
834 } 850 }
835 851
836 UUID newFolderId = UUID.Random(); 852 UUID newFolderId = UUID.Random();
837 InventoryFolderBase newFolder 853 InventoryFolderBase newFolder
838 = new InventoryFolderBase( 854 = new InventoryFolderBase(
839 newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version); 855 newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version);
840 InventoryService.AddFolder(newFolder); 856 InventoryService.AddFolder(newFolder);
@@ -873,8 +889,7 @@ namespace OpenSim.Region.Framework.Scenes
873 889
874 if (item == null) 890 if (item == null)
875 { 891 {
876 item = new InventoryItemBase(oldItemID, remoteClient.AgentId); 892 item = InventoryService.GetItem(remoteClient.AgentId, oldItemID);
877 item = InventoryService.GetItem(item);
878 893
879 if (item == null) 894 if (item == null)
880 { 895 {
@@ -889,6 +904,20 @@ namespace OpenSim.Region.Framework.Scenes
889 if (newName == String.Empty) 904 if (newName == String.Empty)
890 newName = item.Name; 905 newName = item.Name;
891 906
907 AssetBase asset = AssetService.Get(item.AssetID.ToString());
908
909 if (asset != null)
910 {
911 if (newName != String.Empty)
912 {
913 asset.Name = newName;
914 }
915 else
916 {
917 newName = item.Name;
918 }
919
920
892 if (remoteClient.AgentId == oldAgentID 921 if (remoteClient.AgentId == oldAgentID
893 || (LibraryService != null 922 || (LibraryService != null
894 && LibraryService.LibraryRootFolder != null 923 && LibraryService.LibraryRootFolder != null
@@ -901,7 +930,7 @@ namespace OpenSim.Region.Framework.Scenes
901 item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false); 930 item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false);
902 } 931 }
903 else 932 else
904 { 933 {
905 // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item. 934 // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
906 if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0) 935 if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
907 && (m_permissions.BypassPermissions() 936 && (m_permissions.BypassPermissions()
@@ -915,6 +944,13 @@ namespace OpenSim.Region.Framework.Scenes
915 } 944 }
916 } 945 }
917 } 946 }
947 else
948 {
949 m_log.ErrorFormat(
950 "[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found",
951 item.Name, item.AssetID);
952 }
953 }
918 954
919 /// <summary> 955 /// <summary>
920 /// Create a new asset data structure. 956 /// Create a new asset data structure.
@@ -929,6 +965,24 @@ namespace OpenSim.Region.Framework.Scenes
929 } 965 }
930 966
931 /// <summary> 967 /// <summary>
968 /// Move an item within the agent's inventory, and leave a copy (used in making a new outfit)
969 /// </summary>
970 public void MoveInventoryItemsLeaveCopy(IClientAPI remoteClient, List<InventoryItemBase> items, UUID destfolder)
971 {
972 List<InventoryItemBase> moveitems = new List<InventoryItemBase>();
973 foreach (InventoryItemBase b in items)
974 {
975 CopyInventoryItem(remoteClient, 0, remoteClient.AgentId, b.ID, b.Folder, null);
976 InventoryItemBase n = InventoryService.GetItem(b.Owner, b.ID);
977 n.Folder = destfolder;
978 moveitems.Add(n);
979 remoteClient.SendInventoryItemCreateUpdate(n, 0);
980 }
981
982 MoveInventoryItem(remoteClient, moveitems);
983 }
984
985 /// <summary>
932 /// Move an item within the agent's inventory. 986 /// Move an item within the agent's inventory.
933 /// </summary> 987 /// </summary>
934 /// <param name="remoteClient"></param> 988 /// <param name="remoteClient"></param>
@@ -946,32 +1000,6 @@ namespace OpenSim.Region.Framework.Scenes
946 } 1000 }
947 1001
948 /// <summary> 1002 /// <summary>
949 /// Create a new inventory item.
950 /// </summary>
951 /// <param name="remoteClient">Client creating this inventory item.</param>
952 /// <param name="creatorID"></param>
953 /// <param name="creatorData"></param>
954 /// <param name="folderID">UUID of folder in which this item should be placed.</param>
955 /// <param name="name">Item name.</para>
956 /// <param name="description">Item description.</param>
957 /// <param name="flags">Item flags</param>
958 /// <param name="callbackID">Generated by the client.</para>
959 /// <param name="asset">Asset to which this item refers.</param>
960 /// <param name="invType">Type of inventory item.</param>
961 /// <param name="nextOwnerMask">Next owner pemrissions mask.</param>
962 /// <param name="creationDate">Unix timestamp at which this item was created.</param>
963 public void CreateNewInventoryItem(
964 IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
965 string name, string description, uint flags, uint callbackID,
966 UUID assetID, sbyte assetType, sbyte invType, uint nextOwnerMask, int creationDate)
967 {
968 CreateNewInventoryItem(
969 remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, assetID, assetType, invType,
970 (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, 0, nextOwnerMask, 0,
971 creationDate, true);
972 }
973
974 /// <summary>
975 /// Create a new Inventory Item 1003 /// Create a new Inventory Item
976 /// </summary> 1004 /// </summary>
977 /// <param name="remoteClient">Client creating this inventory item.</param> 1005 /// <param name="remoteClient">Client creating this inventory item.</param>
@@ -990,7 +1018,7 @@ namespace OpenSim.Region.Framework.Scenes
990 /// <param name="nextOwnerMask">Next owner pemrissions mask.</param> 1018 /// <param name="nextOwnerMask">Next owner pemrissions mask.</param>
991 /// <param name="groupMask">Group permissions mask.</param> 1019 /// <param name="groupMask">Group permissions mask.</param>
992 /// <param name="creationDate">Unix timestamp at which this item was created.</param> 1020 /// <param name="creationDate">Unix timestamp at which this item was created.</param>
993 private void CreateNewInventoryItem( 1021 public void CreateNewInventoryItem(
994 IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, 1022 IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
995 string name, string description, uint flags, uint callbackID, UUID assetID, sbyte assetType, sbyte invType, 1023 string name, string description, uint flags, uint callbackID, UUID assetID, sbyte assetType, sbyte invType,
996 uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate, 1024 uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate,
@@ -1015,7 +1043,11 @@ namespace OpenSim.Region.Framework.Scenes
1015 item.BasePermissions = baseMask; 1043 item.BasePermissions = baseMask;
1016 item.CreationDate = creationDate; 1044 item.CreationDate = creationDate;
1017 1045
1018 if (AddInventoryItem(item, assetUpload)) 1046 // special AnimationSet case
1047 if (item.InvType == (int)CustomInventoryType.AnimationSet)
1048 AnimationSet.enforceItemPermitions(item,true);
1049
1050 if (AddInventoryItem(item))
1019 { 1051 {
1020 remoteClient.SendInventoryItemCreateUpdate(item, callbackID); 1052 remoteClient.SendInventoryItemCreateUpdate(item, callbackID);
1021 } 1053 }
@@ -1177,13 +1209,14 @@ namespace OpenSim.Region.Framework.Scenes
1177 1209
1178 if (group.GetInventoryItem(localID, itemID) != null) 1210 if (group.GetInventoryItem(localID, itemID) != null)
1179 { 1211 {
1180 if (item.Type == 10) 1212 if (item.Type == (int)InventoryType.LSL)
1181 { 1213 {
1182 part.RemoveScriptEvents(itemID); 1214 part.RemoveScriptEvents(itemID);
1183 EventManager.TriggerRemoveScript(localID, itemID); 1215 part.ParentGroup.AddActiveScriptCount(-1);
1184 } 1216 }
1185 1217
1186 group.RemoveInventoryItem(localID, itemID); 1218 group.RemoveInventoryItem(localID, itemID);
1219 group.InvalidateEffectivePerms();
1187 } 1220 }
1188 1221
1189 part.SendPropertiesToClient(remoteClient); 1222 part.SendPropertiesToClient(remoteClient);
@@ -1228,30 +1261,32 @@ namespace OpenSim.Region.Framework.Scenes
1228 agentItem.InvType = taskItem.InvType; 1261 agentItem.InvType = taskItem.InvType;
1229 agentItem.Flags = taskItem.Flags; 1262 agentItem.Flags = taskItem.Flags;
1230 1263
1264 // The code below isn't OK. It doesn't account for flags being changed
1265 // in the object inventory, so it will break when you do it. That
1266 // is the previous behaviour, so no matter at this moment. However, there is a lot
1267 // TODO: Fix this after the inventory fixer exists and has beenr run
1231 if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions()) 1268 if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions())
1232 { 1269 {
1233 agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); 1270 uint perms = taskItem.BasePermissions & taskItem.NextPermissions;
1234 if (taskItem.InvType == (int)InventoryType.Object) 1271 if (taskItem.InvType == (int)InventoryType.Object)
1235 { 1272 {
1236 // Bake the new base permissions from folded permissions 1273 PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms );
1237 // The folded perms are in the lowest 3 bits of the current perms 1274 perms = PermissionsUtil.FixAndFoldPermissions(perms);
1238 // We use base permissions here to avoid baking the "Locked" status
1239 // into the item as it is passed.
1240 uint perms = taskItem.BasePermissions & taskItem.NextPermissions;
1241 PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms);
1242 // Avoid the "lock trap" - move must always be enabled but the above may remove it
1243 // Add it back here.
1244 agentItem.BasePermissions = perms | (uint)PermissionMask.Move;
1245 // Newly given items cannot be "locked" on rez. Make sure by
1246 // setting current equal to base.
1247 } 1275 }
1276 else
1277 perms &= taskItem.CurrentPermissions;
1248 1278
1249 agentItem.CurrentPermissions = agentItem.BasePermissions; 1279 // always unlock
1250 1280 perms |= (uint)PermissionMask.Move;
1281
1282 agentItem.BasePermissions = perms;
1283 agentItem.CurrentPermissions = perms;
1284 agentItem.NextPermissions = perms & taskItem.NextPermissions;
1285 agentItem.EveryOnePermissions = perms & taskItem.EveryonePermissions;
1286 agentItem.GroupPermissions = perms & taskItem.GroupPermissions;
1287
1251 agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; 1288 agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
1252 agentItem.NextPermissions = taskItem.NextPermissions; 1289 agentItem.Flags &= ~(uint)(InventoryItemFlags.ObjectOverwriteBase | InventoryItemFlags.ObjectOverwriteOwner | InventoryItemFlags.ObjectOverwriteGroup | InventoryItemFlags.ObjectOverwriteEveryone | InventoryItemFlags.ObjectOverwriteNextOwner);
1253 agentItem.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
1254 agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions;
1255 } 1290 }
1256 else 1291 else
1257 { 1292 {
@@ -1282,7 +1317,7 @@ namespace OpenSim.Region.Framework.Scenes
1282 if (taskItem.Type == (int)AssetType.LSLText) 1317 if (taskItem.Type == (int)AssetType.LSLText)
1283 { 1318 {
1284 part.RemoveScriptEvents(itemId); 1319 part.RemoveScriptEvents(itemId);
1285 EventManager.TriggerRemoveScript(part.LocalId, itemId); 1320 part.ParentGroup.AddActiveScriptCount(-1);
1286 } 1321 }
1287 1322
1288 part.Inventory.RemoveInventoryItem(itemId); 1323 part.Inventory.RemoveInventoryItem(itemId);
@@ -1300,9 +1335,9 @@ namespace OpenSim.Region.Framework.Scenes
1300 public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId, out string message) 1335 public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId, out string message)
1301 { 1336 {
1302 m_log.DebugFormat( 1337 m_log.DebugFormat(
1303 "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}", 1338 "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}",
1304 itemId, part.Name, folderId, remoteClient.Name); 1339 itemId, part.Name, folderId, remoteClient.Name);
1305 1340
1306 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId, out message); 1341 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId, out message);
1307 if (agentItem == null) 1342 if (agentItem == null)
1308 return null; 1343 return null;
@@ -1327,6 +1362,10 @@ namespace OpenSim.Region.Framework.Scenes
1327 { 1362 {
1328 SceneObjectPart part = GetSceneObjectPart(primLocalId); 1363 SceneObjectPart part = GetSceneObjectPart(primLocalId);
1329 1364
1365 // Can't move a null item
1366 if (itemId == UUID.Zero)
1367 return;
1368
1330 if (null == part) 1369 if (null == part)
1331 { 1370 {
1332 m_log.WarnFormat( 1371 m_log.WarnFormat(
@@ -1348,24 +1387,12 @@ namespace OpenSim.Region.Framework.Scenes
1348 return; 1387 return;
1349 } 1388 }
1350 1389
1351 if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1390 if (!Permissions.CanCopyObjectInventory(itemId, part.UUID, remoteClient.AgentId))
1352 { 1391 return;
1353 // If the item to be moved is no copy, we need to be able to
1354 // edit the prim.
1355 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
1356 return;
1357 }
1358 else
1359 {
1360 // If the item is copiable, then we just need to have perms
1361 // on it. The delete check is a pure rights check
1362 if (!Permissions.CanDeleteObject(part.UUID, remoteClient.AgentId))
1363 return;
1364 }
1365 1392
1366 string message; 1393 string message;
1367 InventoryItemBase item = MoveTaskInventoryItem(remoteClient, folderId, part, itemId, out message); 1394 InventoryItemBase item = MoveTaskInventoryItem(remoteClient, folderId, part, itemId, out message);
1368 1395
1369 if (item == null) 1396 if (item == null)
1370 remoteClient.SendAgentAlertMessage(message, false); 1397 remoteClient.SendAgentAlertMessage(message, false);
1371 } 1398 }
@@ -1437,20 +1464,7 @@ namespace OpenSim.Region.Framework.Scenes
1437 return; 1464 return;
1438 } 1465 }
1439 1466
1440 if (part.OwnerID != destPart.OwnerID) 1467 if(!Permissions.CanDoObjectInvToObjectInv(srcTaskItem, part, destPart))
1441 {
1442 // Source must have transfer permissions
1443 if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1444 return;
1445
1446 // Object cannot copy items to an object owned by a different owner
1447 // unless llAllowInventoryDrop has been called on the destination
1448 if ((destPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
1449 return;
1450 }
1451
1452 // must have both move and modify permission to put an item in an object
1453 if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0)
1454 return; 1468 return;
1455 1469
1456 TaskInventoryItem destTaskItem = new TaskInventoryItem(); 1470 TaskInventoryItem destTaskItem = new TaskInventoryItem();
@@ -1493,9 +1507,10 @@ namespace OpenSim.Region.Framework.Scenes
1493 destTaskItem.Type = srcTaskItem.Type; 1507 destTaskItem.Type = srcTaskItem.Type;
1494 1508
1495 destPart.Inventory.AddInventoryItem(destTaskItem, part.OwnerID != destPart.OwnerID); 1509 destPart.Inventory.AddInventoryItem(destTaskItem, part.OwnerID != destPart.OwnerID);
1496
1497 if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1510 if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1511 {
1498 part.Inventory.RemoveInventoryItem(itemId); 1512 part.Inventory.RemoveInventoryItem(itemId);
1513 }
1499 1514
1500 ScenePresence avatar; 1515 ScenePresence avatar;
1501 1516
@@ -1507,10 +1522,20 @@ namespace OpenSim.Region.Framework.Scenes
1507 1522
1508 public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items) 1523 public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items)
1509 { 1524 {
1525
1510 ScenePresence avatar; 1526 ScenePresence avatar;
1511 IClientAPI remoteClient = null; 1527 IClientAPI remoteClient = null;
1512 if (TryGetScenePresence(destID, out avatar)) 1528 if (TryGetScenePresence(destID, out avatar))
1513 remoteClient = avatar.ControllingClient; 1529 remoteClient = avatar.ControllingClient;
1530// ????
1531 SceneObjectPart destPart = GetSceneObjectPart(destID);
1532 if (destPart != null) // Move into a prim
1533 {
1534 foreach(UUID itemID in items)
1535 MoveTaskInventoryItem(destID, host, itemID);
1536 return destID; // Prim folder ID == prim ID
1537 }
1538// /????
1514 1539
1515 InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID); 1540 InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID);
1516 1541
@@ -1572,8 +1597,7 @@ namespace OpenSim.Region.Framework.Scenes
1572 InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID); 1597 InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID);
1573 1598
1574 // Fetch the folder itself to get its current version 1599 // Fetch the folder itself to get its current version
1575 InventoryFolderBase containingFolder = new InventoryFolderBase(folder.ID, client.AgentId); 1600 InventoryFolderBase containingFolder = InventoryService.GetFolder(client.AgentId, folder.ID);
1576 containingFolder = InventoryService.GetFolder(containingFolder);
1577 1601
1578// m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}", 1602// m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}",
1579// contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName); 1603// contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
@@ -1587,7 +1611,7 @@ namespace OpenSim.Region.Framework.Scenes
1587 { 1611 {
1588 if (item.AssetType == (int)AssetType.Link) 1612 if (item.AssetType == (int)AssetType.Link)
1589 { 1613 {
1590 InventoryItemBase linkedItem = InventoryService.GetItem(new InventoryItemBase(item.AssetID)); 1614 InventoryItemBase linkedItem = InventoryService.GetItem(client.AgentId, item.AssetID);
1591 1615
1592 // Take care of genuinely broken links where the target doesn't exist 1616 // Take care of genuinely broken links where the target doesn't exist
1593 // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, 1617 // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
@@ -1624,127 +1648,127 @@ namespace OpenSim.Region.Framework.Scenes
1624 uint primLocalID) 1648 uint primLocalID)
1625 { 1649 {
1626 UUID itemID = itemInfo.ItemID; 1650 UUID itemID = itemInfo.ItemID;
1651 if (itemID == UUID.Zero)
1652 {
1653 m_log.ErrorFormat(
1654 "[PRIM INVENTORY]: UpdateTaskInventory called with item ID Zero on update for {1}!",
1655 remoteClient.Name);
1656 return;
1657 }
1627 1658
1628 // Find the prim we're dealing with 1659 // Find the prim we're dealing with
1629 SceneObjectPart part = GetSceneObjectPart(primLocalID); 1660 SceneObjectPart part = GetSceneObjectPart(primLocalID);
1661 if(part == null)
1662 {
1663 m_log.WarnFormat(
1664 "[PRIM INVENTORY]: " +
1665 "Update with item {0} requested of prim {1} for {2} but this prim does not exist",
1666 itemID, primLocalID, remoteClient.Name);
1667 return;
1668 }
1630 1669
1631 if (part != null) 1670 TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID);
1671
1672 if (currentItem == null)
1632 { 1673 {
1633 TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID); 1674 InventoryItemBase item = InventoryService.GetItem(remoteClient.AgentId, itemID);
1634 bool allowInventoryDrop = (part.GetEffectiveObjectFlags()
1635 & (uint)PrimFlags.AllowInventoryDrop) != 0;
1636 1675
1637 // Explicity allow anyone to add to the inventory if the 1676 // if not found Try library
1638 // AllowInventoryDrop flag has been set. Don't however let 1677 if (item == null && LibraryService != null && LibraryService.LibraryRootFolder != null)
1639 // them update an item unless they pass the external checks 1678 item = LibraryService.LibraryRootFolder.FindItem(itemID);
1640 //
1641 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)
1642 && (currentItem != null || !allowInventoryDrop))
1643 return;
1644 1679
1645 if (currentItem == null) 1680 if(item == null)
1646 { 1681 {
1647 UUID copyID = UUID.Random(); 1682 m_log.ErrorFormat(
1648 if (itemID != UUID.Zero) 1683 "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!",
1649 { 1684 itemID, remoteClient.Name);
1650 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 1685 return;
1651 item = InventoryService.GetItem(item); 1686 }
1652 1687
1653 // Try library 1688 if (!Permissions.CanDropInObjectInv(item, remoteClient, part))
1654 if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null) 1689 return;
1655 {
1656 item = LibraryService.LibraryRootFolder.FindItem(itemID);
1657 }
1658 1690
1659 // If we've found the item in the user's inventory or in the library 1691 UUID copyID = UUID.Random();
1660 if (item != null) 1692 bool modrights = Permissions.CanEditObject(part.ParentGroup, remoteClient);
1661 { 1693 part.ParentGroup.AddInventoryItem(remoteClient.AgentId, primLocalID, item, copyID, modrights);
1662 part.ParentGroup.AddInventoryItem(remoteClient.AgentId, primLocalID, item, copyID); 1694 m_log.InfoFormat(
1663//// m_log.InfoFormat( 1695 "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
1664//// "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", 1696 item.Name, primLocalID, remoteClient.Name);
1665//// item.Name, primLocalID, remoteClient.Name); 1697 part.SendPropertiesToClient(remoteClient);
1666 part.SendPropertiesToClient(remoteClient); 1698 if (!Permissions.BypassPermissions())
1667 if (!Permissions.BypassPermissions()) 1699 {
1668 { 1700 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1669 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1701 {
1670 { 1702 List<UUID> uuids = new List<UUID>();
1671 List<UUID> uuids = new List<UUID>(); 1703 uuids.Add(itemID);
1672 uuids.Add(itemID); 1704 RemoveInventoryItem(remoteClient, uuids);
1673 RemoveInventoryItem(remoteClient, uuids);
1674 }
1675 }
1676 }
1677 else
1678 {
1679 m_log.ErrorFormat(
1680 "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!",
1681 itemID, remoteClient.Name);
1682 }
1683 } 1705 }
1684 } 1706 }
1685 else // Updating existing item with new perms etc 1707 }
1686 { 1708 else // Updating existing item with new perms etc
1709 {
1687// m_log.DebugFormat( 1710// m_log.DebugFormat(
1688// "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()", 1711// "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()",
1689// currentItem.Name, part.Name); 1712// currentItem.Name, part.Name);
1690 1713
1691 // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the 1714 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
1692 // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update) 1715 return;
1693 // will not pass in a transaction ID in the update message.
1694 if (transactionID != UUID.Zero && AgentTransactionsModule != null)
1695 {
1696 AgentTransactionsModule.HandleTaskItemUpdateFromTransaction(
1697 remoteClient, part, transactionID, currentItem);
1698 1716
1699 if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) 1717 // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the
1700 remoteClient.SendAlertMessage("Notecard saved"); 1718 // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update)
1701 else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) 1719 // will not pass in a transaction ID in the update message.
1702 remoteClient.SendAlertMessage("Script saved"); 1720 if (transactionID != UUID.Zero && AgentTransactionsModule != null)
1703 else 1721 {
1704 remoteClient.SendAlertMessage("Item saved"); 1722 AgentTransactionsModule.HandleTaskItemUpdateFromTransaction(
1705 } 1723 remoteClient, part, transactionID, currentItem);
1724
1725// if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
1726// remoteClient.SendAgentAlertMessage("Notecard saved", false);
1727// else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
1728// remoteClient.SendAgentAlertMessage("Script saved", false);
1729// else
1730// remoteClient.SendAgentAlertMessage("Item saved", false);
1731 }
1706 1732
1707 // Base ALWAYS has move 1733 // Base ALWAYS has move
1708 currentItem.BasePermissions |= (uint)PermissionMask.Move; 1734 currentItem.BasePermissions |= (uint)PermissionMask.Move;
1709 1735
1710 itemInfo.Flags = currentItem.Flags; 1736 itemInfo.Flags = currentItem.Flags;
1711 1737
1712 // Check if we're allowed to mess with permissions 1738 // Check if we're allowed to mess with permissions
1713 if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god 1739 if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god
1740 {
1741 bool noChange;
1742 if (remoteClient.AgentId != part.OwnerID) // Not owner
1714 { 1743 {
1715 if (remoteClient.AgentId != part.OwnerID) // Not owner 1744 noChange = true;
1716 { 1745 if(itemInfo.OwnerID == UUID.Zero && itemInfo.GroupID != UUID.Zero)
1717 // Friends and group members can't change any perms
1718 itemInfo.BasePermissions = currentItem.BasePermissions;
1719 itemInfo.EveryonePermissions = currentItem.EveryonePermissions;
1720 itemInfo.GroupPermissions = currentItem.GroupPermissions;
1721 itemInfo.NextPermissions = currentItem.NextPermissions;
1722 itemInfo.CurrentPermissions = currentItem.CurrentPermissions;
1723 }
1724 else
1725 { 1746 {
1726 // Owner can't change base, and can change other 1747 if(remoteClient.IsGroupMember(itemInfo.GroupID))
1727 // only up to base 1748 {
1728 itemInfo.BasePermissions = currentItem.BasePermissions; 1749 ulong powers = remoteClient.GetGroupPowers(itemInfo.GroupID);
1729 if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions) 1750 if((powers & (ulong)GroupPowers.ObjectManipulate) != 0)
1730 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; 1751 noChange = false;
1731 if (itemInfo.GroupPermissions != currentItem.GroupPermissions) 1752 }
1732 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
1733 if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions)
1734 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner;
1735 if (itemInfo.NextPermissions != currentItem.NextPermissions)
1736 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
1737 itemInfo.EveryonePermissions &= currentItem.BasePermissions;
1738 itemInfo.GroupPermissions &= currentItem.BasePermissions;
1739 itemInfo.CurrentPermissions &= currentItem.BasePermissions;
1740 itemInfo.NextPermissions &= currentItem.BasePermissions;
1741 } 1753 }
1754 }
1755 else
1756 noChange = false;
1742 1757
1758 if(noChange)
1759 {
1760 // Friends and group members can't change any perms
1761 itemInfo.BasePermissions = currentItem.BasePermissions;
1762 itemInfo.EveryonePermissions = currentItem.EveryonePermissions;
1763 itemInfo.GroupPermissions = currentItem.GroupPermissions;
1764 itemInfo.NextPermissions = currentItem.NextPermissions;
1765 itemInfo.CurrentPermissions = currentItem.CurrentPermissions;
1743 } 1766 }
1744 else 1767 else
1745 { 1768 {
1746 if (itemInfo.BasePermissions != currentItem.BasePermissions) 1769 // Owner can't change base, and can change other
1747 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteBase; 1770 // only up to base
1771 itemInfo.BasePermissions = currentItem.BasePermissions;
1748 if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions) 1772 if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions)
1749 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; 1773 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
1750 if (itemInfo.GroupPermissions != currentItem.GroupPermissions) 1774 if (itemInfo.GroupPermissions != currentItem.GroupPermissions)
@@ -1753,24 +1777,34 @@ namespace OpenSim.Region.Framework.Scenes
1753 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner; 1777 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner;
1754 if (itemInfo.NextPermissions != currentItem.NextPermissions) 1778 if (itemInfo.NextPermissions != currentItem.NextPermissions)
1755 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; 1779 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
1780 itemInfo.EveryonePermissions &= currentItem.BasePermissions;
1781 itemInfo.GroupPermissions &= currentItem.BasePermissions;
1782 itemInfo.CurrentPermissions &= currentItem.BasePermissions;
1783 itemInfo.NextPermissions &= currentItem.BasePermissions;
1756 } 1784 }
1785 }
1786 else
1787 {
1788 if (itemInfo.BasePermissions != currentItem.BasePermissions)
1789 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteBase;
1790 if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions)
1791 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
1792 if (itemInfo.GroupPermissions != currentItem.GroupPermissions)
1793 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
1794 if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions)
1795 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner;
1796 if (itemInfo.NextPermissions != currentItem.NextPermissions)
1797 itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
1798 }
1757 1799
1758 // Next ALWAYS has move 1800 // Next ALWAYS has move
1759 itemInfo.NextPermissions |= (uint)PermissionMask.Move; 1801 itemInfo.NextPermissions |= (uint)PermissionMask.Move;
1760 1802
1761 if (part.Inventory.UpdateInventoryItem(itemInfo)) 1803 if (part.Inventory.UpdateInventoryItem(itemInfo))
1762 { 1804 {
1763 part.SendPropertiesToClient(remoteClient); 1805 part.SendPropertiesToClient(remoteClient);
1764 }
1765 } 1806 }
1766 } 1807 }
1767 else
1768 {
1769 m_log.WarnFormat(
1770 "[PRIM INVENTORY]: " +
1771 "Update with item {0} requested of prim {1} for {2} but this prim does not exist",
1772 itemID, primLocalID, remoteClient.Name);
1773 }
1774 } 1808 }
1775 1809
1776 /// <summary> 1810 /// <summary>
@@ -1803,8 +1837,7 @@ namespace OpenSim.Region.Framework.Scenes
1803 public SceneObjectPart RezScriptFromAgentInventory(UUID agentID, UUID fromItemID, uint localID) 1837 public SceneObjectPart RezScriptFromAgentInventory(UUID agentID, UUID fromItemID, uint localID)
1804 { 1838 {
1805 UUID copyID = UUID.Random(); 1839 UUID copyID = UUID.Random();
1806 InventoryItemBase item = new InventoryItemBase(fromItemID, agentID); 1840 InventoryItemBase item = InventoryService.GetItem(agentID, fromItemID);
1807 item = InventoryService.GetItem(item);
1808 1841
1809 // Try library 1842 // Try library
1810 // XXX clumsy, possibly should be one call 1843 // XXX clumsy, possibly should be one call
@@ -1898,12 +1931,12 @@ namespace OpenSim.Region.Framework.Scenes
1898 return null; 1931 return null;
1899 } 1932 }
1900 1933
1901 AssetBase asset 1934 AssetBase asset
1902 = CreateAsset( 1935 = CreateAsset(
1903 itemBase.Name, 1936 itemBase.Name,
1904 itemBase.Description, 1937 itemBase.Description,
1905 (sbyte)itemBase.AssetType, 1938 (sbyte)itemBase.AssetType,
1906 Encoding.ASCII.GetBytes(scriptText), 1939 Encoding.ASCII.GetBytes(scriptText),
1907 agentID); 1940 agentID);
1908 1941
1909 AssetService.Store(asset); 1942 AssetService.Store(asset);
@@ -1934,6 +1967,8 @@ namespace OpenSim.Region.Framework.Scenes
1934 part.Inventory.AddInventoryItem(taskItem, false); 1967 part.Inventory.AddInventoryItem(taskItem, false);
1935 part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); 1968 part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
1936 1969
1970 part.ParentGroup.InvalidateEffectivePerms();
1971
1937 // tell anyone managing scripts that a new script exists 1972 // tell anyone managing scripts that a new script exists
1938 EventManager.TriggerNewScript(agentID, part, taskItem.ItemID); 1973 EventManager.TriggerNewScript(agentID, part, taskItem.ItemID);
1939 1974
@@ -1982,8 +2017,8 @@ namespace OpenSim.Region.Framework.Scenes
1982 if ((destPart.GroupID == UUID.Zero) || (destPart.GroupID != srcPart.GroupID) || 2017 if ((destPart.GroupID == UUID.Zero) || (destPart.GroupID != srcPart.GroupID) ||
1983 ((destPart.GroupMask & (uint)PermissionMask.Modify) == 0)) 2018 ((destPart.GroupMask & (uint)PermissionMask.Modify) == 0))
1984 return; 2019 return;
1985 } 2020 }
1986 else 2021 else
1987 { 2022 {
1988 if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0) 2023 if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0)
1989 return; 2024 return;
@@ -2069,12 +2104,20 @@ namespace OpenSim.Region.Framework.Scenes
2069 /// <param name='action'>DeRezAction</param> 2104 /// <param name='action'>DeRezAction</param>
2070 /// <param name='destinationID'>User folder ID to place derezzed object</param> 2105 /// <param name='destinationID'>User folder ID to place derezzed object</param>
2071 public virtual void DeRezObjects( 2106 public virtual void DeRezObjects(
2072 IClientAPI remoteClient, List<uint> localIDs, UUID groupID, DeRezAction action, UUID destinationID) 2107 IClientAPI remoteClient, List<uint> localIDs, UUID groupID, DeRezAction action, UUID destinationID, bool AddToReturns = true)
2073 { 2108 {
2074 // First, see of we can perform the requested action and 2109 // First, see of we can perform the requested action and
2075 // build a list of eligible objects 2110 // build a list of eligible objects
2076 List<uint> deleteIDs = new List<uint>(); 2111 List<uint> deleteIDs = new List<uint>();
2077 List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>(); 2112 List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
2113 List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>();
2114 List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>();
2115
2116 ScenePresence sp = null;
2117 if(remoteClient != null)
2118 sp = remoteClient.SceneAgent as ScenePresence;
2119 else if(action != DeRezAction.Return)
2120 return; // only Return can be called without a client
2078 2121
2079 // Start with true for both, then remove the flags if objects 2122 // Start with true for both, then remove the flags if objects
2080 // that we can't derez are part of the selection 2123 // that we can't derez are part of the selection
@@ -2087,20 +2130,27 @@ namespace OpenSim.Region.Framework.Scenes
2087 // Invalid id 2130 // Invalid id
2088 SceneObjectPart part = GetSceneObjectPart(localID); 2131 SceneObjectPart part = GetSceneObjectPart(localID);
2089 if (part == null) 2132 if (part == null)
2133 {
2134 //Client still thinks the object exists, kill it
2135 deleteIDs.Add(localID);
2090 continue; 2136 continue;
2137 }
2091 2138
2092 // Already deleted by someone else 2139 // Already deleted by someone else
2093 if (part.ParentGroup.IsDeleted) 2140 if (part.ParentGroup.IsDeleted)
2141 {
2142 //Client still thinks the object exists, kill it
2143 deleteIDs.Add(localID);
2094 continue; 2144 continue;
2145 }
2095 2146
2096 // Can't delete child prims 2147 // Can't delete child prims
2097 if (part != part.ParentGroup.RootPart) 2148 if (part != part.ParentGroup.RootPart)
2098 continue; 2149 continue;
2099 2150
2100 SceneObjectGroup grp = part.ParentGroup; 2151 SceneObjectGroup grp = part.ParentGroup;
2101 2152 if (grp.IsAttachment)
2102 deleteIDs.Add(localID); 2153 continue;
2103 deleteGroups.Add(grp);
2104 2154
2105 // If child prims have invalid perms, fix them 2155 // If child prims have invalid perms, fix them
2106 grp.AdjustChildPrimPermissions(false); 2156 grp.AdjustChildPrimPermissions(false);
@@ -2112,7 +2162,7 @@ namespace OpenSim.Region.Framework.Scenes
2112 if (action != DeRezAction.Return) 2162 if (action != DeRezAction.Return)
2113 { 2163 {
2114 m_log.WarnFormat( 2164 m_log.WarnFormat(
2115 "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client", 2165 "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client",
2116 action, grp.Name, grp.UUID); 2166 action, grp.Name, grp.UUID);
2117 return; 2167 return;
2118 } 2168 }
@@ -2121,87 +2171,190 @@ namespace OpenSim.Region.Framework.Scenes
2121 } 2171 }
2122 else 2172 else
2123 { 2173 {
2124 if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) 2174 if (action == DeRezAction.TakeCopy)
2175 {
2176 if (!Permissions.CanTakeCopyObject(grp, sp))
2177 permissionToTakeCopy = false;
2178 }
2179 else
2180 {
2125 permissionToTakeCopy = false; 2181 permissionToTakeCopy = false;
2126 2182 }
2127 if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) 2183 if (!Permissions.CanTakeObject(grp, sp))
2128 permissionToTake = false; 2184 permissionToTake = false;
2129 2185
2130 if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) 2186 if (!Permissions.CanDeleteObject(grp, remoteClient))
2131 permissionToDelete = false; 2187 permissionToDelete = false;
2132 } 2188 }
2133 }
2134 2189
2135 // Handle god perms 2190 // Handle god perms
2136 if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) 2191 if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
2137 {
2138 permissionToTake = true;
2139 permissionToTakeCopy = true;
2140 permissionToDelete = true;
2141 }
2142
2143 // If we're re-saving, we don't even want to delete
2144 if (action == DeRezAction.SaveToExistingUserInventoryItem)
2145 permissionToDelete = false;
2146
2147 // if we want to take a copy, we also don't want to delete
2148 // Note: after this point, the permissionToTakeCopy flag
2149 // becomes irrelevant. It already includes the permissionToTake
2150 // permission and after excluding no copy items here, we can
2151 // just use that.
2152 if (action == DeRezAction.TakeCopy)
2153 {
2154 // If we don't have permission, stop right here
2155 if (!permissionToTakeCopy)
2156 { 2192 {
2157 remoteClient.SendAlertMessage("You don't have permission to take the object"); 2193 permissionToTake = true;
2158 return; 2194 permissionToTakeCopy = true;
2195 permissionToDelete = true;
2159 } 2196 }
2160 2197
2161 permissionToTake = true; 2198 // If we're re-saving, we don't even want to delete
2162 // Don't delete 2199 if (action == DeRezAction.SaveToExistingUserInventoryItem)
2163 permissionToDelete = false; 2200 permissionToDelete = false;
2164 }
2165 2201
2166 if (action == DeRezAction.Return) 2202 // if we want to take a copy, we also don't want to delete
2167 { 2203 // Note: after this point, the permissionToTakeCopy flag
2168 if (remoteClient != null) 2204 // becomes irrelevant. It already includes the permissionToTake
2205 // permission and after excluding no copy items here, we can
2206 // just use that.
2207 if (action == DeRezAction.TakeCopy)
2169 { 2208 {
2170 if (Permissions.CanReturnObjects( 2209 // If we don't have permission, stop right here
2171 null, 2210 if (!permissionToTakeCopy)
2172 remoteClient.AgentId,
2173 deleteGroups))
2174 { 2211 {
2175 permissionToTake = true; 2212 remoteClient.SendAlertMessage("You don't have permission to take the object");
2176 permissionToDelete = true; 2213 return;
2214 }
2215
2216 permissionToTake = true;
2217 // Don't delete
2218 permissionToDelete = false;
2219 }
2177 2220
2178 foreach (SceneObjectGroup g in deleteGroups) 2221 if (action == DeRezAction.Return)
2222 {
2223 if (remoteClient != null)
2224 {
2225 if (Permissions.CanReturnObjects(
2226 null,
2227 remoteClient,
2228 new List<SceneObjectGroup>() {grp}))
2179 { 2229 {
2180 AddReturn(g.OwnerID == g.GroupID ? g.LastOwnerID : g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); 2230 permissionToTake = true;
2231 permissionToDelete = true;
2232 if(AddToReturns)
2233 AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition,
2234 "parcel owner return");
2181 } 2235 }
2182 } 2236 }
2237 else // Auto return passes through here with null agent
2238 {
2239 permissionToTake = true;
2240 permissionToDelete = true;
2241 }
2183 } 2242 }
2184 else // Auto return passes through here with null agent 2243
2244 if (permissionToDelete)
2185 { 2245 {
2186 permissionToTake = true; 2246 if (permissionToTake)
2187 permissionToDelete = true; 2247 takeDeleteGroups.Add(grp);
2248 else
2249 deleteGroups.Add(grp);
2250 deleteIDs.Add(grp.LocalId);
2188 } 2251 }
2252 else if(permissionToTake)
2253 takeGroups.Add(grp);
2189 } 2254 }
2190 2255
2191 // OK, we're done with permissions. Let's check if any part of the code prevents the objects from being deleted 2256 SendKillObject(deleteIDs);
2192 bool canDelete = EventManager.TriggerDeRezRequested(remoteClient, deleteGroups, action);
2193 2257
2194 if (permissionToTake && (action != DeRezAction.Delete || this.m_useTrashOnDelete)) 2258 if (takeDeleteGroups.Count > 0)
2259 {
2260 m_asyncSceneObjectDeleter.DeleteToInventory(
2261 action, destinationID, takeDeleteGroups, remoteClient,
2262 true);
2263 }
2264 if (takeGroups.Count > 0)
2195 { 2265 {
2196 m_asyncSceneObjectDeleter.DeleteToInventory( 2266 m_asyncSceneObjectDeleter.DeleteToInventory(
2197 action, destinationID, deleteGroups, remoteClient, 2267 action, destinationID, takeGroups, remoteClient,
2198 permissionToDelete && canDelete); 2268 false);
2199 } 2269 }
2200 else if (permissionToDelete && canDelete) 2270 if (deleteGroups.Count > 0)
2201 { 2271 {
2202 foreach (SceneObjectGroup g in deleteGroups) 2272 foreach (SceneObjectGroup g in deleteGroups)
2203 DeleteSceneObject(g, false); 2273 DeleteSceneObject(g, true);
2274 }
2275 }
2276
2277 public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID)
2278 {
2279 itemID = UUID.Zero;
2280 if (grp != null)
2281 {
2282 Vector3 inventoryStoredPosition = new Vector3(
2283 Math.Min(grp.AbsolutePosition.X, RegionInfo.RegionSizeX - 6),
2284 Math.Min(grp.AbsolutePosition.Y, RegionInfo.RegionSizeY - 6),
2285 grp.AbsolutePosition.Z);
2286
2287 Vector3 originalPosition = grp.AbsolutePosition;
2288
2289 grp.AbsolutePosition = inventoryStoredPosition;
2290
2291 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
2292
2293 grp.AbsolutePosition = originalPosition;
2294
2295 AssetBase asset = CreateAsset(
2296 grp.GetPartName(grp.LocalId),
2297 grp.GetPartDescription(grp.LocalId),
2298 (sbyte)AssetType.Object,
2299 Utils.StringToBytes(sceneObjectXml),
2300 remoteClient.AgentId);
2301 AssetService.Store(asset);
2302
2303 InventoryItemBase item = new InventoryItemBase();
2304 item.CreatorId = grp.RootPart.CreatorID.ToString();
2305 item.CreatorData = grp.RootPart.CreatorData;
2306 item.Owner = remoteClient.AgentId;
2307 item.ID = UUID.Random();
2308 item.AssetID = asset.FullID;
2309 item.Description = asset.Description;
2310 item.Name = asset.Name;
2311 item.AssetType = asset.Type;
2312 item.InvType = (int)InventoryType.Object;
2313
2314 InventoryFolderBase folder = InventoryService.GetFolderForType(remoteClient.AgentId, FolderType.Object);
2315 if (folder != null)
2316 item.Folder = folder.ID;
2317 else // oopsies
2318 item.Folder = UUID.Zero;
2319
2320 // Set up base perms properly
2321 uint permsBase = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify);
2322 permsBase &= grp.RootPart.BaseMask;
2323 permsBase |= (uint)PermissionMask.Move;
2324
2325 // Make sure we don't lock it
2326 grp.RootPart.NextOwnerMask |= (uint)PermissionMask.Move;
2327
2328 if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions())
2329 {
2330 item.BasePermissions = permsBase & grp.RootPart.NextOwnerMask;
2331 item.CurrentPermissions = permsBase & grp.RootPart.NextOwnerMask;
2332 item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask;
2333 item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
2334 item.GroupPermissions = permsBase & grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
2335 }
2336 else
2337 {
2338 item.BasePermissions = permsBase;
2339 item.CurrentPermissions = permsBase & grp.RootPart.OwnerMask;
2340 item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask;
2341 item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask;
2342 item.GroupPermissions = permsBase & grp.RootPart.GroupMask;
2343 }
2344 item.CreationDate = Util.UnixTimeSinceEpoch();
2345
2346 // sets itemID so client can show item as 'attached' in inventory
2347 grp.FromItemID = item.ID;
2348
2349 if (AddInventoryItem(item))
2350 remoteClient.SendInventoryItemCreateUpdate(item, 0);
2351 else
2352 m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
2353
2354 itemID = item.ID;
2355 return item.AssetID;
2204 } 2356 }
2357 return UUID.Zero;
2205 } 2358 }
2206 2359
2207 /// <summary> 2360 /// <summary>
@@ -2236,7 +2389,7 @@ namespace OpenSim.Region.Framework.Scenes
2236 { 2389 {
2237 using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) 2390 using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
2238 { 2391 {
2239 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) 2392 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment, ProhibitDtd = true }))
2240 { 2393 {
2241 reader.Read(); 2394 reader.Read();
2242 bool isSingleObject = reader.Name != "CoalescedObject"; 2395 bool isSingleObject = reader.Name != "CoalescedObject";
@@ -2254,7 +2407,7 @@ namespace OpenSim.Region.Framework.Scenes
2254 Util.LogFailedXML("[AGENT INVENTORY]:", xmlData); 2407 Util.LogFailedXML("[AGENT INVENTORY]:", xmlData);
2255 g = null; 2408 g = null;
2256 } 2409 }
2257 2410
2258 if (g != null) 2411 if (g != null)
2259 { 2412 {
2260 objlist.Add(g); 2413 objlist.Add(g);
@@ -2265,8 +2418,9 @@ namespace OpenSim.Region.Framework.Scenes
2265 return true; 2418 return true;
2266 } 2419 }
2267 else 2420 else
2268 { 2421 {
2269 XmlDocument doc = new XmlDocument(); 2422 XmlDocument doc = new XmlDocument();
2423 doc.XmlResolver=null;
2270 doc.LoadXml(xmlData); 2424 doc.LoadXml(xmlData);
2271 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); 2425 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
2272 XmlElement coll = (XmlElement)e; 2426 XmlElement coll = (XmlElement)e;
@@ -2316,6 +2470,7 @@ namespace OpenSim.Region.Framework.Scenes
2316 /// </summary> 2470 /// </summary>
2317 /// <param name="remoteClient"></param> 2471 /// <param name="remoteClient"></param>
2318 /// <param name="itemID"></param> 2472 /// <param name="itemID"></param>
2473 /// <param name="rezGroupID"></param>
2319 /// <param name="RayEnd"></param> 2474 /// <param name="RayEnd"></param>
2320 /// <param name="RayStart"></param> 2475 /// <param name="RayStart"></param>
2321 /// <param name="RayTargetID"></param> 2476 /// <param name="RayTargetID"></param>
@@ -2326,55 +2481,55 @@ namespace OpenSim.Region.Framework.Scenes
2326 /// <param name="RezSelected"></param> 2481 /// <param name="RezSelected"></param>
2327 /// <param name="RemoveItem"></param> 2482 /// <param name="RemoveItem"></param>
2328 /// <param name="fromTaskID"></param> 2483 /// <param name="fromTaskID"></param>
2329 public virtual void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, 2484 public virtual void RezObject(IClientAPI remoteClient, UUID itemID, UUID rezGroupID,
2485 Vector3 RayEnd, Vector3 RayStart,
2330 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, 2486 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
2331 bool RezSelected, bool RemoveItem, UUID fromTaskID) 2487 bool RezSelected, bool RemoveItem, UUID fromTaskID)
2332 { 2488 {
2333// m_log.DebugFormat( 2489// m_log.DebugFormat(
2334// "[PRIM INVENTORY]: RezObject from {0} for item {1} from task id {2}", 2490// "[PRIM INVENTORY]: RezObject from {0} for item {1} from task id {2}",
2335// remoteClient.Name, itemID, fromTaskID); 2491// remoteClient.Name, itemID, fromTaskID);
2336 2492
2337 if (fromTaskID == UUID.Zero) 2493 if (fromTaskID == UUID.Zero)
2338 { 2494 {
2339 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 2495 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
2340 if (invAccess != null) 2496 if (invAccess != null)
2341 invAccess.RezObject( 2497 invAccess.RezObject(
2342 remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, 2498 remoteClient, itemID, rezGroupID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
2343 RezSelected, RemoveItem, fromTaskID, false); 2499 RezSelected, RemoveItem, fromTaskID, false);
2344 } 2500 }
2345 else 2501 else
2346 { 2502 {
2347 SceneObjectPart part = GetSceneObjectPart(fromTaskID); 2503 SceneObjectPart part = GetSceneObjectPart(fromTaskID);
2348 if (part == null) 2504 if (part == null)
2349 { 2505 {
2350 m_log.ErrorFormat( 2506 m_log.ErrorFormat(
2351 "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such scene object", 2507 "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such scene object",
2352 remoteClient.Name, itemID, fromTaskID); 2508 remoteClient.Name, itemID, fromTaskID);
2353 2509
2354 return; 2510 return;
2355 } 2511 }
2356 2512
2357 TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID); 2513 TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID);
2358 if (item == null) 2514 if (item == null)
2359 { 2515 {
2360 m_log.ErrorFormat( 2516 m_log.ErrorFormat(
2361 "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such item", 2517 "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such item",
2362 remoteClient.Name, itemID, fromTaskID); 2518 remoteClient.Name, itemID, fromTaskID);
2363 2519
2364 return; 2520 return;
2365 } 2521 }
2366 2522
2367 byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); 2523 byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
2368 Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); 2524 Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
2369 Vector3 pos 2525 Vector3 pos = GetNewRezLocation(
2370 = GetNewRezLocation(
2371 RayStart, RayEnd, RayTargetID, Quaternion.Identity, 2526 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
2372 BypassRayCast, bRayEndIsIntersection, true, scale, false); 2527 BypassRayCast, bRayEndIsIntersection, true, scale, false);
2373 2528
2374 RezObject(part, item, pos, null, Vector3.Zero, 0); 2529 RezObject(part, item, pos, null, Vector3.Zero, 0, false);
2375 } 2530 }
2376 } 2531 }
2377 2532
2378 /// <summary> 2533 /// <summary>
2379 /// Rez an object into the scene from a prim's inventory. 2534 /// Rez an object into the scene from a prim's inventory.
2380 /// </summary> 2535 /// </summary>
@@ -2387,15 +2542,18 @@ namespace OpenSim.Region.Framework.Scenes
2387 /// <param name="param"></param> 2542 /// <param name="param"></param>
2388 /// <returns>The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful</returns> 2543 /// <returns>The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful</returns>
2389 public virtual List<SceneObjectGroup> RezObject( 2544 public virtual List<SceneObjectGroup> RezObject(
2390 SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param) 2545 SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param, bool atRoot)
2391 { 2546 {
2392 if (null == item) 2547 if (null == item)
2393 return null; 2548 return null;
2394 2549
2395 List<SceneObjectGroup> objlist; 2550 List<SceneObjectGroup> objlist;
2396 List<Vector3> veclist; 2551 List<Vector3> veclist;
2397 2552 Vector3 bbox;
2398 bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist); 2553 float offsetHeight;
2554
2555 bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist,out bbox, out offsetHeight);
2556
2399 if (!success) 2557 if (!success)
2400 return null; 2558 return null;
2401 2559
@@ -2412,10 +2570,69 @@ namespace OpenSim.Region.Framework.Scenes
2412 sourcePart.Inventory.RemoveInventoryItem(item.ItemID); 2570 sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
2413 } 2571 }
2414 2572
2573 SceneObjectGroup sog;
2574
2575 bool fixrot = false;
2576 Quaternion netRot = Quaternion.Identity;
2577
2578 // position adjust
2579 if (totalPrims > 1) // nothing to do on a single prim
2580 {
2581 if (objlist.Count == 1)
2582 {
2583 // current object position is root position
2584 if(!atRoot)
2585 {
2586 sog = objlist[0];
2587 Quaternion orot;
2588 if (rot == null)
2589 orot = sog.RootPart.GetWorldRotation();
2590 else
2591 orot = rot.Value;
2592 // possible should be bbox, but geometric center looks better
2593 Vector3 off = sog.GetGeometricCenter();
2594// Vector3 off = bbox * 0.5f;
2595 off *= orot;
2596 pos -= off;
2597 }
2598 }
2599 else
2600 {
2601 //veclist[] are relative to bbox corner with min X,Y and Z
2602 // rez at root, and rot will be referenced to first object in list
2603 if (rot == null)
2604 {
2605 // use original rotations
2606 if (atRoot)
2607 pos -= veclist[0];
2608 else
2609 pos -= bbox / 2;
2610 }
2611 else
2612 {
2613 fixrot = true;
2614 sog = objlist[0];
2615 netRot = Quaternion.Conjugate(sog.RootPart.GetWorldRotation());
2616 netRot = netRot * rot.Value;
2617 Vector3 off;
2618 if (atRoot)
2619 off = veclist[0];
2620 else
2621 off = bbox / 2;
2622 off *= netRot;
2623 pos -= off;
2624 }
2625 }
2626 }
2627
2415 for (int i = 0; i < objlist.Count; i++) 2628 for (int i = 0; i < objlist.Count; i++)
2416 { 2629 {
2417 SceneObjectGroup group = objlist[i]; 2630 SceneObjectGroup group = objlist[i];
2418 Vector3 curpos = pos + veclist[i]; 2631 Vector3 curpos;
2632 if(fixrot)
2633 curpos = pos + veclist[i] * netRot;
2634 else
2635 curpos = pos + veclist[i];
2419 2636
2420 if (group.IsAttachment == false && group.RootPart.Shape.State != 0) 2637 if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
2421 { 2638 {
@@ -2423,11 +2640,23 @@ namespace OpenSim.Region.Framework.Scenes
2423 group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; 2640 group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
2424 } 2641 }
2425 2642
2426 group.FromPartID = sourcePart.UUID; 2643 group.RezzerID = sourcePart.UUID;
2427 AddNewSceneObject(group, true, curpos, rot, vel); 2644
2645 if( i == 0)
2646 AddNewSceneObject(group, true, curpos, rot, vel);
2647 else
2648 {
2649 Quaternion crot = objlist[i].RootPart.GetWorldRotation();
2650 if (fixrot)
2651 {
2652 crot *= netRot;
2653 }
2654 AddNewSceneObject(group, true, curpos, crot, vel);
2655 }
2428 2656
2429 // We can only call this after adding the scene object, since the scene object references the scene 2657 // We can only call this after adding the scene object, since the scene object references the scene
2430 // to find out if scripts should be activated at all. 2658 // to find out if scripts should be activated at all.
2659 group.InvalidateEffectivePerms();
2431 group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); 2660 group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
2432 2661
2433 group.ScheduleGroupForFullUpdate(); 2662 group.ScheduleGroupForFullUpdate();
@@ -2437,7 +2666,7 @@ namespace OpenSim.Region.Framework.Scenes
2437 } 2666 }
2438 2667
2439 public virtual bool returnObjects(SceneObjectGroup[] returnobjects, 2668 public virtual bool returnObjects(SceneObjectGroup[] returnobjects,
2440 UUID AgentId) 2669 IClientAPI client)
2441 { 2670 {
2442 List<uint> localIDs = new List<uint>(); 2671 List<uint> localIDs = new List<uint>();
2443 2672
@@ -2447,14 +2676,17 @@ namespace OpenSim.Region.Framework.Scenes
2447 "parcel owner return"); 2676 "parcel owner return");
2448 localIDs.Add(grp.RootPart.LocalId); 2677 localIDs.Add(grp.RootPart.LocalId);
2449 } 2678 }
2450 DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, 2679 DeRezObjects(client, localIDs, UUID.Zero, DeRezAction.Return,
2451 UUID.Zero); 2680 UUID.Zero, false);
2452 2681
2453 return true; 2682 return true;
2454 } 2683 }
2455 2684
2456 public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running) 2685 public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running)
2457 { 2686 {
2687 if (!Permissions.CanEditScript(itemID, objectID, controllingClient.AgentId))
2688 return;
2689
2458 SceneObjectPart part = GetSceneObjectPart(objectID); 2690 SceneObjectPart part = GetSceneObjectPart(objectID);
2459 if (part == null) 2691 if (part == null)
2460 return; 2692 return;
@@ -2476,9 +2708,6 @@ namespace OpenSim.Region.Framework.Scenes
2476 { 2708 {
2477 if (ownerID != UUID.Zero) 2709 if (ownerID != UUID.Zero)
2478 return; 2710 return;
2479
2480 if (!Permissions.CanDeedObject(remoteClient.AgentId, groupID))
2481 return;
2482 } 2711 }
2483 2712
2484 List<SceneObjectGroup> groups = new List<SceneObjectGroup>(); 2713 List<SceneObjectGroup> groups = new List<SceneObjectGroup>();
@@ -2486,8 +2715,8 @@ namespace OpenSim.Region.Framework.Scenes
2486 foreach (uint localID in localIDs) 2715 foreach (uint localID in localIDs)
2487 { 2716 {
2488 SceneObjectPart part = GetSceneObjectPart(localID); 2717 SceneObjectPart part = GetSceneObjectPart(localID);
2489 if (part == null) 2718 if (part == null)
2490 continue; 2719 continue;
2491 2720
2492 if (!groups.Contains(part.ParentGroup)) 2721 if (!groups.Contains(part.ParentGroup))
2493 groups.Add(part.ParentGroup); 2722 groups.Add(part.ParentGroup);
@@ -2502,40 +2731,46 @@ namespace OpenSim.Region.Framework.Scenes
2502 sog.ScheduleGroupForFullUpdate(); 2731 sog.ScheduleGroupForFullUpdate();
2503 2732
2504 SceneObjectPart[] partList = sog.Parts; 2733 SceneObjectPart[] partList = sog.Parts;
2505 2734
2506 foreach (SceneObjectPart child in partList) 2735 foreach (SceneObjectPart child in partList)
2507 { 2736 {
2508 child.Inventory.ChangeInventoryOwner(ownerID); 2737 child.Inventory.ChangeInventoryOwner(ownerID);
2509 child.TriggerScriptChangedEvent(Changed.OWNER); 2738 child.TriggerScriptChangedEvent(Changed.OWNER);
2510 } 2739 }
2511 } 2740 }
2512 else 2741 else // The object deeded to the group
2513 { 2742 {
2514 if (!Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)) 2743 if (!Permissions.CanDeedObject(remoteClient, sog, groupID))
2515 continue; 2744 continue;
2516 2745
2517 if (sog.GroupID != groupID) 2746 sog.SetOwnerId(groupID);
2518 continue; 2747
2519 2748 // this is wrong, GroupMask is used for group sharing, still possible to set
2520 SceneObjectPart[] partList = sog.Parts; 2749 // this whould give owner rights to users that are member of group but don't have role powers to edit
2750// sog.RootPart.GroupMask = sog.RootPart.OwnerMask;
2751
2752 // we should keep all permissions on deed to group
2753 // and with this comented code, if user does not set next permissions on the object
2754 // and on ALL contents of ALL prims, he may loose rights, making the object useless
2755 sog.ApplyNextOwnerPermissions();
2756 sog.InvalidateEffectivePerms();
2757
2758 sog.ScheduleGroupForFullUpdate();
2521 2759
2760 SceneObjectPart[] partList = sog.Parts;
2522 foreach (SceneObjectPart child in partList) 2761 foreach (SceneObjectPart child in partList)
2523 { 2762 {
2524 child.LastOwnerID = child.OwnerID;
2525 child.Inventory.ChangeInventoryOwner(groupID); 2763 child.Inventory.ChangeInventoryOwner(groupID);
2526 child.TriggerScriptChangedEvent(Changed.OWNER); 2764 child.TriggerScriptChangedEvent(Changed.OWNER);
2527 } 2765 }
2528
2529 sog.SetOwnerId(groupID);
2530 sog.ApplyNextOwnerPermissions();
2531 } 2766 }
2532 } 2767 }
2533 2768
2534 foreach (uint localID in localIDs) 2769 foreach (uint localID in localIDs)
2535 { 2770 {
2536 SceneObjectPart part = GetSceneObjectPart(localID); 2771 SceneObjectPart part = GetSceneObjectPart(localID);
2537 if (part == null) 2772 if (part == null)
2538 continue; 2773 continue;
2539 part.SendPropertiesToClient(remoteClient); 2774 part.SendPropertiesToClient(remoteClient);
2540 } 2775 }
2541 } 2776 }
@@ -2622,7 +2857,18 @@ namespace OpenSim.Region.Framework.Scenes
2622 return; 2857 return;
2623 } 2858 }
2624 2859
2860 bool oldUsePhysics = (root.Flags & PrimFlags.Physics) != 0;
2625 m_sceneGraph.LinkObjects(root, children); 2861 m_sceneGraph.LinkObjects(root, children);
2862
2863 ScenePresence sp;
2864 if (TryGetScenePresence(agentId, out sp))
2865 {
2866 root.SendPropertiesToClient(sp.ControllingClient);
2867 if (oldUsePhysics && (root.Flags & PrimFlags.Physics) == 0)
2868 {
2869 sp.ControllingClient.SendAlertMessage("Object physics cancelled");
2870 }
2871 }
2626 } 2872 }
2627 2873
2628 private string PermissionString(uint permissions) 2874 private string PermissionString(uint permissions)