/// <summary> /// Delete a scene object from a scene and place in the given avatar's inventory. /// Returns the UUID of the newly created asset. /// </summary> /// <param name="action"></param> /// <param name="folderID"></param> /// <param name="objectGroup"></param> /// <param name="remoteClient"> </param> public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) { UUID assetID = UUID.Zero; Vector3 inventoryStoredPosition = new Vector3 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) ? 250 : objectGroup.AbsolutePosition.X) , (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) ? 250 : objectGroup.AbsolutePosition.X, objectGroup.AbsolutePosition.Z); Vector3 originalPosition = objectGroup.AbsolutePosition; objectGroup.AbsolutePosition = inventoryStoredPosition; string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); objectGroup.AbsolutePosition = originalPosition; // Get the user info of the item destination // UUID userID = UUID.Zero; if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || action == DeRezAction.SaveToExistingUserInventoryItem) { // Take or take copy require a taker // Saving changes requires a local user // if (remoteClient == null) return UUID.Zero; userID = remoteClient.AgentId; } else { // All returns / deletes go to the object owner // userID = objectGroup.RootPart.OwnerID; } if (userID == UUID.Zero) // Can't proceed { return UUID.Zero; } // If we're returning someone's item, it goes back to the // owner's Lost And Found folder. // Delete is treated like return in this case // Deleting your own items makes them go to trash // InventoryFolderBase folder = null; InventoryItemBase item = null; if (DeRezAction.SaveToExistingUserInventoryItem == action) { item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID); item = m_Scene.InventoryService.GetItem(item); //item = userInfo.RootFolder.FindItem( // objectGroup.RootPart.FromUserInventoryItemID); if (null == item) { m_log.DebugFormat( "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", objectGroup.Name, objectGroup.UUID); return UUID.Zero; } } else { // Folder magic // if (action == DeRezAction.Delete) { // Deleting someone else's item // if (remoteClient == null || objectGroup.OwnerID != remoteClient.AgentId) { // Folder skeleton may not be loaded and we // have to wait for the inventory to find // the destination folder // folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } else { // Assume inventory skeleton was loaded during login // and all folders can be found // folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); } } else if (action == DeRezAction.Return) { // Dump to lost + found unconditionally // folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } if (folderID == UUID.Zero && folder == null) { if (action == DeRezAction.Delete) { // Deletes go to trash by default // folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); } else { // Catch all. Use lost & found // folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } } if (folder == null) // None of the above { //folder = userInfo.RootFolder.FindFolder(folderID); folder = new InventoryFolderBase(folderID); if (folder == null) // Nowhere to put it { return UUID.Zero; } } item = new InventoryItemBase(); item.CreatorId = objectGroup.RootPart.CreatorID.ToString(); item.ID = UUID.Random(); item.InvType = (int)InventoryType.Object; item.Folder = folder.ID; item.Owner = userID; } AssetBase asset = CreateAsset( objectGroup.GetPartName(objectGroup.RootPart.LocalId), objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), objectGroup.OwnerID.ToString()); m_Scene.AssetService.Store(asset); assetID = asset.FullID; if (DeRezAction.SaveToExistingUserInventoryItem == action) { item.AssetID = asset.FullID; m_Scene.InventoryService.UpdateItem(item); } else { item.AssetID = asset.FullID; if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) { uint perms = objectGroup.GetEffectivePermissions(); uint nextPerms = (perms & 7) << 13; if ((nextPerms & (uint)PermissionMask.Copy) == 0) perms &= ~(uint)PermissionMask.Copy; if ((nextPerms & (uint)PermissionMask.Transfer) == 0) perms &= ~(uint)PermissionMask.Transfer; if ((nextPerms & (uint)PermissionMask.Modify) == 0) perms &= ~(uint)PermissionMask.Modify; item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask; item.CurrentPermissions = item.BasePermissions; item.NextPermissions = objectGroup.RootPart.NextOwnerMask; item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask; item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask; item.CurrentPermissions |= 8; // Slam! } else { item.BasePermissions = objectGroup.GetEffectivePermissions(); item.CurrentPermissions = objectGroup.GetEffectivePermissions(); item.NextPermissions = objectGroup.RootPart.NextOwnerMask; item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; item.GroupPermissions = objectGroup.RootPart.GroupMask; item.CurrentPermissions |= 8; // Slam! } // TODO: add the new fields (Flags, Sale info, etc) item.CreationDate = Util.UnixTimeSinceEpoch(); item.Description = asset.Description; item.Name = asset.Name; item.AssetType = asset.Type; m_Scene.InventoryService.AddItem(item); if (remoteClient != null && item.Owner == remoteClient.AgentId) { remoteClient.SendInventoryItemCreateUpdate(item, 0); } else { ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); if (notifyUser != null) { notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); } } } return assetID; }
public bool NoCopyObjectOrContents(SceneObjectGroup target) { if (m_allowUserReassignment) return false; // ignore no-copy permissions for "load oar" // "loadexplicit oar" and rezzed in-world object is no-copy return ((target.GetEffectivePermissions(true) & (uint)PermissionMask.Copy) != (uint)PermissionMask.Copy); }