aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs575
1 files changed, 427 insertions, 148 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index a6db4de..b838177 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -30,22 +30,27 @@ using System.Collections.Generic;
30using System.Collections; 30using System.Collections;
31using System.Reflection; 31using System.Reflection;
32using System.Text; 32using System.Text;
33using System.Threading;
33using System.Timers; 34using System.Timers;
35using System.Xml;
34using OpenMetaverse; 36using OpenMetaverse;
35using OpenMetaverse.Packets; 37using OpenMetaverse.Packets;
36using log4net; 38using log4net;
37using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Framework.Serialization.External;
38using OpenSim.Region.Framework; 41using OpenSim.Region.Framework;
39using OpenSim.Framework.Client; 42using OpenSim.Framework.Client;
40using OpenSim.Region.Framework.Interfaces; 43using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes.Serialization; 44using OpenSim.Region.Framework.Scenes.Serialization;
45using OpenSim.Services.Interfaces;
46using PermissionMask = OpenSim.Framework.PermissionMask;
42 47
43namespace OpenSim.Region.Framework.Scenes 48namespace OpenSim.Region.Framework.Scenes
44{ 49{
45 public partial class Scene 50 public partial class Scene
46 { 51 {
47 private static readonly ILog m_log 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 //private static readonly string LogHeader = "[SCENE INVENTORY]";
49 54
50 /// <summary> 55 /// <summary>
51 /// Allows asynchronous derezzing of objects from the scene into a client's inventory. 56 /// Allows asynchronous derezzing of objects from the scene into a client's inventory.
@@ -125,11 +130,16 @@ namespace OpenSim.Region.Framework.Scenes
125 } 130 }
126 } 131 }
127 132
133 public bool AddInventoryItem(InventoryItemBase item)
134 {
135 return AddInventoryItem(item, true);
136 }
137
128 /// <summary> 138 /// <summary>
129 /// Add the given inventory item to a user's inventory. 139 /// Add the given inventory item to a user's inventory.
130 /// </summary> 140 /// </summary>
131 /// <param name="item"></param> 141 /// <param name="item"></param>
132 public bool AddInventoryItem(InventoryItemBase item) 142 public bool AddInventoryItem(InventoryItemBase item, bool trigger)
133 { 143 {
134 if (item.Folder != UUID.Zero && InventoryService.AddItem(item)) 144 if (item.Folder != UUID.Zero && InventoryService.AddItem(item))
135 { 145 {
@@ -138,14 +148,17 @@ namespace OpenSim.Region.Framework.Scenes
138 { 148 {
139 userlevel = 1; 149 userlevel = 1;
140 } 150 }
141 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel); 151 if (trigger)
152 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
142 153
143 return true; 154 return true;
144 } 155 }
145 156
146 // OK so either the viewer didn't send a folderID or AddItem failed 157 // OK so either the viewer didn't send a folderID or AddItem failed
147 UUID originalFolder = item.Folder; 158 UUID originalFolder = item.Folder;
148 InventoryFolderBase f = InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType); 159 InventoryFolderBase f = null;
160 if (Enum.IsDefined(typeof(FolderType), (sbyte)item.AssetType))
161 f = InventoryService.GetFolderForType(item.Owner, (FolderType)item.AssetType);
149 if (f != null) 162 if (f != null)
150 { 163 {
151 m_log.DebugFormat( 164 m_log.DebugFormat(
@@ -177,7 +190,8 @@ namespace OpenSim.Region.Framework.Scenes
177 { 190 {
178 userlevel = 1; 191 userlevel = 1;
179 } 192 }
180 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel); 193 if (trigger)
194 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
181 195
182 if (originalFolder != UUID.Zero) 196 if (originalFolder != UUID.Zero)
183 { 197 {
@@ -325,7 +339,7 @@ namespace OpenSim.Region.Framework.Scenes
325 // Update item with new asset 339 // Update item with new asset
326 item.AssetID = asset.FullID; 340 item.AssetID = asset.FullID;
327 if (group.UpdateInventoryItem(item)) 341 if (group.UpdateInventoryItem(item))
328 remoteClient.SendAgentAlertMessage("Script saved", false); 342 remoteClient.SendAlertMessage("Script saved");
329 343
330 part.SendPropertiesToClient(remoteClient); 344 part.SendPropertiesToClient(remoteClient);
331 345
@@ -341,7 +355,7 @@ namespace OpenSim.Region.Framework.Scenes
341 } 355 }
342 else 356 else
343 { 357 {
344 remoteClient.SendAgentAlertMessage("Script saved", false); 358 remoteClient.SendAlertMessage("Script saved");
345 } 359 }
346 360
347 // Tell anyone managing scripts that a script has been reloaded/changed 361 // Tell anyone managing scripts that a script has been reloaded/changed
@@ -415,20 +429,61 @@ namespace OpenSim.Region.Framework.Scenes
415// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags, 429// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
416// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions); 430// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);
417 431
432 bool sendUpdate = false;
433
418 if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid 434 if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid
419 { 435 {
436 // Create a set of base permissions that will not include export if the user
437 // is not allowed to change the export flag.
438 bool denyExportChange = false;
439
440// m_log.DebugFormat("[XXX]: B: {0} O: {1} E: {2}", itemUpd.BasePermissions, itemUpd.CurrentPermissions, itemUpd.EveryOnePermissions);
441
442 // If the user is not the creator or doesn't have "E" in both "B" and "O", deny setting export
443 if ((item.BasePermissions & (uint)(PermissionMask.All | PermissionMask.Export)) != (uint)(PermissionMask.All | PermissionMask.Export) || (item.CurrentPermissions & (uint)PermissionMask.Export) == 0 || item.CreatorIdAsUuid != item.Owner)
444 denyExportChange = true;
445
446// m_log.DebugFormat("[XXX]: Deny Export Update {0}", denyExportChange);
447
448 // If it is already set, force it set and also force full perm
449 // else prevent setting it. It can and should never be set unless
450 // set in base, so the condition above is valid
451 if (denyExportChange)
452 {
453 // If we are not allowed to change it, then force it to the
454 // original item's setting and if it was on, also force full perm
455 if ((item.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
456 {
457 itemUpd.NextPermissions = (uint)(PermissionMask.All);
458 itemUpd.EveryOnePermissions |= (uint)PermissionMask.Export;
459 }
460 else
461 {
462 itemUpd.EveryOnePermissions &= ~(uint)PermissionMask.Export;
463 }
464 }
465 else
466 {
467 // If the new state is exportable, force full perm
468 if ((itemUpd.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
469 {
470// m_log.DebugFormat("[XXX]: Force full perm");
471 itemUpd.NextPermissions = (uint)(PermissionMask.All);
472 }
473 }
474
420 if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions)) 475 if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
421 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; 476 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
422 item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions; 477 item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
478
423 if (item.EveryOnePermissions != (itemUpd.EveryOnePermissions & item.BasePermissions)) 479 if (item.EveryOnePermissions != (itemUpd.EveryOnePermissions & item.BasePermissions))
424 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; 480 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
425 item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions; 481 item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions;
482
426 if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions)) 483 if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions))
427 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup; 484 item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
428
429// m_log.DebugFormat("[USER INVENTORY]: item.Flags {0}", item.Flags);
430
431 item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions; 485 item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions;
486
432 item.GroupID = itemUpd.GroupID; 487 item.GroupID = itemUpd.GroupID;
433 item.GroupOwned = itemUpd.GroupOwned; 488 item.GroupOwned = itemUpd.GroupOwned;
434 item.CreationDate = itemUpd.CreationDate; 489 item.CreationDate = itemUpd.CreationDate;
@@ -449,6 +504,12 @@ namespace OpenSim.Region.Framework.Scenes
449 item.SalePrice = itemUpd.SalePrice; 504 item.SalePrice = itemUpd.SalePrice;
450 item.SaleType = itemUpd.SaleType; 505 item.SaleType = itemUpd.SaleType;
451 506
507 if (item.InvType == (int)InventoryType.Wearable && (item.Flags & 0xf) == 0 && (itemUpd.Flags & 0xf) != 0)
508 {
509 item.Flags = (uint)(item.Flags & 0xfffffff0) | (itemUpd.Flags & 0xf);
510 sendUpdate = true;
511 }
512
452 InventoryService.UpdateItem(item); 513 InventoryService.UpdateItem(item);
453 } 514 }
454 515
@@ -459,6 +520,17 @@ namespace OpenSim.Region.Framework.Scenes
459 AgentTransactionsModule.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); 520 AgentTransactionsModule.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
460 } 521 }
461 } 522 }
523 else
524 {
525 // This MAY be problematic, if it is, another solution
526 // needs to be found. If inventory item flags are updated
527 // the viewer's notion of the item needs to be refreshed.
528 //
529 // 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.
531 if (sendUpdate)
532 remoteClient.SendBulkUpdateInventory(item);
533 }
462 } 534 }
463 else 535 else
464 { 536 {
@@ -474,9 +546,9 @@ namespace OpenSim.Region.Framework.Scenes
474 /// <param name="recipientClient"></param> 546 /// <param name="recipientClient"></param>
475 /// <param name="senderId">ID of the sender of the item</param> 547 /// <param name="senderId">ID of the sender of the item</param>
476 /// <param name="itemId"></param> 548 /// <param name="itemId"></param>
477 public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId) 549 public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId, out string message)
478 { 550 {
479 InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId); 551 InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId, out message);
480 552
481 if (itemCopy != null) 553 if (itemCopy != null)
482 recipientClient.SendBulkUpdateInventory(itemCopy); 554 recipientClient.SendBulkUpdateInventory(itemCopy);
@@ -489,9 +561,9 @@ namespace OpenSim.Region.Framework.Scenes
489 /// <param name="senderId">ID of the sender of the item</param> 561 /// <param name="senderId">ID of the sender of the item</param>
490 /// <param name="itemId"></param> 562 /// <param name="itemId"></param>
491 /// <returns>The inventory item copy given, null if the give was unsuccessful</returns> 563 /// <returns>The inventory item copy given, null if the give was unsuccessful</returns>
492 public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId) 564 public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId, out string message)
493 { 565 {
494 return GiveInventoryItem(recipient, senderId, itemId, UUID.Zero); 566 return GiveInventoryItem(recipient, senderId, itemId, UUID.Zero, out message);
495 } 567 }
496 568
497 /// <summary> 569 /// <summary>
@@ -508,10 +580,16 @@ namespace OpenSim.Region.Framework.Scenes
508 /// The inventory item copy given, null if the give was unsuccessful 580 /// The inventory item copy given, null if the give was unsuccessful
509 /// </returns> 581 /// </returns>
510 public virtual InventoryItemBase GiveInventoryItem( 582 public virtual InventoryItemBase GiveInventoryItem(
511 UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId) 583 UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId, out string message)
512 { 584 {
513 //Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem"); 585 //Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem");
514 586
587 if (!Permissions.CanTransferUserInventory(itemId, senderId, recipient))
588 {
589 message = "Not allowed to transfer this item.";
590 return null;
591 }
592
515 InventoryItemBase item = new InventoryItemBase(itemId, senderId); 593 InventoryItemBase item = new InventoryItemBase(itemId, senderId);
516 item = InventoryService.GetItem(item); 594 item = InventoryService.GetItem(item);
517 595
@@ -519,6 +597,7 @@ namespace OpenSim.Region.Framework.Scenes
519 { 597 {
520 m_log.WarnFormat( 598 m_log.WarnFormat(
521 "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient); 599 "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient);
600 message = string.Format("Item not found: {0}.", itemId);
522 return null; 601 return null;
523 } 602 }
524 603
@@ -527,6 +606,7 @@ namespace OpenSim.Region.Framework.Scenes
527 m_log.WarnFormat( 606 m_log.WarnFormat(
528 "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}", 607 "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}",
529 item.Name, item.ID, recipient, senderId, item.Owner); 608 item.Name, item.ID, recipient, senderId, item.Owner);
609 message = "Sender did not match item owner.";
530 return null; 610 return null;
531 } 611 }
532 612
@@ -537,7 +617,10 @@ namespace OpenSim.Region.Framework.Scenes
537 if (!Permissions.BypassPermissions()) 617 if (!Permissions.BypassPermissions())
538 { 618 {
539 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) 619 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
620 {
621 message = "Item doesn't have the Transfer permission.";
540 return null; 622 return null;
623 }
541 } 624 }
542 625
543 // Insert a copy of the item into the recipient 626 // Insert a copy of the item into the recipient
@@ -606,17 +689,13 @@ namespace OpenSim.Region.Framework.Scenes
606 // a mask 689 // a mask
607 if (item.InvType == (int)InventoryType.Object) 690 if (item.InvType == (int)InventoryType.Object)
608 { 691 {
609 // Create a safe mask for the current perms
610 uint foldedPerms = (item.CurrentPermissions & 7) << 13;
611 foldedPerms |= permsMask;
612
613 bool isRootMod = (item.CurrentPermissions & 692 bool isRootMod = (item.CurrentPermissions &
614 (uint)PermissionMask.Modify) != 0 ? 693 (uint)PermissionMask.Modify) != 0 ?
615 true : false; 694 true : false;
616 695
617 // Mask the owner perms to the folded perms 696 // Mask the owner perms to the folded perms
618 ownerPerms &= foldedPerms; 697 PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref ownerPerms);
619 basePerms &= foldedPerms; 698 PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref basePerms);
620 699
621 // If the root was mod, let the mask reflect that 700 // If the root was mod, let the mask reflect that
622 // We also need to adjust the base here, because 701 // We also need to adjust the base here, because
@@ -666,7 +745,9 @@ namespace OpenSim.Region.Framework.Scenes
666 745
667 if (itemCopy.Folder == UUID.Zero) 746 if (itemCopy.Folder == UUID.Zero)
668 { 747 {
669 InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); 748 InventoryFolderBase folder = null;
749 if (Enum.IsDefined(typeof(FolderType), (sbyte)item.AssetType))
750 folder = InventoryService.GetFolderForType(recipient, (FolderType)itemCopy.AssetType);
670 751
671 if (folder != null) 752 if (folder != null)
672 { 753 {
@@ -677,9 +758,14 @@ namespace OpenSim.Region.Framework.Scenes
677 InventoryFolderBase root = InventoryService.GetRootFolder(recipient); 758 InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
678 759
679 if (root != null) 760 if (root != null)
761 {
680 itemCopy.Folder = root.ID; 762 itemCopy.Folder = root.ID;
763 }
681 else 764 else
682 return null; // No destination 765 {
766 message = "Can't find a folder to add the item to.";
767 return null;
768 }
683 } 769 }
684 } 770 }
685 771
@@ -692,7 +778,7 @@ namespace OpenSim.Region.Framework.Scenes
692 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 778 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
693 if (invAccess != null) 779 if (invAccess != null)
694 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); 780 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
695 AddInventoryItem(itemCopy); 781 AddInventoryItem(itemCopy, false);
696 782
697 if (!Permissions.BypassPermissions()) 783 if (!Permissions.BypassPermissions())
698 { 784 {
@@ -704,6 +790,7 @@ namespace OpenSim.Region.Framework.Scenes
704 } 790 }
705 } 791 }
706 792
793 message = null;
707 return itemCopy; 794 return itemCopy;
708 } 795 }
709 796
@@ -721,11 +808,11 @@ namespace OpenSim.Region.Framework.Scenes
721 /// <returns> 808 /// <returns>
722 /// The inventory folder copy given, null if the copy was unsuccessful 809 /// The inventory folder copy given, null if the copy was unsuccessful
723 /// </returns> 810 /// </returns>
724 public virtual InventoryFolderBase GiveInventoryFolder( 811 public virtual InventoryFolderBase GiveInventoryFolder(IClientAPI client,
725 UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId) 812 UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId)
726 { 813 {
727 //// Retrieve the folder from the sender 814 //// Retrieve the folder from the sender
728 InventoryFolderBase folder = InventoryService.GetFolder(new InventoryFolderBase(folderId)); 815 InventoryFolderBase folder = InventoryService.GetFolder(new InventoryFolderBase(folderId, senderId));
729 if (null == folder) 816 if (null == folder)
730 { 817 {
731 m_log.ErrorFormat( 818 m_log.ErrorFormat(
@@ -756,13 +843,18 @@ namespace OpenSim.Region.Framework.Scenes
756 InventoryCollection contents = InventoryService.GetFolderContent(senderId, folderId); 843 InventoryCollection contents = InventoryService.GetFolderContent(senderId, folderId);
757 foreach (InventoryFolderBase childFolder in contents.Folders) 844 foreach (InventoryFolderBase childFolder in contents.Folders)
758 { 845 {
759 GiveInventoryFolder(recipientId, senderId, childFolder.ID, newFolder.ID); 846 GiveInventoryFolder(client, recipientId, senderId, childFolder.ID, newFolder.ID);
760 } 847 }
761 848
762 // Give all the items 849 // Give all the items
763 foreach (InventoryItemBase item in contents.Items) 850 foreach (InventoryItemBase item in contents.Items)
764 { 851 {
765 GiveInventoryItem(recipientId, senderId, item.ID, newFolder.ID); 852 string message;
853 if (GiveInventoryItem(recipientId, senderId, item.ID, newFolder.ID, out message) == null)
854 {
855 if (client != null)
856 client.SendAgentAlertMessage(message, false);
857 }
766 } 858 }
767 859
768 return newFolder; 860 return newFolder;
@@ -794,51 +886,34 @@ namespace OpenSim.Region.Framework.Scenes
794 return; 886 return;
795 } 887 }
796 888
797 AssetBase asset = AssetService.Get(item.AssetID.ToString()); 889 if (newName == String.Empty)
890 newName = item.Name;
798 891
799 if (asset != null) 892 if (remoteClient.AgentId == oldAgentID
893 || (LibraryService != null
894 && LibraryService.LibraryRootFolder != null
895 && oldAgentID == LibraryService.LibraryRootFolder.Owner))
800 { 896 {
801 if (newName != String.Empty) 897 CreateNewInventoryItem(
802 { 898 remoteClient, item.CreatorId, item.CreatorData, newFolderID,
803 asset.Name = newName; 899 newName, item.Description, item.Flags, callbackID, item.AssetID, (sbyte)item.AssetType, (sbyte)item.InvType,
804 } 900 item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions,
805 else 901 item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false);
806 { 902 }
807 newName = item.Name; 903 else
808 } 904 {
809 905 // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
810 if (remoteClient.AgentId == oldAgentID 906 if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
811 || (LibraryService != null 907 && (m_permissions.BypassPermissions()
812 && LibraryService.LibraryRootFolder != null 908 || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
813 && oldAgentID == LibraryService.LibraryRootFolder.Owner))
814 { 909 {
815 CreateNewInventoryItem( 910 CreateNewInventoryItem(
816 remoteClient, item.CreatorId, item.CreatorData, newFolderID, 911 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Description, item.Flags, callbackID,
817 newName, item.Description, item.Flags, callbackID, asset, (sbyte)item.InvType, 912 item.AssetID, (sbyte)item.AssetType, (sbyte) item.InvType,
818 item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, 913 item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
819 item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch()); 914 item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false);
820 }
821 else
822 {
823 // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
824 if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
825 && (m_permissions.BypassPermissions()
826 || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
827 {
828 CreateNewInventoryItem(
829 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Description, item.Flags, callbackID,
830 asset, (sbyte) item.InvType,
831 item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
832 item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
833 }
834 } 915 }
835 } 916 }
836 else
837 {
838 m_log.ErrorFormat(
839 "[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found",
840 item.Name, item.AssetID);
841 }
842 } 917 }
843 918
844 /// <summary> 919 /// <summary>
@@ -888,11 +963,12 @@ namespace OpenSim.Region.Framework.Scenes
888 public void CreateNewInventoryItem( 963 public void CreateNewInventoryItem(
889 IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, 964 IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
890 string name, string description, uint flags, uint callbackID, 965 string name, string description, uint flags, uint callbackID,
891 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) 966 UUID assetID, sbyte assetType, sbyte invType, uint nextOwnerMask, int creationDate)
892 { 967 {
893 CreateNewInventoryItem( 968 CreateNewInventoryItem(
894 remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, asset, invType, 969 remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, assetID, assetType, invType,
895 (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate); 970 (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, 0, nextOwnerMask, 0,
971 creationDate, true);
896 } 972 }
897 973
898 /// <summary> 974 /// <summary>
@@ -916,19 +992,20 @@ namespace OpenSim.Region.Framework.Scenes
916 /// <param name="creationDate">Unix timestamp at which this item was created.</param> 992 /// <param name="creationDate">Unix timestamp at which this item was created.</param>
917 private void CreateNewInventoryItem( 993 private void CreateNewInventoryItem(
918 IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, 994 IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
919 string name, string description, uint flags, uint callbackID, AssetBase asset, sbyte invType, 995 string name, string description, uint flags, uint callbackID, UUID assetID, sbyte assetType, sbyte invType,
920 uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate) 996 uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate,
997 bool assetUpload)
921 { 998 {
922 InventoryItemBase item = new InventoryItemBase(); 999 InventoryItemBase item = new InventoryItemBase();
923 item.Owner = remoteClient.AgentId; 1000 item.Owner = remoteClient.AgentId;
924 item.CreatorId = creatorID; 1001 item.CreatorId = creatorID;
925 item.CreatorData = creatorData; 1002 item.CreatorData = creatorData;
926 item.ID = UUID.Random(); 1003 item.ID = UUID.Random();
927 item.AssetID = asset.FullID; 1004 item.AssetID = assetID;
928 item.Name = name; 1005 item.Name = name;
929 item.Description = description; 1006 item.Description = description;
930 item.Flags = flags; 1007 item.Flags = flags;
931 item.AssetType = asset.Type; 1008 item.AssetType = assetType;
932 item.InvType = invType; 1009 item.InvType = invType;
933 item.Folder = folderID; 1010 item.Folder = folderID;
934 item.CurrentPermissions = currentMask; 1011 item.CurrentPermissions = currentMask;
@@ -938,7 +1015,7 @@ namespace OpenSim.Region.Framework.Scenes
938 item.BasePermissions = baseMask; 1015 item.BasePermissions = baseMask;
939 item.CreationDate = creationDate; 1016 item.CreationDate = creationDate;
940 1017
941 if (AddInventoryItem(item)) 1018 if (AddInventoryItem(item, assetUpload))
942 { 1019 {
943 remoteClient.SendInventoryItemCreateUpdate(item, callbackID); 1020 remoteClient.SendInventoryItemCreateUpdate(item, callbackID);
944 } 1021 }
@@ -1001,17 +1078,12 @@ namespace OpenSim.Region.Framework.Scenes
1001// return; 1078// return;
1002// } 1079// }
1003 1080
1004 AssetBase asset = new AssetBase();
1005 asset.FullID = olditemID;
1006 asset.Type = type;
1007 asset.Name = name;
1008 asset.Description = description;
1009
1010 CreateNewInventoryItem( 1081 CreateNewInventoryItem(
1011 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, 1082 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
1012 name, description, 0, callbackID, asset, invType, 1083 name, description, 0, callbackID, olditemID, type, invType,
1013 (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, 1084 (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All,
1014 (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); 1085 (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, Util.UnixTimeSinceEpoch(),
1086 false);
1015 } 1087 }
1016 else 1088 else
1017 { 1089 {
@@ -1087,13 +1159,21 @@ namespace OpenSim.Region.Framework.Scenes
1087 if (item == null) 1159 if (item == null)
1088 return; 1160 return;
1089 1161
1090 InventoryFolderBase destFolder = InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.TrashFolder); 1162 InventoryFolderBase destFolder = InventoryService.GetFolderForType(remoteClient.AgentId, FolderType.Trash);
1091 1163
1092 // Move the item to trash. If this is a copiable item, only 1164 // Move the item to trash. If this is a copyable item, only
1093 // a copy will be moved and we will still need to delete 1165 // a copy will be moved and we will still need to delete
1094 // the item from the prim. If it was no copy, is will be 1166 // the item from the prim. If it was no copy, it will be
1095 // deleted by this method. 1167 // deleted by this method.
1096 MoveTaskInventoryItem(remoteClient, destFolder.ID, part, itemID); 1168 string message;
1169 InventoryItemBase item2 = MoveTaskInventoryItem(remoteClient, destFolder.ID, part, itemID, out message);
1170
1171 if (item2 == null)
1172 {
1173 m_log.WarnFormat("[SCENE INVENTORY]: RemoveTaskInventory of item {0} failed: {1}", itemID, message);
1174 remoteClient.SendAgentAlertMessage(message, false);
1175 return;
1176 }
1097 1177
1098 if (group.GetInventoryItem(localID, itemID) != null) 1178 if (group.GetInventoryItem(localID, itemID) != null)
1099 { 1179 {
@@ -1105,11 +1185,16 @@ namespace OpenSim.Region.Framework.Scenes
1105 1185
1106 group.RemoveInventoryItem(localID, itemID); 1186 group.RemoveInventoryItem(localID, itemID);
1107 } 1187 }
1188
1108 part.SendPropertiesToClient(remoteClient); 1189 part.SendPropertiesToClient(remoteClient);
1109 } 1190 }
1110 } 1191 }
1111 1192
1112 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) 1193
1194 /// <summary>
1195 /// Creates (in memory only) a user inventory item that will contain a copy of a task inventory item.
1196 /// </summary>
1197 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId, out string message)
1113 { 1198 {
1114 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId); 1199 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
1115 1200
@@ -1120,12 +1205,13 @@ namespace OpenSim.Region.Framework.Scenes
1120 + " inventory item from a prim's inventory item " 1205 + " inventory item from a prim's inventory item "
1121 + " but the required item does not exist in the prim's inventory", 1206 + " but the required item does not exist in the prim's inventory",
1122 itemId, part.Name, part.UUID); 1207 itemId, part.Name, part.UUID);
1123 1208 message = "Item not found: " + itemId;
1124 return null; 1209 return null;
1125 } 1210 }
1126 1211
1127 if ((destAgent != taskItem.OwnerID) && ((taskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)) 1212 if ((destAgent != taskItem.OwnerID) && ((taskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
1128 { 1213 {
1214 message = "Item doesn't have the Transfer permission.";
1129 return null; 1215 return null;
1130 } 1216 }
1131 1217
@@ -1146,9 +1232,21 @@ namespace OpenSim.Region.Framework.Scenes
1146 { 1232 {
1147 agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); 1233 agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
1148 if (taskItem.InvType == (int)InventoryType.Object) 1234 if (taskItem.InvType == (int)InventoryType.Object)
1149 agentItem.CurrentPermissions = agentItem.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move)); 1235 {
1150 else 1236 // Bake the new base permissions from folded permissions
1151 agentItem.CurrentPermissions = agentItem.BasePermissions & taskItem.CurrentPermissions; 1237 // The folded perms are in the lowest 3 bits of the current 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 }
1248
1249 agentItem.CurrentPermissions = agentItem.BasePermissions;
1152 1250
1153 agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; 1251 agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
1154 agentItem.NextPermissions = taskItem.NextPermissions; 1252 agentItem.NextPermissions = taskItem.NextPermissions;
@@ -1164,11 +1262,24 @@ namespace OpenSim.Region.Framework.Scenes
1164 agentItem.GroupPermissions = taskItem.GroupPermissions; 1262 agentItem.GroupPermissions = taskItem.GroupPermissions;
1165 } 1263 }
1166 1264
1265 message = null;
1266 return agentItem;
1267 }
1268
1269 /// <summary>
1270 /// If the task item is not-copyable then remove it from the prim.
1271 /// </summary>
1272 private void RemoveNonCopyTaskItemFromPrim(SceneObjectPart part, UUID itemId)
1273 {
1274 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
1275 if (taskItem == null)
1276 return;
1277
1167 if (!Permissions.BypassPermissions()) 1278 if (!Permissions.BypassPermissions())
1168 { 1279 {
1169 if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1280 if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1170 { 1281 {
1171 if (taskItem.Type == 10) 1282 if (taskItem.Type == (int)AssetType.LSLText)
1172 { 1283 {
1173 part.RemoveScriptEvents(itemId); 1284 part.RemoveScriptEvents(itemId);
1174 EventManager.TriggerRemoveScript(part.LocalId, itemId); 1285 EventManager.TriggerRemoveScript(part.LocalId, itemId);
@@ -1177,8 +1288,6 @@ namespace OpenSim.Region.Framework.Scenes
1177 part.Inventory.RemoveInventoryItem(itemId); 1288 part.Inventory.RemoveInventoryItem(itemId);
1178 } 1289 }
1179 } 1290 }
1180
1181 return agentItem;
1182 } 1291 }
1183 1292
1184 /// <summary> 1293 /// <summary>
@@ -1188,19 +1297,22 @@ namespace OpenSim.Region.Framework.Scenes
1188 /// <param name="folderID"></param> 1297 /// <param name="folderID"></param>
1189 /// <param name="part"></param> 1298 /// <param name="part"></param>
1190 /// <param name="itemID"></param> 1299 /// <param name="itemID"></param>
1191 public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId) 1300 public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId, out string message)
1192 { 1301 {
1193 m_log.DebugFormat( 1302 m_log.DebugFormat(
1194 "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}", 1303 "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}",
1195 itemId, part.Name, folderId, remoteClient.Name); 1304 itemId, part.Name, folderId, remoteClient.Name);
1196 1305
1197 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId); 1306 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId, out message);
1198
1199 if (agentItem == null) 1307 if (agentItem == null)
1200 return null; 1308 return null;
1201 1309
1202 agentItem.Folder = folderId; 1310 agentItem.Folder = folderId;
1203 AddInventoryItem(remoteClient, agentItem); 1311 AddInventoryItem(remoteClient, agentItem);
1312
1313 RemoveNonCopyTaskItemFromPrim(part, itemId);
1314
1315 message = null;
1204 return agentItem; 1316 return agentItem;
1205 } 1317 }
1206 1318
@@ -1251,7 +1363,11 @@ namespace OpenSim.Region.Framework.Scenes
1251 return; 1363 return;
1252 } 1364 }
1253 1365
1254 MoveTaskInventoryItem(remoteClient, folderId, part, itemId); 1366 string message;
1367 InventoryItemBase item = MoveTaskInventoryItem(remoteClient, folderId, part, itemId, out message);
1368
1369 if (item == null)
1370 remoteClient.SendAgentAlertMessage(message, false);
1255 } 1371 }
1256 1372
1257 /// <summary> 1373 /// <summary>
@@ -1265,17 +1381,17 @@ namespace OpenSim.Region.Framework.Scenes
1265 /// </param> 1381 /// </param>
1266 /// <param name="part"></param> 1382 /// <param name="part"></param>
1267 /// <param name="itemID"></param> 1383 /// <param name="itemID"></param>
1268 public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId) 1384 public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId, out string message)
1269 { 1385 {
1270 ScenePresence avatar; 1386 ScenePresence avatar;
1271 1387
1272 if (TryGetScenePresence(avatarId, out avatar)) 1388 if (TryGetScenePresence(avatarId, out avatar))
1273 { 1389 {
1274 return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId); 1390 return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId, out message);
1275 } 1391 }
1276 else 1392 else
1277 { 1393 {
1278 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(avatarId, part, itemId); 1394 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(avatarId, part, itemId, out message);
1279 1395
1280 if (agentItem == null) 1396 if (agentItem == null)
1281 return null; 1397 return null;
@@ -1284,6 +1400,8 @@ namespace OpenSim.Region.Framework.Scenes
1284 1400
1285 AddInventoryItem(agentItem); 1401 AddInventoryItem(agentItem);
1286 1402
1403 RemoveNonCopyTaskItemFromPrim(part, itemId);
1404
1287 return agentItem; 1405 return agentItem;
1288 } 1406 }
1289 } 1407 }
@@ -1389,6 +1507,11 @@ namespace OpenSim.Region.Framework.Scenes
1389 1507
1390 public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items) 1508 public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items)
1391 { 1509 {
1510 ScenePresence avatar;
1511 IClientAPI remoteClient = null;
1512 if (TryGetScenePresence(destID, out avatar))
1513 remoteClient = avatar.ControllingClient;
1514
1392 InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID); 1515 InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID);
1393 1516
1394 UUID newFolderID = UUID.Random(); 1517 UUID newFolderID = UUID.Random();
@@ -1398,26 +1521,28 @@ namespace OpenSim.Region.Framework.Scenes
1398 1521
1399 foreach (UUID itemID in items) 1522 foreach (UUID itemID in items)
1400 { 1523 {
1401 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(destID, host, itemID); 1524 string message;
1525 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(destID, host, itemID, out message);
1402 1526
1403 if (agentItem != null) 1527 if (agentItem != null)
1404 { 1528 {
1405 agentItem.Folder = newFolderID; 1529 agentItem.Folder = newFolderID;
1406 1530
1407 AddInventoryItem(agentItem); 1531 AddInventoryItem(agentItem);
1532
1533 RemoveNonCopyTaskItemFromPrim(host, itemID);
1534 }
1535 else
1536 {
1537 if (remoteClient != null)
1538 remoteClient.SendAgentAlertMessage(message, false);
1408 } 1539 }
1409 } 1540 }
1410 1541
1411 ScenePresence avatar = null; 1542 if (remoteClient != null)
1412 if (TryGetScenePresence(destID, out avatar))
1413 { 1543 {
1414 //profile.SendInventoryDecendents(avatar.ControllingClient, 1544 SendInventoryUpdate(remoteClient, rootFolder, true, false);
1415 // profile.RootFolder.ID, true, false); 1545 SendInventoryUpdate(remoteClient, newFolder, false, true);
1416 //profile.SendInventoryDecendents(avatar.ControllingClient,
1417 // newFolderID, false, true);
1418
1419 SendInventoryUpdate(avatar.ControllingClient, rootFolder, true, false);
1420 SendInventoryUpdate(avatar.ControllingClient, newFolder, false, true);
1421 } 1546 }
1422 1547
1423 return newFolderID; 1548 return newFolderID;
@@ -1572,11 +1697,11 @@ namespace OpenSim.Region.Framework.Scenes
1572 remoteClient, part, transactionID, currentItem); 1697 remoteClient, part, transactionID, currentItem);
1573 1698
1574 if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) 1699 if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
1575 remoteClient.SendAgentAlertMessage("Notecard saved", false); 1700 remoteClient.SendAlertMessage("Notecard saved");
1576 else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) 1701 else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
1577 remoteClient.SendAgentAlertMessage("Script saved", false); 1702 remoteClient.SendAlertMessage("Script saved");
1578 else 1703 else
1579 remoteClient.SendAgentAlertMessage("Item saved", false); 1704 remoteClient.SendAlertMessage("Item saved");
1580 } 1705 }
1581 1706
1582 // Base ALWAYS has move 1707 // Base ALWAYS has move
@@ -1739,6 +1864,21 @@ namespace OpenSim.Region.Framework.Scenes
1739 /// <returns>The part where the script was rezzed if successful. False otherwise.</returns> 1864 /// <returns>The part where the script was rezzed if successful. False otherwise.</returns>
1740 public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase) 1865 public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase)
1741 { 1866 {
1867 return RezNewScript(
1868 agentID,
1869 itemBase,
1870 "default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}");
1871 }
1872
1873 /// <summary>
1874 /// Rez a new script from nothing with given script text.
1875 /// </summary>
1876 /// <param name="remoteClient"></param>
1877 /// <param name="itemBase">Template item.</param>
1878 /// <param name="scriptText"></param>
1879 /// <returns>The part where the script was rezzed if successful. False otherwise.</returns>
1880 public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase, string scriptText)
1881 {
1742 // The part ID is the folder ID! 1882 // The part ID is the folder ID!
1743 SceneObjectPart part = GetSceneObjectPart(itemBase.Folder); 1883 SceneObjectPart part = GetSceneObjectPart(itemBase.Folder);
1744 if (part == null) 1884 if (part == null)
@@ -1758,9 +1898,14 @@ namespace OpenSim.Region.Framework.Scenes
1758 return null; 1898 return null;
1759 } 1899 }
1760 1900
1761 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, 1901 AssetBase asset
1762 Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"), 1902 = CreateAsset(
1763 agentID); 1903 itemBase.Name,
1904 itemBase.Description,
1905 (sbyte)itemBase.AssetType,
1906 Encoding.ASCII.GetBytes(scriptText),
1907 agentID);
1908
1764 AssetService.Store(asset); 1909 AssetService.Store(asset);
1765 1910
1766 TaskInventoryItem taskItem = new TaskInventoryItem(); 1911 TaskInventoryItem taskItem = new TaskInventoryItem();
@@ -1801,8 +1946,11 @@ namespace OpenSim.Region.Framework.Scenes
1801 /// Rez a script into a prim's inventory from another prim 1946 /// Rez a script into a prim's inventory from another prim
1802 /// </summary> 1947 /// </summary>
1803 /// <param name="remoteClient"></param> 1948 /// <param name="remoteClient"></param>
1804 /// <param name="itemID"> </param> 1949 /// <param name="srcPart"> </param>
1805 /// <param name="localID"></param> 1950 /// <param name="destId"> </param>
1951 /// <param name="pin"></param>
1952 /// <param name="running"></param>
1953 /// <param name="start_param"></param>
1806 public void RezScriptFromPrim(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param) 1954 public void RezScriptFromPrim(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param)
1807 { 1955 {
1808 TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId); 1956 TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId);
@@ -1822,12 +1970,11 @@ namespace OpenSim.Region.Framework.Scenes
1822 if (destPart == null) 1970 if (destPart == null)
1823 { 1971 {
1824 m_log.ErrorFormat( 1972 m_log.ErrorFormat(
1825 "[PRIM INVENTORY]: " + 1973 "[PRIM INVENTORY]: Could not find part {0} to insert script item {1} from {2} {3} in {4}",
1826 "Could not find script for ID {0}", 1974 destId, srcId, srcPart.Name, srcPart.UUID, Name);
1827 destId);
1828 return; 1975 return;
1829 } 1976 }
1830 1977
1831 // Must own the object, and have modify rights 1978 // Must own the object, and have modify rights
1832 if (srcPart.OwnerID != destPart.OwnerID) 1979 if (srcPart.OwnerID != destPart.OwnerID)
1833 { 1980 {
@@ -1835,12 +1982,14 @@ namespace OpenSim.Region.Framework.Scenes
1835 if ((destPart.GroupID == UUID.Zero) || (destPart.GroupID != srcPart.GroupID) || 1982 if ((destPart.GroupID == UUID.Zero) || (destPart.GroupID != srcPart.GroupID) ||
1836 ((destPart.GroupMask & (uint)PermissionMask.Modify) == 0)) 1983 ((destPart.GroupMask & (uint)PermissionMask.Modify) == 0))
1837 return; 1984 return;
1838 } else { 1985 }
1986 else
1987 {
1839 if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0) 1988 if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0)
1840 return; 1989 return;
1841 } 1990 }
1842 1991
1843 if (destPart.ScriptAccessPin != pin) 1992 if (destPart.ScriptAccessPin == 0 || destPart.ScriptAccessPin != pin)
1844 { 1993 {
1845 m_log.WarnFormat( 1994 m_log.WarnFormat(
1846 "[PRIM INVENTORY]: " + 1995 "[PRIM INVENTORY]: " +
@@ -1954,7 +2103,7 @@ namespace OpenSim.Region.Framework.Scenes
1954 deleteGroups.Add(grp); 2103 deleteGroups.Add(grp);
1955 2104
1956 // If child prims have invalid perms, fix them 2105 // If child prims have invalid perms, fix them
1957 grp.AdjustChildPrimPermissions(); 2106 grp.AdjustChildPrimPermissions(false);
1958 2107
1959 if (remoteClient == null) 2108 if (remoteClient == null)
1960 { 2109 {
@@ -2004,7 +2153,10 @@ namespace OpenSim.Region.Framework.Scenes
2004 { 2153 {
2005 // If we don't have permission, stop right here 2154 // If we don't have permission, stop right here
2006 if (!permissionToTakeCopy) 2155 if (!permissionToTakeCopy)
2156 {
2157 remoteClient.SendAlertMessage("You don't have permission to take the object");
2007 return; 2158 return;
2159 }
2008 2160
2009 permissionToTake = true; 2161 permissionToTake = true;
2010 // Don't delete 2162 // Don't delete
@@ -2036,13 +2188,16 @@ namespace OpenSim.Region.Framework.Scenes
2036 } 2188 }
2037 } 2189 }
2038 2190
2191 // OK, we're done with permissions. Let's check if any part of the code prevents the objects from being deleted
2192 bool canDelete = EventManager.TriggerDeRezRequested(remoteClient, deleteGroups, action);
2193
2039 if (permissionToTake && (action != DeRezAction.Delete || this.m_useTrashOnDelete)) 2194 if (permissionToTake && (action != DeRezAction.Delete || this.m_useTrashOnDelete))
2040 { 2195 {
2041 m_asyncSceneObjectDeleter.DeleteToInventory( 2196 m_asyncSceneObjectDeleter.DeleteToInventory(
2042 action, destinationID, deleteGroups, remoteClient, 2197 action, destinationID, deleteGroups, remoteClient,
2043 permissionToDelete); 2198 permissionToDelete && canDelete);
2044 } 2199 }
2045 else if (permissionToDelete) 2200 else if (permissionToDelete && canDelete)
2046 { 2201 {
2047 foreach (SceneObjectGroup g in deleteGroups) 2202 foreach (SceneObjectGroup g in deleteGroups)
2048 DeleteSceneObject(g, false); 2203 DeleteSceneObject(g, false);
@@ -2050,6 +2205,112 @@ namespace OpenSim.Region.Framework.Scenes
2050 } 2205 }
2051 2206
2052 /// <summary> 2207 /// <summary>
2208 /// Returns the list of Scene Objects in an asset.
2209 /// </summary>
2210 /// <remarks>
2211 /// Returns one object if the asset is a regular object, and multiple objects for a coalesced object.
2212 /// </remarks>
2213 /// <param name="assetData">Asset data</param>
2214 /// <param name="isAttachment">True if the object is an attachment.</param>
2215 /// <param name="objlist">The objects included in the asset</param>
2216 /// <param name="veclist">Relative positions of the objects</param>
2217 /// <param name="bbox">Bounding box of all the objects</param>
2218 /// <param name="offsetHeight">Offset in the Z axis from the centre of the bounding box
2219 /// to the centre of the root prim (relevant only when returning a single object)</param>
2220 /// <returns>
2221 /// true if returning a single object or deserialization fails, false if returning the coalesced
2222 /// list of objects
2223 /// </returns>
2224 public bool GetObjectsToRez(
2225 byte[] assetData, bool isAttachment, out List<SceneObjectGroup> objlist, out List<Vector3> veclist,
2226 out Vector3 bbox, out float offsetHeight)
2227 {
2228 objlist = new List<SceneObjectGroup>();
2229 veclist = new List<Vector3>();
2230 bbox = Vector3.Zero;
2231 offsetHeight = 0;
2232
2233 string xmlData = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(assetData));
2234
2235 try
2236 {
2237 using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
2238 {
2239 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
2240 {
2241 reader.Read();
2242 bool isSingleObject = reader.Name != "CoalescedObject";
2243
2244 if (isSingleObject || isAttachment)
2245 {
2246 SceneObjectGroup g;
2247 try
2248 {
2249 g = SceneObjectSerializer.FromOriginalXmlFormat(reader);
2250 }
2251 catch (Exception e)
2252 {
2253 m_log.Error("[AGENT INVENTORY]: Deserialization of xml failed ", e);
2254 Util.LogFailedXML("[AGENT INVENTORY]:", xmlData);
2255 g = null;
2256 }
2257
2258 if (g != null)
2259 {
2260 objlist.Add(g);
2261 veclist.Add(Vector3.Zero);
2262 bbox = g.GetAxisAlignedBoundingBox(out offsetHeight);
2263 }
2264
2265 return true;
2266 }
2267 else
2268 {
2269 XmlDocument doc = new XmlDocument();
2270 doc.LoadXml(xmlData);
2271 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
2272 XmlElement coll = (XmlElement)e;
2273 float bx = Convert.ToSingle(coll.GetAttribute("x"));
2274 float by = Convert.ToSingle(coll.GetAttribute("y"));
2275 float bz = Convert.ToSingle(coll.GetAttribute("z"));
2276 bbox = new Vector3(bx, by, bz);
2277 offsetHeight = 0;
2278
2279 XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
2280 foreach (XmlNode n in groups)
2281 {
2282 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
2283 if (g != null)
2284 {
2285 objlist.Add(g);
2286
2287 XmlElement el = (XmlElement)n;
2288 string rawX = el.GetAttribute("offsetx");
2289 string rawY = el.GetAttribute("offsety");
2290 string rawZ = el.GetAttribute("offsetz");
2291
2292 float x = Convert.ToSingle(rawX);
2293 float y = Convert.ToSingle(rawY);
2294 float z = Convert.ToSingle(rawZ);
2295 veclist.Add(new Vector3(x, y, z));
2296 }
2297 }
2298
2299 return false;
2300 }
2301 }
2302 }
2303 }
2304 catch (Exception e)
2305 {
2306 m_log.Error("[AGENT INVENTORY]: Deserialization of xml failed when looking for CoalescedObject tag ", e);
2307 Util.LogFailedXML("[AGENT INVENTORY]:", xmlData);
2308 }
2309
2310 return true;
2311 }
2312
2313 /// <summary>
2053 /// Event Handler Rez an object into a scene 2314 /// Event Handler Rez an object into a scene
2054 /// Calls the non-void event handler 2315 /// Calls the non-void event handler
2055 /// </summary> 2316 /// </summary>
@@ -2124,19 +2385,25 @@ namespace OpenSim.Region.Framework.Scenes
2124 /// will be used if it exists.</param> 2385 /// will be used if it exists.</param>
2125 /// <param name="vel">The velocity of the rezzed object.</param> 2386 /// <param name="vel">The velocity of the rezzed object.</param>
2126 /// <param name="param"></param> 2387 /// <param name="param"></param>
2127 /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful</returns> 2388 /// <returns>The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful</returns>
2128 public virtual SceneObjectGroup RezObject( 2389 public virtual List<SceneObjectGroup> RezObject(
2129 SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param) 2390 SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param)
2130 { 2391 {
2131 if (null == item) 2392 if (null == item)
2132 return null; 2393 return null;
2394
2395 List<SceneObjectGroup> objlist;
2396 List<Vector3> veclist;
2133 2397
2134 SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item); 2398 bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist);
2135 2399 if (!success)
2136 if (null == group)
2137 return null; 2400 return null;
2138 2401
2139 if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos)) 2402 int totalPrims = 0;
2403 foreach (SceneObjectGroup group in objlist)
2404 totalPrims += group.PrimCount;
2405
2406 if (!Permissions.CanRezObject(totalPrims, item.OwnerID, pos))
2140 return null; 2407 return null;
2141 2408
2142 if (!Permissions.BypassPermissions()) 2409 if (!Permissions.BypassPermissions())
@@ -2145,16 +2412,28 @@ namespace OpenSim.Region.Framework.Scenes
2145 sourcePart.Inventory.RemoveInventoryItem(item.ItemID); 2412 sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
2146 } 2413 }
2147 2414
2148 group.FromPartID = sourcePart.UUID; 2415 for (int i = 0; i < objlist.Count; i++)
2149 AddNewSceneObject(group, true, pos, rot, vel); 2416 {
2150 2417 SceneObjectGroup group = objlist[i];
2151 // We can only call this after adding the scene object, since the scene object references the scene 2418 Vector3 curpos = pos + veclist[i];
2152 // to find out if scripts should be activated at all. 2419
2153 group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); 2420 if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
2154 2421 {
2155 group.ScheduleGroupForFullUpdate(); 2422 group.RootPart.AttachedPos = group.AbsolutePosition;
2156 2423 group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
2157 return group; 2424 }
2425
2426 group.FromPartID = sourcePart.UUID;
2427 AddNewSceneObject(group, true, curpos, rot, vel);
2428
2429 // 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.
2431 group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
2432
2433 group.ScheduleGroupForFullUpdate();
2434 }
2435
2436 return objlist;
2158 } 2437 }
2159 2438
2160 public virtual bool returnObjects(SceneObjectGroup[] returnobjects, 2439 public virtual bool returnObjects(SceneObjectGroup[] returnobjects,