/// <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;
}