diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.Inventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 575 |
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; | |||
30 | using System.Collections; | 30 | using System.Collections; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Text; | 32 | using System.Text; |
33 | using System.Threading; | ||
33 | using System.Timers; | 34 | using System.Timers; |
35 | using System.Xml; | ||
34 | using OpenMetaverse; | 36 | using OpenMetaverse; |
35 | using OpenMetaverse.Packets; | 37 | using OpenMetaverse.Packets; |
36 | using log4net; | 38 | using log4net; |
37 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
40 | using OpenSim.Framework.Serialization.External; | ||
38 | using OpenSim.Region.Framework; | 41 | using OpenSim.Region.Framework; |
39 | using OpenSim.Framework.Client; | 42 | using OpenSim.Framework.Client; |
40 | using OpenSim.Region.Framework.Interfaces; | 43 | using OpenSim.Region.Framework.Interfaces; |
41 | using OpenSim.Region.Framework.Scenes.Serialization; | 44 | using OpenSim.Region.Framework.Scenes.Serialization; |
45 | using OpenSim.Services.Interfaces; | ||
46 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
42 | 47 | ||
43 | namespace OpenSim.Region.Framework.Scenes | 48 | namespace 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, |