Пример #1
0
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                                      List <ISceneEntity> objectGroups, UUID AgentId,
                                      bool permissionToDelete, bool permissionToTake)
        {
            DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();

            dtis.action             = action;
            dtis.folderID           = folderID;
            dtis.objectGroups       = objectGroups;
            dtis.agentId            = AgentId;
            dtis.permissionToDelete = permissionToDelete;
            dtis.permissionToTake   = permissionToTake;
            //Do this before the locking so that the objects 'appear' gone and the client doesn't think things have gone wrong
            if (permissionToDelete)
            {
                DeleteGroups(objectGroups);
            }

            lock (m_removeFromSimQueue)
            {
                m_removeFromSimQueue.Enqueue(dtis);
            }

            if (!DeleteLoopInUse)
            {
                DeleteLoopInUse = true;
                //m_log.Debug("[SCENE]: Starting delete loop");
                Util.FireAndForget(DoDeleteObject, new Object[] { 0 });
            }
        }
Пример #2
0
        /// <summary>
        ///     Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                                      List <ISceneEntity> objectGroups, UUID agentId,
                                      bool permissionToDelete, bool permissionToTake)
        {
            DeleteToInventoryHolder dtis = new DeleteToInventoryHolder {
                action             = action,
                folderID           = folderID,
                objectGroups       = objectGroups,
                agentId            = agentId,
                permissionToDelete = permissionToDelete,
                permissionToTake   = permissionToTake
            };

            //Do this before the locking so that the objects 'appear' gone and the client doesn't think things have gone wrong
            if (permissionToDelete)
            {
                DeleteGroups(objectGroups);
            }

            m_removeFromSimQueue.Enqueue(dtis);

            if (!DeleteLoopInUse)
            {
                DeleteLoopInUse = true;
                //MainConsole.Instance.Debug("[SCENE]: Starting delete loop");
                Util.FireAndForget(DoDeleteObject);
            }
        }
Пример #3
0
        /// <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,
                                              List <SceneObjectGroup> objectGroups, IClientAPI remoteClient)
        {
            // HACK: This is only working for lists containing a single item!
            // It's just a hack to make this WIP compile and run. Nothing
            // currently calls this with multiple items.
            UUID ret = UUID.Zero;

            Dictionary <UUID, List <SceneObjectGroup> > deletes =
                new Dictionary <UUID, List <SceneObjectGroup> >();

            foreach (SceneObjectGroup g in objectGroups)
            {
                if (!deletes.ContainsKey(g.OwnerID))
                {
                    deletes[g.OwnerID] = new List <SceneObjectGroup>();
                }

                deletes[g.OwnerID].Add(g);
            }

            foreach (List <SceneObjectGroup> objlist in deletes.Values)
            {
                foreach (SceneObjectGroup g in objlist)
                {
                    ret = DeleteToInventory(action, folderID, g, remoteClient);
                }
            }

            return(ret);
        }
Пример #4
0
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                                      SceneObjectGroup objectGroup, IClientAPI remoteClient,
                                      bool permissionToDelete)
        {
            if (Enabled)
            {
                m_inventoryTicker.Stop();
            }

            lock (m_inventoryDeletes)
            {
                DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
                dtis.action             = action;
                dtis.folderID           = folderID;
                dtis.objectGroup        = objectGroup;
                dtis.remoteClient       = remoteClient;
                dtis.permissionToDelete = permissionToDelete;

                m_inventoryDeletes.Enqueue(dtis);
            }

            if (Enabled)
            {
                m_inventoryTicker.Start();
            }

            // Visually remove it, even if it isnt really gone yet.  This means that if we crash before the object
            // has gone to inventory, it will reappear in the region again on restart instead of being lost.
            // This is not ideal since the object will still be available for manipulation when it should be, but it's
            // better than losing the object for now.
            if (permissionToDelete)
            {
                objectGroup.DeleteGroup(false);
            }
        }
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                SceneObjectGroup objectGroup, IClientAPI remoteClient, 
                bool permissionToDelete)
        {
            if (Enabled)
                lock (m_inventoryTicker)
                    m_inventoryTicker.Stop();

            lock (m_inventoryDeletes)
            {
                DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
                dtis.action = action;
                dtis.folderID = folderID;
                dtis.objectGroup = objectGroup;
                dtis.remoteClient = remoteClient;
                dtis.permissionToDelete = permissionToDelete;

                m_inventoryDeletes.Enqueue(dtis);
            }

            if (Enabled)
                lock (m_inventoryTicker)
                    m_inventoryTicker.Start();
        
            // Visually remove it, even if it isnt really gone yet.  This means that if we crash before the object
            // has gone to inventory, it will reappear in the region again on restart instead of being lost.
            // This is not ideal since the object will still be available for manipulation when it should be, but it's
            // better than losing the object for now.
            if (permissionToDelete)
                objectGroup.DeleteGroup(false);
        }
Пример #6
0
        /// <summary>
        /// Delete a scene object asynchronously
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="part"></param>
        /// <param name="action"></param>
        /// <param name="destinationId"></param>
        /// <param name="client"></param>
        public static void DeleteSceneObjectAsync(
            TestScene scene, SceneObjectPart part, DeRezAction action, UUID destinationId, IClientAPI client)
        {
            // Turn off the timer on the async sog deleter - we'll crank it by hand within a unit test
            AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;

            sogd.Enabled = false;

            scene.DeRezObject(client, part.LocalId, UUID.Zero, action, destinationId);
            sogd.InventoryDeQueueAndDelete();
        }
        ///
        /// DeleteToInventory
        ///
        public override UUID DeleteToInventory(DeRezAction action, UUID folderID, List <SceneObjectGroup> objectGroups, IClientAPI remoteClient)
        {
            UUID ret = UUID.Zero;

            // HACK: Only works for lists of length one.
            // Intermediate version, just to make things compile
            foreach (SceneObjectGroup g in objectGroups)
            {
                ret = DeleteToInventory(action, folderID, g, remoteClient);
            }

            return(ret);
        }
Пример #8
0
        ///
        /// DeleteToInventory
        ///
        public override UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient)
        {
            UUID assetID = base.DeleteToInventory(action, folderID, objectGroup, remoteClient);

            if (!assetID.Equals(UUID.Zero))
            {
                UploadInventoryItem(remoteClient.AgentId, assetID, "", 0);
            }
            else
            {
                m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
            }

            return(assetID);
        }
Пример #9
0
        /// <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,
                                              List <SceneObjectGroup> objectGroups, IClientAPI remoteClient)
        {
            // HACK: This is only working for lists containing a single item!
            // It's just a hack to make this WIP compile and run. Nothing
            // currently calls this with multiple items.
            UUID ret = UUID.Zero;

            foreach (SceneObjectGroup g in objectGroups)
            {
                ret = DeleteToInventory(action, folderID, g, remoteClient);
            }

            return(ret);
        }
Пример #10
0
        public virtual List <InventoryItemBase> CopyToInventory(
            DeRezAction action, UUID folderID,
            List <SceneObjectGroup> objectGroups, IClientAPI remoteClient, bool asAttachment)
        {
            List <InventoryItemBase> copiedItems = new List <InventoryItemBase>();

            Dictionary <UUID, List <SceneObjectGroup> > bundlesToCopy = new Dictionary <UUID, List <SceneObjectGroup> >();

            if (CoalesceMultipleObjectsToInventory)
            {
                // The following code groups the SOG's by owner. No objects
                // belonging to different people can be coalesced, for obvious
                // reasons.
                foreach (SceneObjectGroup g in objectGroups)
                {
                    if (!bundlesToCopy.ContainsKey(g.OwnerID))
                    {
                        bundlesToCopy[g.OwnerID] = new List <SceneObjectGroup>();
                    }

                    bundlesToCopy[g.OwnerID].Add(g);
                }
            }
            else
            {
                // If we don't want to coalesce then put every object in its own bundle.
                foreach (SceneObjectGroup g in objectGroups)
                {
                    List <SceneObjectGroup> bundle = new List <SceneObjectGroup>();
                    bundle.Add(g);
                    bundlesToCopy[g.UUID] = bundle;
                }
            }

//            m_log.DebugFormat(
//                "[INVENTORY ACCESS MODULE]: Copying {0} object bundles to folder {1} action {2} for {3}",
//                bundlesToCopy.Count, folderID, action, remoteClient.Name);

            // Each iteration is really a separate asset being created,
            // with distinct destinations as well.
            foreach (List <SceneObjectGroup> bundle in bundlesToCopy.Values)
            {
                copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment));
            }

            return(copiedItems);
        }
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                                      IEnumerable <SceneObjectGroup> objectGroups, IClientAPI remoteClient,
                                      bool permissionToDelete)
        {
            if (Enabled)
            {
                m_inventoryTicker.Stop();
            }


            lock (m_inventoryDeletes)
            {
                DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
                dtis.action       = action;
                dtis.folderID     = folderID;
                dtis.objectGroups = new List <SceneObjectGroup>(objectGroups);

                if (dtis.objectGroups.Count == 0)
                {
                    //something is wrong, caller sent us an empty set
                    throw new ArgumentException("DeleteToInventory() Can not work with an empty set", "objectGroups");
                }

                dtis.remoteClient       = remoteClient;
                dtis.permissionToDelete = permissionToDelete;

                m_inventoryDeletes.Enqueue(dtis);
            }

            if (Enabled)
            {
                m_inventoryTicker.Start();
            }

            // Visually remove it, even if it isnt really gone yet.  This means that if we crash before the object
            // has gone to inventory, it will reappear in the region again on restart instead of being lost.
            // This is not ideal since the object will still be available for manipulation when it should be, but it's
            // better than losing the object for now.
            if (permissionToDelete)
            {
                foreach (SceneObjectGroup group in objectGroups)
                {
                    group.DeleteGroup(false);
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                                      List <SceneObjectGroup> objectGroups, IClientAPI remoteClient,
                                      bool permissionToDelete)
        {
            if (Enabled)
            {
                lock (m_inventoryTicker)
                    m_inventoryTicker.Stop();
            }

            lock (m_inventoryDeletes)
            {
                DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
                dtis.action             = action;
                dtis.folderID           = folderID;
                dtis.objectGroups       = objectGroups;
                dtis.remoteClient       = remoteClient;
                dtis.permissionToDelete = permissionToDelete;

                m_inventoryDeletes.Enqueue(dtis);
            }

            if (Enabled)
            {
                lock (m_inventoryTicker)
                    m_inventoryTicker.Start();
            }

            // Visually remove it, even if it isnt really gone yet.  This means that if we crash before the object
            // has gone to inventory, it will reappear in the region again on restart instead of being lost.
            // This is not ideal since the object will still be available for manipulation when it should be, but it's
            // better than losing the object for now.
            if (permissionToDelete)
            {
                List <uint> killIDs = new List <uint>();

                foreach (SceneObjectGroup g in objectGroups)
                {
                    killIDs.Add(g.LocalId);
                    g.DeleteGroupFromScene(true);
                }

                m_scene.SendKillObject(killIDs);
            }
        }
Пример #13
0
        public virtual UUID CopyToInventory(DeRezAction action, UUID folderID,
                                            List <SceneObjectGroup> objectGroups, IClientAPI remoteClient)
        {
            Dictionary <UUID, List <SceneObjectGroup> > bundlesToCopy = new Dictionary <UUID, List <SceneObjectGroup> >();

            if (CoalesceMultipleObjectsToInventory)
            {
                // The following code groups the SOG's by owner. No objects
                // belonging to different people can be coalesced, for obvious
                // reasons.
                foreach (SceneObjectGroup g in objectGroups)
                {
                    if (!bundlesToCopy.ContainsKey(g.OwnerID))
                    {
                        bundlesToCopy[g.OwnerID] = new List <SceneObjectGroup>();
                    }

                    bundlesToCopy[g.OwnerID].Add(g);
                }
            }
            else
            {
                // If we don't want to coalesce then put every object in its own bundle.
                foreach (SceneObjectGroup g in objectGroups)
                {
                    List <SceneObjectGroup> bundle = new List <SceneObjectGroup>();
                    bundle.Add(g);
                    bundlesToCopy[g.UUID] = bundle;
                }
            }

            // This is method scoped and will be returned. It will be the
            // last created asset id
            UUID assetID = UUID.Zero;

            // Each iteration is really a separate asset being created,
            // with distinct destinations as well.
            foreach (List <SceneObjectGroup> bundle in bundlesToCopy.Values)
            {
                assetID = CopyBundleToInventory(action, folderID, bundle, remoteClient);
            }

            return(assetID);
        }
Пример #14
0
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                IEnumerable<SceneObjectGroup> objectGroups, IClientAPI remoteClient, 
                bool permissionToDelete)
        {
            if (Enabled)
                m_inventoryTicker.Stop();


            lock (m_inventoryDeletes)
            {
                DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
                dtis.action = action;
                dtis.folderID = folderID;
                dtis.objectGroups = new List<SceneObjectGroup>(objectGroups);

                if (dtis.objectGroups.Count == 0)
                {
                    //something is wrong, caller sent us an empty set
                    throw new ArgumentException("DeleteToInventory() Can not work with an empty set", "objectGroups");
                }

                dtis.remoteClient = remoteClient;
                dtis.permissionToDelete = permissionToDelete;

                m_inventoryDeletes.Enqueue(dtis);
            }

            if (Enabled)
                m_inventoryTicker.Start();
        
            // Visually remove it, even if it isnt really gone yet.  This means that if we crash before the object
            // has gone to inventory, it will reappear in the region again on restart instead of being lost.
            // This is not ideal since the object will still be available for manipulation when it should be, but it's
            // better than losing the object for now.
            if (permissionToDelete)
            {
                foreach (SceneObjectGroup group in objectGroups)
                {
                    group.DeleteGroup(false);
                }
            }
        }
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                List<SceneObjectGroup> objectGroups, UUID AgentId,
                bool permissionToDelete, bool permissionToTake)
        {
            DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
            dtis.action = action;
            dtis.folderID = folderID;
            dtis.objectGroups = objectGroups;
            dtis.agentId = AgentId;
            dtis.permissionToDelete = permissionToDelete;
            dtis.permissionToTake = permissionToTake;
            //Do this before the locking so that the objects 'appear' gone and the client doesn't think things have gone wrong
            if (permissionToDelete)
            {
                m_scene.DeleteGroups(objectGroups);
            }

            lock (m_sendToInventoryQueue)
            {
                m_sendToInventoryQueue.Enqueue(dtis);
            }

            lock (m_removeFromSimQueue)
            {
                m_removeFromSimQueue.Enqueue(dtis);
            }

            if (!DeleteLoopInUse)
            {
                DeleteLoopInUse = true;
                //m_log.Debug("[SCENE]: Starting delete loop");
                Util.FireAndForget(DoDeleteObject, new Object[] { 0 });
            }
            if (!SendToInventoryLoopInUse)
            {
                SendToInventoryLoopInUse = true;
                //m_log.Debug("[SCENE]: Starting send to inventory loop");
                Util.FireAndForget(DoSendToInventory, new Object[] { 0 });
            }
        }
Пример #16
0
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                List<SceneObjectGroup> objectGroups, IClientAPI remoteClient, 
                bool permissionToDelete)
        {
            if (Enabled)
                lock (m_inventoryTicker)
                    m_inventoryTicker.Stop();

            lock (m_inventoryDeletes)
            {
                DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
                dtis.action = action;
                dtis.folderID = folderID;
                dtis.objectGroups = objectGroups;
                dtis.remoteClient = remoteClient;
                dtis.permissionToDelete = permissionToDelete;

                m_inventoryDeletes.Enqueue(dtis);
            }

            if (Enabled)
                lock (m_inventoryTicker)
                    m_inventoryTicker.Start();
        
            // Visually remove it, even if it isnt really gone yet.  This means that if we crash before the object
            // has gone to inventory, it will reappear in the region again on restart instead of being lost.
            // This is not ideal since the object will still be available for manipulation when it should be, but it's
            // better than losing the object for now.
            if (permissionToDelete)
            {
                List<uint> killIDs = new List<uint>();

                foreach (SceneObjectGroup g in objectGroups)
                {   killIDs.Add(g.LocalId);
                    g.DeleteGroupFromScene(true);
                }

                m_scene.SendKillObject(killIDs);
            }
        }
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                                      List <SceneObjectGroup> objectGroups, IClientAPI remoteClient,
                                      bool permissionToDelete)
        {
            DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();

            dtis.action             = action;
            dtis.folderID           = folderID;
            dtis.objectGroups       = objectGroups;
            dtis.remoteClient       = remoteClient;
            dtis.permissionToDelete = permissionToDelete;

            m_inventoryDeletes.Enqueue(dtis);

            if (permissionToDelete)
            {
                foreach (SceneObjectGroup g in objectGroups)
                {
                    g.DeleteGroupFromScene(false);
                }
            }

            if (Monitor.TryEnter(m_threadLock))
            {
                if (!m_running)
                {
                    if (Enabled)
                    {
                        m_running = true;
                        Util.FireAndForget(x => InventoryDeQueueAndDelete());
                    }
                    else
                    {
                        m_running = true;
                        InventoryDeQueueAndDelete();
                    }
                }
                Monitor.Exit(m_threadLock);
            }
        }
        // DO NOT OVERRIDE THE BASE METHOD
        public new virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
                                                  SceneObjectGroup objectGroup, IClientAPI remoteClient)
        {
            UUID assetID = base.DeleteToInventory(action, folderID, new List <SceneObjectGroup>()
            {
                objectGroup
            }, remoteClient);

            if (!assetID.Equals(UUID.Zero))
            {
                if (remoteClient != null)
                {
                    UploadInventoryItem(remoteClient.AgentId, assetID, "", 0);
                }
            }
            else
            {
                m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
            }

            return(assetID);
        }
Пример #19
0
        /// <summary>
        /// Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                                      List <SceneObjectGroup> objectGroups, IClientAPI remoteClient,
                                      bool permissionToDelete)
        {
            if (Enabled)
            {
                lock (m_inventoryTicker)
                    m_inventoryTicker.Stop();
            }

            lock (m_inventoryDeletes)
            {
                DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
                dtis.action             = action;
                dtis.folderID           = folderID;
                dtis.objectGroups       = objectGroups;
                dtis.remoteClient       = remoteClient;
                dtis.permissionToDelete = permissionToDelete;

                m_inventoryDeletes.Enqueue(dtis);
            }

            if (permissionToDelete)
            {
                foreach (SceneObjectGroup g in objectGroups)
                {
                    g.DeleteGroupFromScene(false);
                }
            }

            if (Enabled)
            {
                lock (m_inventoryTicker)
                    m_inventoryTicker.Start();
            }
        }
Пример #20
0
        private DeRezActionResult GetIntendedResult(DeRezAction action)
        {
            switch (action)
            {
                case DeRezAction.SaveToExistingUserInventoryItem:
                    return DeRezActionResult.Take;

                case DeRezAction.TakeCopy:
                    return DeRezActionResult.Take;

                case DeRezAction.GodTakeCopy:
                    return DeRezActionResult.Take;

                case DeRezAction.Take:
                    return DeRezActionResult.Both;

                case DeRezAction.Delete:
                    return DeRezActionResult.Both;

                case DeRezAction.Return:
                    return DeRezActionResult.Both;
            }

            return DeRezActionResult.None;
        }
Пример #21
0
        private DeRezActionResult FindDeRezPermissions(IClientAPI remoteClient, SceneObjectGroup grp, DeRezAction action)
        {
            bool permissionToTake = false;
            bool permissionToDelete = false;

            switch (action)
            {
                case DeRezAction.SaveToExistingUserInventoryItem:
                    if (grp.OwnerID == remoteClient.AgentId && grp.RootPart.FromUserInventoryItemID != UUID.Zero)
                    {
                        permissionToTake = true;
                        permissionToDelete = false;
                    }
                    break;

                case DeRezAction.TakeCopy:
                    permissionToTake =
                        Permissions.CanTakeCopyObject(
                        grp.UUID,
                        remoteClient.AgentId);
                    break;

                case DeRezAction.GodTakeCopy:
                    permissionToTake =
                        Permissions.IsGod(
                        remoteClient.AgentId);
                    break;

                case DeRezAction.Take:
                    permissionToTake =
                        Permissions.CanTakeObject(
                        grp.UUID,
                        remoteClient.AgentId);

                    //If they can take, they can delete!
                    permissionToDelete = permissionToTake;
                    break;

                case DeRezAction.Delete:
                    permissionToTake =
                        Permissions.CanDeleteObject(
                        grp.UUID,
                        remoteClient.AgentId);

                    permissionToDelete = permissionToTake;
                    break;

                case DeRezAction.Return:
                    if (remoteClient != null)
                    {
                        permissionToTake =
                                Permissions.CanReturnObject(
                                grp.UUID,
                                remoteClient.AgentId);
                        permissionToDelete = permissionToTake;

                        if (permissionToDelete)
                        {
                            UUID NotifyID = (grp.OwnerID == grp.GroupID) ? grp.RootPart.LastOwnerID : grp.OwnerID; 
                            AddReturn(NotifyID, grp.Name, grp.AbsolutePosition, "parcel owner return");
                        }
                    }
                    else // Auto return passes through here with null agent
                    {
                        permissionToTake = true;
                        permissionToDelete = true;
                    }
                    break;

                default:
                    m_log.DebugFormat(
                    "[AGENT INVENTORY]: Ignoring unexpected derez action {0} for {1}", action, remoteClient.Name);
                    return DeRezActionResult.None;
            }

            if (permissionToTake && permissionToDelete)
            {
                return DeRezActionResult.Both;
            }
            else if (permissionToTake)
            {
                return DeRezActionResult.Take;
            }
            else if (permissionToDelete)
            {
                return DeRezActionResult.Delete;
            }

            return DeRezActionResult.None;
        }
        ///
        /// DeleteToInventory
        ///
        public override UUID DeleteToInventory(DeRezAction action, UUID folderID, List<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
        {
            UUID ret = UUID.Zero;

            // HACK: Only works for lists of length one.
            // Intermediate version, just to make things compile
            foreach (SceneObjectGroup g in objectGroups)
                ret = DeleteToInventory(action, folderID, g, remoteClient);
            
            return ret;
        }
Пример #23
0
 /// <summary>
 /// Called when an object is removed from the environment into inventory.
 /// </summary>
 /// <param name="remoteClient"></param>
 /// <param name="localID"></param>
 /// <param name="groupID"></param>
 /// <param name="action"></param>
 /// <param name="destinationID"></param>
 public virtual void DeRezObject(IClientAPI remoteClient, uint localID,
         UUID groupID, DeRezAction action, UUID destinationID)
 {
     DeRezObjects(remoteClient, new List<uint>() { localID} , groupID, action, destinationID);
 }
Пример #24
0
        /// <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,
                IEnumerable<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
        {
            StringBuilder objectNames = new StringBuilder();
            foreach (var obj in objectGroups)
            {
                objectNames.Append(obj.Name);
                objectNames.Append(", ");
            }

            string agentText = "(unknown/internal)";
            if (remoteClient != null)
                agentText = remoteClient.AgentId.ToString();
            m_log.InfoFormat("[AGENT INVENTORY] About to DeRezAction.{0} for client {1}. Groups: {2}", action, agentText, objectNames.ToString());

            //now lets deal with the individual cases..
            switch (action)
            {
                case DeRezAction.Delete:
                    this.PerformInventoryDelete(folderID, objectGroups, remoteClient);
                    break;

                case DeRezAction.Return:
                    this.PerformInventoryReturn(folderID, objectGroups, remoteClient);
                    break;

                case DeRezAction.GodTakeCopy:
                    this.PerformGodTakeCopy(folderID, objectGroups, remoteClient);
                    break;

                case DeRezAction.SaveToExistingUserInventoryItem:
                    this.PerformSaveToExistingUserInventoryItem(folderID, objectGroups, remoteClient);
                    break;

                case DeRezAction.Take:
                    this.PerformTake(folderID, objectGroups, remoteClient, true);
                    break;

                case DeRezAction.TakeCopy:
                    this.PerformTake(folderID, objectGroups, remoteClient, false);
                    break;
            }

            return UUID.Zero;
        }
Пример #25
0
        /// <summary>
        /// Copy a bundle of objects to inventory.  If there is only one object, then this will create an object
        /// item.  If there are multiple objects then these will be saved as a single coalesced item.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="folderID"></param>
        /// <param name="objlist"></param>
        /// <param name="remoteClient"></param>
        /// <param name="asAttachment">Should be true if the bundle is being copied as an attachment.  This prevents
        /// attempted serialization of any script state which would abort any operating scripts.</param>
        /// <returns>The inventory item created by the copy</returns>
        protected InventoryItemBase CopyBundleToInventory(
            DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient,
            bool asAttachment)
        {
            CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);                
//            Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();

            foreach (SceneObjectGroup objectGroup in objlist)
            {
                if (objectGroup.RootPart.KeyframeMotion != null)
                    objectGroup.RootPart.KeyframeMotion.Stop();
                objectGroup.RootPart.KeyframeMotion = null;
//                Vector3 inventoryStoredPosition = new Vector3
//                            (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
//                                  ? 250
//                                  : objectGroup.AbsolutePosition.X)
//                             ,
//                             (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
//                                 ? 250
//                                 : objectGroup.AbsolutePosition.Y,
//                             objectGroup.AbsolutePosition.Z);
//
//                originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
//
//                objectGroup.AbsolutePosition = inventoryStoredPosition;

                // Make sure all bits but the ones we want are clear
                // on take.
                // This will be applied to the current perms, so
                // it will do what we want.
                objectGroup.RootPart.NextOwnerMask &=
                        ((uint)PermissionMask.Copy |
                         (uint)PermissionMask.Transfer |
                         (uint)PermissionMask.Modify |
                         (uint)PermissionMask.Export);
                objectGroup.RootPart.NextOwnerMask |=
                        (uint)PermissionMask.Move;
                
                coa.Add(objectGroup);
            }

            string itemXml;

            // If we're being called from a script, then trying to serialize that same script's state will not complete
            // in any reasonable time period.  Therefore, we'll avoid it.  The worst that can happen is that if
            // the client/server crashes rather than logging out normally, the attachment's scripts will resume
            // without state on relog.  Arguably, this is what we want anyway.
            if (objlist.Count > 1)
                itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment);
            else
                itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
            
//            // Restore the position of each group now that it has been stored to inventory.
//            foreach (SceneObjectGroup objectGroup in objlist)
//                objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];

            InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);

//            m_log.DebugFormat(
//                "[INVENTORY ACCESS MODULE]: Created item is {0}",
//                item != null ? item.ID.ToString() : "NULL");

            if (item == null)
                return null;
                            
            // Can't know creator is the same, so null it in inventory
            if (objlist.Count > 1)
            {
                item.CreatorId = UUID.Zero.ToString();
                item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
            }
            else
            {
                item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
                item.CreatorData = objlist[0].RootPart.CreatorData;
                item.SaleType = objlist[0].RootPart.ObjectSaleType;
                item.SalePrice = objlist[0].RootPart.SalePrice;                    
            }              

            AssetBase asset = CreateAsset(
                objlist[0].GetPartName(objlist[0].RootPart.LocalId),
                objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
                (sbyte)AssetType.Object,
                Utils.StringToBytes(itemXml),
                objlist[0].OwnerID.ToString());
            m_Scene.AssetService.Store(asset);
            
            item.AssetID = asset.FullID;

            if (DeRezAction.SaveToExistingUserInventoryItem == action)
            {
                m_Scene.InventoryService.UpdateItem(item);
            }
            else
            {
                AddPermissions(item, objlist[0], objlist, remoteClient);

                item.CreationDate = Util.UnixTimeSinceEpoch();
                item.Description = asset.Description;
                item.Name = asset.Name;
                item.AssetType = asset.Type;

                m_Scene.AddInventoryItem(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);
                    }
                }
            }

            // This is a hook to do some per-asset post-processing for subclasses that need that
            if (remoteClient != null)
                ExportAsset(remoteClient.AgentId, asset.FullID);
            
            return item;
        }
Пример #26
0
        /// <summary>
        /// Copy a bundle of objects to inventory.  If there is only one object, then this will create an object
        /// item.  If there are multiple objects then these will be saved as a single coalesced item.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="folderID"></param>
        /// <param name="objlist"></param>
        /// <param name="remoteClient"></param>
        /// <param name="asAttachment">Should be true if the bundle is being copied as an attachment.  This prevents
        /// attempted serialization of any script state which would abort any operating scripts.</param>
        /// <returns>The inventory item created by the copy</returns>
        protected InventoryItemBase CopyBundleToInventory(
            DeRezAction action, UUID folderID, List <SceneObjectGroup> objlist, IClientAPI remoteClient,
            bool asAttachment)
        {
            CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
//            Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();

            Dictionary <SceneObjectGroup, KeyframeMotion> group2Keyframe = new Dictionary <SceneObjectGroup, KeyframeMotion>();

            foreach (SceneObjectGroup objectGroup in objlist)
            {
                if (objectGroup.RootPart.KeyframeMotion != null)
                {
                    objectGroup.RootPart.KeyframeMotion.Pause();
                    group2Keyframe.Add(objectGroup, objectGroup.RootPart.KeyframeMotion);
                    objectGroup.RootPart.KeyframeMotion = null;
                }

//                Vector3 inventoryStoredPosition = new Vector3
//                            (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
//                                  ? 250
//                                  : objectGroup.AbsolutePosition.X)
//                             ,
//                             (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
//                                 ? 250
//                                 : objectGroup.AbsolutePosition.Y,
//                             objectGroup.AbsolutePosition.Z);
//
//                originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
//
//                objectGroup.AbsolutePosition = inventoryStoredPosition;

                // Make sure all bits but the ones we want are clear
                // on take.
                // This will be applied to the current perms, so
                // it will do what we want.
                objectGroup.RootPart.NextOwnerMask &=
                    ((uint)PermissionMask.Copy |
                     (uint)PermissionMask.Transfer |
                     (uint)PermissionMask.Modify |
                     (uint)PermissionMask.Export);
                objectGroup.RootPart.NextOwnerMask |=
                    (uint)PermissionMask.Move;

                coa.Add(objectGroup);
            }

            string itemXml;

            // If we're being called from a script, then trying to serialize that same script's state will not complete
            // in any reasonable time period.  Therefore, we'll avoid it.  The worst that can happen is that if
            // the client/server crashes rather than logging out normally, the attachment's scripts will resume
            // without state on relog.  Arguably, this is what we want anyway.
            if (objlist.Count > 1)
            {
                itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment);
            }
            else
            {
                itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
            }

//            // Restore the position of each group now that it has been stored to inventory.
//            foreach (SceneObjectGroup objectGroup in objlist)
//                objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];

            InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);

//            m_log.DebugFormat(
//                "[INVENTORY ACCESS MODULE]: Created item is {0}",
//                item != null ? item.ID.ToString() : "NULL");

            if (item == null)
            {
                return(null);
            }

            item.CreatorId   = objlist[0].RootPart.CreatorID.ToString();
            item.CreatorData = objlist[0].RootPart.CreatorData;

            if (objlist.Count > 1)
            {
                item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;

                // If the objects have different creators then don't specify a creator at all
                foreach (SceneObjectGroup objectGroup in objlist)
                {
                    if ((objectGroup.RootPart.CreatorID.ToString() != item.CreatorId) ||
                        (objectGroup.RootPart.CreatorData.ToString() != item.CreatorData))
                    {
                        item.CreatorId   = UUID.Zero.ToString();
                        item.CreatorData = string.Empty;
                        break;
                    }
                }
            }
            else
            {
                item.SaleType  = objlist[0].RootPart.ObjectSaleType;
                item.SalePrice = objlist[0].RootPart.SalePrice;
            }

            AssetBase asset = CreateAsset(
                objlist[0].GetPartName(objlist[0].RootPart.LocalId),
                objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
                (sbyte)AssetType.Object,
                Utils.StringToBytes(itemXml),
                objlist[0].OwnerID.ToString());

            m_Scene.AssetService.Store(asset);

            item.AssetID = asset.FullID;

            if (DeRezAction.SaveToExistingUserInventoryItem == action)
            {
                m_Scene.InventoryService.UpdateItem(item);
            }
            else
            {
                item.CreationDate = Util.UnixTimeSinceEpoch();
                item.Description  = asset.Description;
                item.Name         = asset.Name;
                item.AssetType    = asset.Type;

                AddPermissions(item, objlist[0], objlist, remoteClient);

                m_Scene.AddInventoryItem(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);
                    }
                }
            }

            // Restore KeyframeMotion
            foreach (SceneObjectGroup objectGroup in group2Keyframe.Keys)
            {
                objectGroup.RootPart.KeyframeMotion = group2Keyframe[objectGroup];
                objectGroup.RootPart.KeyframeMotion.Start();
            }

            // This is a hook to do some per-asset post-processing for subclasses that need that
            if (remoteClient != null)
            {
                ExportAsset(remoteClient.AgentId, asset.FullID);
            }

            return(item);
        }
        /// <summary>
        /// Copy a bundle of objects to inventory.  If there is only one object, then this will create an object
        /// item.  If there are multiple objects then these will be saved as a single coalesced item.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="folderID"></param>
        /// <param name="objlist"></param>
        /// <param name="remoteClient"></param>
        /// <returns></returns>
        protected UUID CopyBundleToInventory(
            DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient)
        {
            UUID assetID = UUID.Zero;
            
            CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);                
            Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();

            foreach (SceneObjectGroup objectGroup in objlist)
            {
                Vector3 inventoryStoredPosition = new Vector3
                            (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
                                  ? 250
                                  : objectGroup.AbsolutePosition.X)
                             ,
                             (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
                                 ? 250
                                 : objectGroup.AbsolutePosition.Y,
                             objectGroup.AbsolutePosition.Z);

                originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;

                objectGroup.AbsolutePosition = inventoryStoredPosition;

                // Make sure all bits but the ones we want are clear
                // on take.
                // This will be applied to the current perms, so
                // it will do what we want.
                objectGroup.RootPart.NextOwnerMask &=
                        ((uint)PermissionMask.Copy |
                         (uint)PermissionMask.Transfer |
                         (uint)PermissionMask.Modify);
                objectGroup.RootPart.NextOwnerMask |=
                        (uint)PermissionMask.Move;
                
                coa.Add(objectGroup);
            }

            string itemXml;

            if (objlist.Count > 1)
                itemXml = CoalescedSceneObjectsSerializer.ToXml(coa);
            else
                itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]);
            
            // Restore the position of each group now that it has been stored to inventory.
            foreach (SceneObjectGroup objectGroup in objlist)
                objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];

            InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
            if (item == null)
                return UUID.Zero;
                            
            // Can't know creator is the same, so null it in inventory
            if (objlist.Count > 1)
            {
                item.CreatorId = UUID.Zero.ToString();
                item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
            }
            else
            {
                item.CreatorId = objlist[0].RootPart.CreatorID.ToString();                
                item.SaleType = objlist[0].RootPart.ObjectSaleType;
                item.SalePrice = objlist[0].RootPart.SalePrice;                    
            }              

            AssetBase asset = CreateAsset(
                objlist[0].GetPartName(objlist[0].RootPart.LocalId),
                objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
                (sbyte)AssetType.Object,
                Utils.StringToBytes(itemXml),
                objlist[0].OwnerID.ToString());
            m_Scene.AssetService.Store(asset);
            
            item.AssetID = asset.FullID;  
            assetID = asset.FullID;                              

            if (DeRezAction.SaveToExistingUserInventoryItem == action)
            {
                m_Scene.InventoryService.UpdateItem(item);
            }
            else
            {
                AddPermissions(item, objlist[0], objlist, remoteClient);

                item.CreationDate = Util.UnixTimeSinceEpoch();
                item.Description = asset.Description;
                item.Name = asset.Name;
                item.AssetType = asset.Type;

                m_Scene.AddInventoryItem(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);
                    }
                }
            }

            // This is a hook to do some per-asset post-processing for subclasses that need that
            ExportAsset(remoteClient.AgentId, assetID);
            
            return assetID;
        }
Пример #28
0
        /// <summary>
        /// Derez one or more objects from the scene.
        /// </summary>
        /// <remarks>
        /// Won't actually remove the scene object in the case where the object is being copied to a user inventory.
        /// </remarks>
        /// <param name='remoteClient'>Client requesting derez</param>
        /// <param name='localIDs'>Local ids of root parts of objects to delete.</param>
        /// <param name='groupID'>Not currently used.  Here because the client passes this to us.</param>
        /// <param name='action'>DeRezAction</param>
        /// <param name='destinationID'>User folder ID to place derezzed object</param>
        public virtual void DeRezObjects(
            IClientAPI remoteClient, List<uint> localIDs, UUID groupID, DeRezAction action, UUID destinationID)
        {
            // First, see of we can perform the requested action and
            // build a list of eligible objects
            List<uint> deleteIDs = new List<uint>();
            List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();

            // Start with true for both, then remove the flags if objects
            // that we can't derez are part of the selection
            bool permissionToTake = true;
            bool permissionToTakeCopy = true;
            bool permissionToDelete = true;

            foreach (uint localID in localIDs)
            {
                // Invalid id
                SceneObjectPart part = GetSceneObjectPart(localID);
                if (part == null)
                    continue;

                // Already deleted by someone else
                if (part.ParentGroup.IsDeleted)
                    continue;

                // Can't delete child prims
                if (part != part.ParentGroup.RootPart)
                    continue;

                SceneObjectGroup grp = part.ParentGroup;

                deleteIDs.Add(localID);
                deleteGroups.Add(grp);

                // If child prims have invalid perms, fix them
                grp.AdjustChildPrimPermissions(false);

                if (remoteClient == null)
                {
                    // Autoreturn has a null client. Nothing else does. So
                    // allow only returns
                    if (action != DeRezAction.Return)
                    {
                        m_log.WarnFormat(
                            "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client", 
                            action, grp.Name, grp.UUID);
                        return;
                    }

                    permissionToTakeCopy = false;
                }
                else
                {
                    if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId))
                        permissionToTakeCopy = false;
                    
                    if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId))
                        permissionToTake = false;
                    
                    if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId))
                        permissionToDelete = false;
                }
            }

            // Handle god perms
            if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
            {
                permissionToTake = true;
                permissionToTakeCopy = true;
                permissionToDelete = true;
            }

            // If we're re-saving, we don't even want to delete
            if (action == DeRezAction.SaveToExistingUserInventoryItem)
                permissionToDelete = false;

            // if we want to take a copy, we also don't want to delete
            // Note: after this point, the permissionToTakeCopy flag
            // becomes irrelevant. It already includes the permissionToTake
            // permission and after excluding no copy items here, we can
            // just use that.
            if (action == DeRezAction.TakeCopy)
            {
                // If we don't have permission, stop right here
                if (!permissionToTakeCopy)
                {
                    remoteClient.SendAlertMessage("You don't have permission to take the object");
                    return;
                }

                permissionToTake = true;
                // Don't delete
                permissionToDelete = false;
            }

            if (action == DeRezAction.Return)
            {
                if (remoteClient != null)
                {
                    if (Permissions.CanReturnObjects(
                                    null,
                                    remoteClient.AgentId,
                                    deleteGroups))
                    {
                        permissionToTake = true;
                        permissionToDelete = true;

                        foreach (SceneObjectGroup g in deleteGroups)
                        {
                            AddReturn(g.OwnerID == g.GroupID ? g.LastOwnerID : g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return");
                        }
                    }
                }
                else // Auto return passes through here with null agent
                {
                    permissionToTake = true;
                    permissionToDelete = true;
                }
            }

            if (permissionToTake && (action != DeRezAction.Delete || this.m_useTrashOnDelete))
            {
                m_asyncSceneObjectDeleter.DeleteToInventory(
                        action, destinationID, deleteGroups, remoteClient,
                        permissionToDelete);
            }
            else if (permissionToDelete)
            {
                foreach (SceneObjectGroup g in deleteGroups)
                    DeleteSceneObject(g, false);
            }
        }
        /// <summary>
        ///   Delete the given object from the scene
        /// </summary>
        public void DeleteToInventory(DeRezAction action, UUID folderID,
                                      List<ISceneEntity> objectGroups, UUID AgentId,
                                      bool permissionToDelete, bool permissionToTake)
        {
            DeleteToInventoryHolder dtis = new DeleteToInventoryHolder
                                               {
                                                   action = action,
                                                   folderID = folderID,
                                                   objectGroups = objectGroups,
                                                   agentId = AgentId,
                                                   permissionToDelete = permissionToDelete,
                                                   permissionToTake = permissionToTake
                                               };
            //Do this before the locking so that the objects 'appear' gone and the client doesn't think things have gone wrong
            if (permissionToDelete)
            {
                DeleteGroups(objectGroups);
            }

            lock (m_removeFromSimQueue)
            {
                m_removeFromSimQueue.Enqueue(dtis);
            }

            if (!DeleteLoopInUse)
            {
                DeleteLoopInUse = true;
                //MainConsole.Instance.Debug("[SCENE]: Starting delete loop");
                Util.FireAndForget(DoDeleteObject);
            }
        }
Пример #30
0
        /// <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,
                                              List <ISceneEntity> objectGroups, UUID agentId, out UUID itemID)
        {
            itemID = UUID.Zero;
            if (objectGroups.Count == 0)
            {
                return(UUID.Zero);
            }

            UUID    assetID     = UUID.Zero;
            Vector3 GroupMiddle = Vector3.Zero;
            string  AssetXML    = "<groups>";

            if (objectGroups.Count == 1)
            {
                m_scene.AuroraEventManager.FireGenericEventHandler("DeleteToInventory", objectGroups[0]);
                AssetXML = ((ISceneObject)objectGroups[0]).ToXml2();
            }
            else
            {
                foreach (ISceneEntity objectGroup in objectGroups)
                {
                    Vector3 inventoryStoredPosition = new Vector3
                                                          (((objectGroup.AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX)
                                      ? m_scene.RegionInfo.RegionSizeX - 1
                                      : objectGroup.AbsolutePosition.X)
                                                          ,
                                                          (objectGroup.AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY)
                                     ? m_scene.RegionInfo.RegionSizeY - 1
                                     : objectGroup.AbsolutePosition.Y,
                                                          objectGroup.AbsolutePosition.Z);
                    GroupMiddle += inventoryStoredPosition;
                    Vector3 originalPosition = objectGroup.AbsolutePosition;

                    objectGroup.AbsolutePosition = inventoryStoredPosition;

                    m_scene.AuroraEventManager.FireGenericEventHandler("DeleteToInventory", objectGroup);
                    AssetXML += ((ISceneObject)objectGroup).ToXml2();

                    objectGroup.AbsolutePosition = originalPosition;
                }
                GroupMiddle.X /= objectGroups.Count;
                GroupMiddle.Y /= objectGroups.Count;
                GroupMiddle.Z /= objectGroups.Count;
                AssetXML      += "<middle>";
                AssetXML      += "<mid>" + GroupMiddle.ToRawString() + "</mid>";
                AssetXML      += "</middle>";
                AssetXML      += "</groups>";
            }
            // Get the user info of the item destination
            //
            IScenePresence SP     = m_scene.GetScenePresence(agentId);
            UUID           userID = UUID.Zero;

            if (action == DeRezAction.Take || action == DeRezAction.AcquireToUserInventory ||
                action == DeRezAction.SaveToExistingUserInventoryItem)
            {
                // Take or take copy require a taker
                // Saving changes requires a local user
                //
                if (SP == null || SP.ControllingClient == null)
                {
                    return(UUID.Zero);
                }

                userID = agentId;
            }
            else
            {
                // All returns / deletes go to the object owner
                //

                userID = objectGroups[0].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(objectGroups[0].RootChild.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.",
                        objectGroups[0].Name, objectGroups[0].UUID);
                    return(UUID.Zero);
                }
            }
            else
            {
                // Folder magic
                //
                if (action == DeRezAction.Delete)
                {
                    // Deleting someone else's item
                    //

                    if (SP == null || SP.ControllingClient == null ||
                        objectGroups[0].OwnerID != agentId)
                    {
                        folder = m_scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                    }
                    else
                    {
                        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
                    {
                        if (SP == null || SP.ControllingClient == null ||
                            objectGroups[0].OwnerID != agentId)
                        {
                            folder = m_scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                        }
                        else
                        {
                            folder = m_scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
                        }
                    }
                }

                // Override and put into where it came from, if it came
                // from anywhere in inventory
                //
                if (action == DeRezAction.Attachment || action == DeRezAction.Take || action == DeRezAction.AcquireToUserInventory)
                {
                    if (objectGroups[0].RootChild.FromUserInventoryItemID != UUID.Zero)
                    {
                        InventoryFolderBase f = new InventoryFolderBase(objectGroups[0].RootChild.FromUserInventoryItemID, userID);
                        folder = m_scene.InventoryService.GetFolder(f);
                    }
                    else
                    {
                        folder = m_scene.InventoryService.GetFolderForType(userID, AssetType.Object);
                    }
                }

                if (folder == null) // None of the above
                {
                    folder = new InventoryFolderBase(folderID);

                    if (folder == null) // Nowhere to put it
                    {
                        return(UUID.Zero);
                    }
                }

                item           = new InventoryItemBase();
                item.CreatorId = objectGroups[0].RootChild.CreatorID.ToString();
                item.ID        = UUID.Random();
                item.InvType   = (int)InventoryType.Object;
                item.Folder    = folder.ID;
                item.Owner     = userID;
            }

            AssetBase asset = CreateAsset(
                objectGroups[0].Name,
                objectGroups[0].RootChild.Description,
                (sbyte)AssetType.Object,
                Utils.StringToBytes(AssetXML),
                objectGroups[0].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 (SP != null && SP.ControllingClient != null && (SP.ControllingClient.AgentId != objectGroups[0].OwnerID) && m_scene.Permissions.PropagatePermissions())
                {
                    foreach (SceneObjectGroup group in objectGroups)
                    {
                        uint perms     = group.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;
                        }

                        // Make sure all bits but the ones we want are clear
                        // on take.
                        // This will be applied to the current perms, so
                        // it will do what we want.
                        group.RootPart.NextOwnerMask &=
                            ((uint)PermissionMask.Copy |
                             (uint)PermissionMask.Transfer |
                             (uint)PermissionMask.Modify);
                        group.RootPart.NextOwnerMask |=
                            (uint)PermissionMask.Move;

                        item.BasePermissions     = perms & group.RootPart.NextOwnerMask;
                        item.CurrentPermissions  = item.BasePermissions;
                        item.NextPermissions     = group.RootPart.NextOwnerMask;
                        item.EveryOnePermissions = group.RootPart.EveryoneMask & group.RootPart.NextOwnerMask;
                        item.GroupPermissions    = group.RootPart.GroupMask & group.RootPart.NextOwnerMask;

                        // Magic number badness. Maybe this deserves an enum.
                        // bit 4 (16) is the "Slam" bit, it means treat as passed
                        // and apply next owner perms on rez
                        item.CurrentPermissions |= 16; // Slam!
                    }
                }
                else
                {
                    foreach (SceneObjectGroup group in objectGroups)
                    {
                        item.BasePermissions     = group.GetEffectivePermissions();
                        item.CurrentPermissions  = group.GetEffectivePermissions();
                        item.NextPermissions     = group.RootPart.NextOwnerMask;
                        item.EveryOnePermissions = group.RootPart.EveryoneMask;
                        item.GroupPermissions    = group.RootPart.GroupMask;

                        item.CurrentPermissions &=
                            ((uint)PermissionMask.Copy |
                             (uint)PermissionMask.Transfer |
                             (uint)PermissionMask.Modify |
                             (uint)PermissionMask.Move |
                             7);     // Preserve folded permissions
                    }
                }

                // TODO: add the new fields (Flags, Sale info, etc)
                if (objectGroups.Count != 1)
                {
                    item.Flags |= (uint)OpenMetaverse.InventoryItemFlags.ObjectHasMultipleItems;
                }
                item.CreationDate = Util.UnixTimeSinceEpoch();
                item.Description  = asset.Description;
                item.Name         = asset.Name;
                item.AssetType    = asset.Type;

                m_LLCLientInventoryModule.AddInventoryItem(item);

                if (SP != null && SP.ControllingClient != null && item.Owner == SP.ControllingClient.AgentId)
                {
                    SP.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {
                    IScenePresence notifyUser = m_scene.GetScenePresence(item.Owner);
                    if (notifyUser != null)
                    {
                        notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
                    }
                }
            }
            if (item != null)
            {
                itemID = item.ID;
            }
            return(assetID);
        }
Пример #31
0
        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 = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                    }
                    else
                    {
                        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 = 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);
        }
        /// <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,
                List<SceneObjectGroup> objectGroups, UUID agentId, out UUID itemID)
        {
            itemID = UUID.Zero;
            if (objectGroups.Count == 0)
                return UUID.Zero;

            UUID assetID = UUID.Zero;
            Vector3 GroupMiddle = Vector3.Zero;
            string AssetXML = "<groups>";

            if (objectGroups.Count == 1)
            {
                AssetXML = SceneObjectSerializer.ToOriginalXmlFormat(objectGroups[0]);
            }
            else
            {
                foreach (SceneObjectGroup objectGroup in objectGroups)
                {
                    Vector3 inventoryStoredPosition = new Vector3
                                (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
                                      ? 250
                                      : objectGroup.AbsolutePosition.X)
                                 ,
                                 (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
                                     ? 250
                                     : objectGroup.AbsolutePosition.Y,
                                 objectGroup.AbsolutePosition.Z);
                    GroupMiddle += inventoryStoredPosition;
                    Vector3 originalPosition = objectGroup.AbsolutePosition;

                    objectGroup.AbsolutePosition = inventoryStoredPosition;

                    AssetXML += SceneObjectSerializer.ToOriginalXmlFormat(objectGroup);

                    objectGroup.AbsolutePosition = originalPosition;
                }
                GroupMiddle.X /= objectGroups.Count;
                GroupMiddle.Y /= objectGroups.Count;
                GroupMiddle.Z /= objectGroups.Count;
                AssetXML += "<middle>";
                AssetXML += "<mid>" + GroupMiddle.ToRawString() + "</mid>";
                AssetXML += "</middle>";
                AssetXML += "</groups>";
            }
            // Get the user info of the item destination
            //
            ScenePresence SP = m_Scene.GetScenePresence(agentId);
            UUID userID = UUID.Zero;

            if (action == DeRezAction.Take || action == DeRezAction.AcquireToUserInventory ||
                action == DeRezAction.SaveToExistingUserInventoryItem)
            {
                // Take or take copy require a taker
                // Saving changes requires a local user
                //
                if (SP == null || SP.ControllingClient == null)
                    return UUID.Zero;

                userID = agentId;
            }
            else
            {
                // All returns / deletes go to the object owner
                //

                userID = objectGroups[0].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(objectGroups[0].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.",
                        objectGroups[0].Name, objectGroups[0].UUID);
                    return UUID.Zero;
                }
            }
            else
            {
                // Folder magic
                //
                if (action == DeRezAction.Delete)
                {
                    // Deleting someone else's item
                    //

                    if (SP == null || SP.ControllingClient == null ||
                        objectGroups[0].OwnerID != agentId)
                    {

                        folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                    }
                    else
                    {
                         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
                    {
                        if (SP == null || SP.ControllingClient == null ||
                            objectGroups[0].OwnerID != agentId)
                        {

                            folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                        }
                        else
                        {
                            folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
                        }
                    }
                }

                // Override and put into where it came from, if it came
                // from anywhere in inventory
                //
                if (action == DeRezAction.Attachment || action == DeRezAction.Take || action == DeRezAction.AcquireToUserInventory)
                {
                    if (objectGroups[0].RootPart.FromItemID != UUID.Zero)
                    {
                        InventoryFolderBase f = new InventoryFolderBase(objectGroups[0].RootPart.FromItemID, userID);
                        folder = m_Scene.InventoryService.GetFolder(f);
                    }
                    else
                    {
                        folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
                    }
                }

                if (folder == null) // None of the above
                {
                    folder = new InventoryFolderBase(folderID);

                    if (folder == null) // Nowhere to put it
                    {
                        return UUID.Zero;
                    }
                }

                item = new InventoryItemBase();
                item.CreatorId = objectGroups[0].RootPart.CreatorID.ToString();
                item.ID = UUID.Random();
                item.InvType = (int)InventoryType.Object;
                item.Folder = folder.ID;
                item.Owner = userID;
            }

            AssetBase asset = CreateAsset(
                objectGroups[0].GetPartName(objectGroups[0].RootPart.LocalId),
                objectGroups[0].GetPartDescription(objectGroups[0].RootPart.LocalId),
                (sbyte)AssetType.Object,
                Utils.StringToBytes(AssetXML),
                objectGroups[0].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 (SP != null && SP.ControllingClient != null && (SP.ControllingClient.AgentId != objectGroups[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
                {
                    foreach (SceneObjectGroup group in objectGroups)
                    {
                        uint perms = group.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;

                        // Make sure all bits but the ones we want are clear
                        // on take.
                        // This will be applied to the current perms, so
                        // it will do what we want.
                        group.RootPart.NextOwnerMask &=
                                ((uint)PermissionMask.Copy |
                                 (uint)PermissionMask.Transfer |
                                 (uint)PermissionMask.Modify);
                        group.RootPart.NextOwnerMask |=
                                (uint)PermissionMask.Move;

                        item.BasePermissions = perms & group.RootPart.NextOwnerMask;
                        item.CurrentPermissions = item.BasePermissions;
                        item.NextPermissions = group.RootPart.NextOwnerMask;
                        item.EveryOnePermissions = group.RootPart.EveryoneMask & group.RootPart.NextOwnerMask;
                        item.GroupPermissions = group.RootPart.GroupMask & group.RootPart.NextOwnerMask;

                        // Magic number badness. Maybe this deserves an enum.
                        // bit 4 (16) is the "Slam" bit, it means treat as passed
                        // and apply next owner perms on rez
                        item.CurrentPermissions |= 16; // Slam!

                    }
                }
                else
                {
                    foreach (SceneObjectGroup group in objectGroups)
                    {
                        item.BasePermissions = group.GetEffectivePermissions();
                        item.CurrentPermissions = group.GetEffectivePermissions();
                        item.NextPermissions = group.RootPart.NextOwnerMask;
                        item.EveryOnePermissions = group.RootPart.EveryoneMask;
                        item.GroupPermissions = group.RootPart.GroupMask;

                        item.CurrentPermissions &=
                                ((uint)PermissionMask.Copy |
                                 (uint)PermissionMask.Transfer |
                                 (uint)PermissionMask.Modify |
                                 (uint)PermissionMask.Move |
                                 7); // Preserve folded permissions

                    }
                }

                // TODO: add the new fields (Flags, Sale info, etc)
                if(objectGroups.Count != 1)
                    item.Flags |= (uint)OpenMetaverse.InventoryItemFlags.ObjectHasMultipleItems;
                item.CreationDate = Util.UnixTimeSinceEpoch();
                item.Description = asset.Description;
                item.Name = asset.Name;
                item.AssetType = asset.Type;

                m_LLCLientInventoryModule.AddInventoryItem(item);

                if (SP != null && SP.ControllingClient != null && item.Owner == SP.ControllingClient.AgentId)
                {
                    SP.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {
                    ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
                    if (notifyUser != null)
                    {
                        notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
                    }
                }
            }
            if (item != null)
                itemID = item.ID;
            return assetID;
        }
Пример #33
0
        public virtual void DeRezObject(IClientAPI remoteClient, uint localId,
            UUID groupId, DeRezAction action, UUID destinationID)
        {
            List<uint> partInfo = new List<uint>();
            partInfo.Add(localId);

            this.DeRezObjects(remoteClient, partInfo, groupId, action, destinationID);
        }
        /// <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;
        }
Пример #35
0
        /// <summary>
        /// Called when an object is removed from the environment into inventory.
        /// </summary>
        /// <param name="remoteClient"></param>
        /// <param name="localID"></param>
        /// <param name="groupID"></param>
        /// <param name="action"></param>
        /// <param name="destinationID"></param>
        public virtual void DeRezObjects(IClientAPI remoteClient, ICollection<uint> objectParts, 
            UUID groupId, DeRezAction action, UUID destinationID)
        {
            //get the intended behavior of this action
            DeRezActionResult intendedResult = this.GetIntendedResult(action);

            //List for collecting found prims
            List<SceneObjectGroup> groupsToDerez = new List<SceneObjectGroup>();
            bool abort = false;
            bool reportErrorForNoGroupsReturned = true;

            using (SceneTransaction transaction = SceneGraph.BeginPrimTransaction(objectParts))
            {
                try
                {
                    //check to make sure each part can meet the intended result
                    //skip with null client
                    if (remoteClient != null)
                    {
                        foreach (uint partInfo in objectParts)
                        {
                            SceneObjectGroup grp = this.FindGroupAppropriateForDeRez(partInfo);
                            if (grp == null) return; //couldn't find groups
                            if (grp.IsAttachment) continue; //none of this should be done on attachments

                            if (this.FindDeRezPermissions(remoteClient, grp, action) != this.GetIntendedResult(action))
                            {
                                //missing permissions for one or more of the objects
                                remoteClient.SendAlertMessage("Insuffient permissions on '" + grp.Name + "'.");
                                return;
                            }
                            else
                            {
                                if (!this.AddToListIfDerezOk(intendedResult, grp, groupsToDerez))
                                {
                                    //could not derez
                                    abort = true;
                                    remoteClient.SendBlueBoxMessage(UUID.Zero, String.Empty, "Could not take/remove '" + grp.Name + "', operation aborted.");
                                    return;
                                }
                            }
                        }
                    }
                    else
                    {
                        //delete called from parcel return
                        foreach (uint partInfo in objectParts)
                        {
                            SceneObjectGroup grp = this.FindGroupAppropriateForDeRez(partInfo);
                            if (grp == null) return; //couldn't find groups
                            if (grp.IsAttachment) continue; //none of this should be done on attachments

                            //protect against a return on the same object happing multiple times
                            if (!this.AddToListIfDerezOk(intendedResult, grp, groupsToDerez))
                            {
                                //could not derez
                                reportErrorForNoGroupsReturned = false;
                                continue;
                            }
                        }
                    }

                    if (groupsToDerez.Count == 0)
                    {
                        //there must've been a problem locating the group(s), inform the user

                        if (reportErrorForNoGroupsReturned)
                        {
                            m_log.ErrorFormat("[Scene.Inventory] No groups found to derez after scene search, Action: {0}", action);
                        }

                        /*
                        if (remoteClient != null)
                        {
                            remoteClient.SendBlueBoxMessage(UUID.Zero, String.Empty, "Could not find objects to derez");
                        }
                        */
                        return;
                    }

                    //if we got here, we can start completing the requested action
                    ForceBulkSceneObjectBackup(groupsToDerez);

                    if (intendedResult == DeRezActionResult.Both || intendedResult == DeRezActionResult.Take)
                    {
                        m_asyncSceneObjectDeleter.DeleteToInventory(
                                action, destinationID, groupsToDerez, remoteClient,
                                intendedResult == DeRezActionResult.Both //also delete?
                                );
                    }
                    else if (intendedResult == DeRezActionResult.Delete)
                    {
                        DeleteSceneObjects(groupsToDerez, false);
                    }
                }
                finally
                {
                    if (abort)
                    {
                        //clean up the derezzed flag 
                        foreach (var group in groupsToDerez)
                        {
                            group.IsBeingDerezzed = false;
                        }
                    }
                }
            }
        }
Пример #36
0
        ///
        /// DeleteToInventory
        ///
        public override UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient)
        {
            UUID assetID = base.DeleteToInventory(action, folderID, objectGroup, remoteClient);

            if (!assetID.Equals(UUID.Zero))
            {
                UploadInventoryItem(remoteClient.AgentId, assetID, "", 0);
            }
            else
                m_log.Debug("[HGScene]: Scene.Inventory did not create asset");

            return assetID;
        }
Пример #37
0
        public virtual List<InventoryItemBase> CopyToInventory(
            DeRezAction action, UUID folderID,
            List<SceneObjectGroup> objectGroups, IClientAPI remoteClient, bool asAttachment)
        {
            List<InventoryItemBase> copiedItems = new List<InventoryItemBase>();

            Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>();
            
            if (CoalesceMultipleObjectsToInventory)
            {
                // The following code groups the SOG's by owner. No objects
                // belonging to different people can be coalesced, for obvious
                // reasons.
                foreach (SceneObjectGroup g in objectGroups)
                {
                    if (!bundlesToCopy.ContainsKey(g.OwnerID))
                        bundlesToCopy[g.OwnerID] = new List<SceneObjectGroup>();
    
                    bundlesToCopy[g.OwnerID].Add(g);
                }
            }
            else
            {
                // If we don't want to coalesce then put every object in its own bundle.
                foreach (SceneObjectGroup g in objectGroups)
                {
                    List<SceneObjectGroup> bundle = new List<SceneObjectGroup>();
                    bundle.Add(g);
                    bundlesToCopy[g.UUID] = bundle;                    
                }
            }

//            m_log.DebugFormat(
//                "[INVENTORY ACCESS MODULE]: Copying {0} object bundles to folder {1} action {2} for {3}",
//                bundlesToCopy.Count, folderID, action, remoteClient.Name);

            // Each iteration is really a separate asset being created,
            // with distinct destinations as well.
            foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values)
                copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment));
            
            return copiedItems;
        }
Пример #38
0
   /// <summary>
 /// Called when one or more objects are removed from the environment into inventory.
 /// </summary>
 /// <param name="remoteClient"></param>
 /// <param name="localID"></param>
 /// <param name="groupID"></param>
 /// <param name="action"></param>
 /// <param name="destinationID"></param>
 public virtual void DeRezObject(IClientAPI remoteClient, List<uint> localIDs,
         UUID groupID, DeRezAction action, UUID destinationID)
 {
     foreach (uint localID in localIDs)
     {
         DeRezObject(remoteClient, localID, groupID, action, destinationID);
     }
 }
Пример #39
0
        /// <summary>
        /// Create an item using details for the given scene object.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="remoteClient"></param>
        /// <param name="so"></param>
        /// <param name="folderID"></param>
        /// <returns></returns>
        protected InventoryItemBase CreateItemForObject(
            DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID)
        {
            // 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 null;

                userID = remoteClient.AgentId;

//                m_log.DebugFormat(
//                    "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is {1} {2}",
//                    action, remoteClient.Name, userID);
            }
            else if (so.RootPart.OwnerID == so.RootPart.GroupID)
            {
                // Group owned objects go to the last owner before the object was transferred.
                userID = so.RootPart.LastOwnerID;
            }
            else
            {
                // Other returns / deletes go to the object owner
                //
                userID = so.RootPart.OwnerID;

//                m_log.DebugFormat(
//                    "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is object owner {1}",
//                    action, userID);
            }

            if (userID == UUID.Zero) // Can't proceed
            {
                return null;
            }

            // 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(so.RootPart.FromUserInventoryItemID, userID);
                item = m_Scene.InventoryService.GetItem(item);

                //item = userInfo.RootFolder.FindItem(
                //        objectGroup.RootPart.FromUserInventoryItemID);

                if (null == item)
                {
                    m_log.DebugFormat(
                        "[INVENTORY ACCESS MODULE]:  Object {0} {1} scheduled for save to inventory has already been deleted.",
                        so.Name, so.UUID);
                    
                    return null;
                }
            }
            else
            {
                // Folder magic
                //
                if (action == DeRezAction.Delete)
                {
                    // Deleting someone else's item
                    //
                    if (remoteClient == null ||
                        so.OwnerID != remoteClient.AgentId)
                    {
                        folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                    }
                    else
                    {
                        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
                    {
                        if (remoteClient == null || so.RootPart.OwnerID != remoteClient.AgentId)
                        {
                            // Taking copy of another person's item. Take to
                            // Objects folder.
                            folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
                            so.FromFolderID = UUID.Zero;
                        }
                        else
                        {
                            // Catch all. Use lost & found
                            //
                            folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                        }
                    }
                }

                // Override and put into where it came from, if it came
                // from anywhere in inventory and the owner is taking it back.
                //
                if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
                {
                    if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId)
                    {
                        InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
                        folder = m_Scene.InventoryService.GetFolder(f);

                        if(folder.Type == 14 || folder.Type == 16)
                        {
                            // folder.Type = 6;
                            folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
                        }
                    }
                }

                if (folder == null) // None of the above
                {
                    folder = new InventoryFolderBase(folderID);

                    if (folder == null) // Nowhere to put it
                    {
                        return null;
                    }
                }

                item = new InventoryItemBase();                
                item.ID = UUID.Random();
                item.InvType = (int)InventoryType.Object;
                item.Folder = folder.ID;
                item.Owner = userID;
            }   
            
            return item;
        }
Пример #40
0
        /// <summary>
        /// Called when an object is removed from the environment into inventory.
        /// </summary>
        /// <param name="remoteClient"></param>
        /// <param name="localID"></param>
        /// <param name="groupID"></param>
        /// <param name="action"></param>
        /// <param name="destinationID"></param>
        public virtual void DeRezObject(IClientAPI remoteClient, uint localID,
                UUID groupID, DeRezAction action, UUID destinationID)
        {
            SceneObjectPart part = GetSceneObjectPart(localID);
            if (part == null)
                return;

            if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
                return;

            // Can't delete child prims
            if (part != part.ParentGroup.RootPart)
                return;

            SceneObjectGroup grp = part.ParentGroup;

            //force a database backup/update on this SceneObjectGroup
            //So that we know the database is upto date, for when deleting the object from it
            ForceSceneObjectBackup(grp);

            bool permissionToTake = false;
            bool permissionToDelete = false;

            if (action == DeRezAction.SaveToExistingUserInventoryItem)
            {
                if (grp.OwnerID == remoteClient.AgentId && grp.RootPart.FromUserInventoryItemID != UUID.Zero)
                {
                    permissionToTake = true;
                    permissionToDelete = false;
                }
            }
            else if (action == DeRezAction.TakeCopy)
            {
                permissionToTake =
                        Permissions.CanTakeCopyObject(
                        grp.UUID,
                        remoteClient.AgentId);
            }
            else if (action == DeRezAction.GodTakeCopy)
            {
                permissionToTake =
                        Permissions.IsGod(
                        remoteClient.AgentId);
            }
            else if (action == DeRezAction.Take)
            {
                permissionToTake =
                        Permissions.CanTakeObject(
                        grp.UUID,
                        remoteClient.AgentId);

                //If they can take, they can delete!
                permissionToDelete = permissionToTake;
            }
            else if (action == DeRezAction.Delete)
            {
                permissionToTake =
                        Permissions.CanDeleteObject(
                        grp.UUID,
                        remoteClient.AgentId);
                permissionToDelete = permissionToTake;
            }
            else if (action == DeRezAction.Return)
            {
                if (remoteClient != null)
                {
                    permissionToTake =
                            Permissions.CanReturnObject(
                            grp.UUID,
                            remoteClient.AgentId);
                    permissionToDelete = permissionToTake;

                    if (permissionToDelete)
                    {
                        AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
                    }
                }
                else // Auto return passes through here with null agent
                {
                    permissionToTake = true;
                    permissionToDelete = true;
                }
            }
            else
            {
                m_log.DebugFormat(
                    "[AGENT INVENTORY]: Ignoring unexpected derez action {0} for {1}", action, remoteClient.Name);
                return;
            }

            if (permissionToTake)
            {
                m_asyncSceneObjectDeleter.DeleteToInventory(
                        action, destinationID, grp, remoteClient,
                        permissionToDelete);
            }
            else if (permissionToDelete)
            {
                DeleteSceneObject(grp, false);
            }
        }
Пример #41
0
        /// <summary>
        /// Delete a scene object asynchronously
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="part"></param>
        /// <param name="action"></param>
        /// <param name="destinationId"></param>
        /// <param name="client"></param>
        public static void DeleteSceneObjectAsync(
            TestScene scene, SceneObjectPart part, DeRezAction action, UUID destinationId, IClientAPI client)
        {
            // Turn off the timer on the async sog deleter - we'll crank it by hand within a unit test
            AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
            sogd.Enabled = false;

            scene.DeRezObject(client, part.LocalId, UUID.Zero, action, destinationId);
            sogd.InventoryDeQueueAndDelete();
        }
Пример #42
0
        public virtual void DeRezObjects(IClientAPI remoteClient, List<uint> localIDs,
                UUID groupID, DeRezAction action, UUID destinationID)
        {
            // First, see of we can perform the requested action and
            // build a list of eligible objects
            List<uint> deleteIDs = new List<uint>();
            List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();

            // Start with true for both, then remove the flags if objects
            // that we can't derez are part of the selection
            bool permissionToTake = true;
            bool permissionToTakeCopy = true;
            bool permissionToDelete = true;

            foreach (uint localID in localIDs)
            {
                // Invalid id
                SceneObjectPart part = GetSceneObjectPart(localID);
                if (part == null)
                    continue;

                // Already deleted by someone else
                if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
                    continue;

                // Can't delete child prims
                if (part != part.ParentGroup.RootPart)
                    continue;

                SceneObjectGroup grp = part.ParentGroup;

                deleteIDs.Add(localID);
                deleteGroups.Add(grp);

                // Force a database backup/update on this SceneObjectGroup
                // So that we know the database is upto date,
                // for when deleting the object from it
                ForceSceneObjectBackup(grp);

                if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId))
                    permissionToTakeCopy = false;
                if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId))
                    permissionToTake = false;

                if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId))
                    permissionToDelete = false;

            }

            // Handle god perms
            if (Permissions.IsGod(remoteClient.AgentId))
            {
                permissionToTake = true;
                permissionToTakeCopy = true;
                permissionToDelete = true;
            }

            // If we're re-saving, we don't even want to delete
            if (action == DeRezAction.SaveToExistingUserInventoryItem)
                permissionToDelete = false;

            // if we want to take a copy,, we also don't want to delete
            // Note: after this point, the permissionToTakeCopy flag
            // becomes irrelevant. It already includes the permissionToTake
            // permission and after excluding no copy items here, we can
            // just use that.
            if (action == DeRezAction.TakeCopy)
            {
                // If we don't have permission, stop right here
                if (!permissionToTakeCopy)
                    return;

                // Don't delete
                permissionToDelete = false;
            }

            if (action == DeRezAction.Return)
            {
                if (remoteClient != null)
                {
                    if (Permissions.CanReturnObjects(
                                    null,
                                    remoteClient.AgentId,
                                    deleteGroups))
                    {
                        permissionToTake = true;
                        permissionToDelete = true;

                        foreach (SceneObjectGroup g in deleteGroups)
                        {
                            AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return");
                        }
                    }
                }
                else // Auto return passes through here with null agent
                {
                    permissionToTake = true;
                    permissionToDelete = true;
                }
            }

            if (permissionToTake)
            {
                m_asyncSceneObjectDeleter.DeleteToInventory(
                        action, destinationID, deleteGroups, remoteClient,
                        permissionToDelete);
            }
            else if (permissionToDelete)
            {
                foreach (SceneObjectGroup g in deleteGroups)
                    DeleteSceneObject(g, false);
            }
        }
        /// <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="objectGroups"></param>
        /// <param name="agentId"></param>
        /// <param name="itemID"></param>
        public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
            List<ISceneEntity> objectGroups, UUID agentId, out UUID itemID)
        {
            itemID = UUID.Zero;
            if (objectGroups.Count == 0)
                return UUID.Zero;

            // Get the user info of the item destination
            //
            IScenePresence SP = m_scene.GetScenePresence(agentId);
            UUID userID = UUID.Zero;

            if (action == DeRezAction.Take || action == DeRezAction.AcquireToUserInventory ||
                action == DeRezAction.SaveToExistingUserInventoryItem)
            {
                // Take or take copy require a taker
                // Saving changes requires a local user
                //
                if (SP == null || SP.ControllingClient == null)
                    return UUID.Zero;

                userID = agentId;
            }
            else
            {
                // All returns / deletes go to the object owner
                //

                userID = objectGroups[0].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 = m_scene.InventoryService.GetItem(userID, objectGroups[0].RootChild.FromUserInventoryItemID);

                //item = userInfo.RootFolder.FindItem(
                //        objectGroup.RootPart.FromUserInventoryItemID);

                if (null == item)
                {
                    MainConsole.Instance.DebugFormat(
                        "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
                        objectGroups[0].Name, objectGroups[0].UUID);
                    return UUID.Zero;
                }
            }
            else
            {
                // Folder magic
                //
                if (action == DeRezAction.Delete)
                {
                    // Deleting someone else's item
                    //

                    if (SP == null || SP.ControllingClient == null ||
                        objectGroups[0].OwnerID != agentId)
                    {
                        folder = m_scene.InventoryService.GetFolderForType(userID, InventoryType.Unknown,
                                                                           AssetType.LostAndFoundFolder);
                    }
                    else
                    {
                        folder = m_scene.InventoryService.GetFolderForType(userID, InventoryType.Unknown,
                                                                           AssetType.TrashFolder);
                    }
                }
                else if (action == DeRezAction.Return)
                {
                    // Dump to lost + found unconditionally
                    //
                    folder = m_scene.InventoryService.GetFolderForType(userID, InventoryType.Unknown,
                                                                       AssetType.LostAndFoundFolder);
                }

                if (folderID == UUID.Zero && folder == null)
                {
                    if (action == DeRezAction.Delete)
                    {
                        // Deletes go to trash by default
                        //
                        folder = m_scene.InventoryService.GetFolderForType(userID, InventoryType.Unknown,
                                                                           AssetType.TrashFolder);
                    }
                    else
                    {
                        if (SP == null || SP.ControllingClient == null ||
                            objectGroups[0].OwnerID != agentId)
                        {
                            folder = m_scene.InventoryService.GetFolderForType(userID, InventoryType.Unknown,
                                                                               AssetType.LostAndFoundFolder);
                        }
                        else
                        {
                            folder = m_scene.InventoryService.GetFolderForType(userID, InventoryType.Unknown,
                                                                               AssetType.TrashFolder);
                        }
                    }
                }

                // Override and put into where it came from, if it came
                // from anywhere in inventory
                //
                if (action == DeRezAction.Attachment || action == DeRezAction.Take ||
                    action == DeRezAction.AcquireToUserInventory)
                {
                    if (objectGroups[0].RootChild.FromUserInventoryItemID != UUID.Zero)
                    {
                        InventoryFolderBase f =
                            new InventoryFolderBase(objectGroups[0].RootChild.FromUserInventoryItemID, userID);
                        folder = m_scene.InventoryService.GetFolder(f);
                    }
                    else
                    {
                        folder = m_scene.InventoryService.GetFolderForType(userID, InventoryType.Object,
                                                                           AssetType.Object);
                    }
                }

                if (folder == null) // None of the above
                {
                    folder = new InventoryFolderBase(folderID);
                }

                item = new InventoryItemBase
                           {
                               CreatorId = objectGroups[0].RootChild.CreatorID.ToString(),
                               ID = UUID.Random(),
                               InvType = (int) InventoryType.Object,
                               Folder = folder.ID,
                               Owner = userID
                           };
            }

            AssetBase asset;
            UUID assetID = SaveAsAsset(objectGroups, out asset);
            item.AssetID = assetID;
            if (DeRezAction.SaveToExistingUserInventoryItem != action)
            {
                item.Description = asset.Description;
                item.Name = asset.Name;
                item.AssetType = asset.Type;
            }

            if (DeRezAction.SaveToExistingUserInventoryItem == action)
            {
                m_scene.InventoryService.UpdateItem(item);
            }
            else
            {
                if (SP != null && SP.ControllingClient != null &&
                    (SP.ControllingClient.AgentId != objectGroups[0].OwnerID) &&
                    m_scene.Permissions.PropagatePermissions())
                {
                    foreach (ISceneEntity group in objectGroups)
                    {
                        uint perms = group.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;

                        // Make sure all bits but the ones we want are clear
                        // on take.
                        // This will be applied to the current perms, so
                        // it will do what we want.
                        group.RootChild.NextOwnerMask &=
                            ((uint) PermissionMask.Copy |
                             (uint) PermissionMask.Transfer |
                             (uint) PermissionMask.Modify);
                        group.RootChild.NextOwnerMask |=
                            (uint) PermissionMask.Move;

                        item.BasePermissions = perms & group.RootChild.NextOwnerMask;
                        item.CurrentPermissions = item.BasePermissions;
                        item.NextPermissions = group.RootChild.NextOwnerMask;
                        item.EveryOnePermissions = group.RootChild.EveryoneMask & group.RootChild.NextOwnerMask;
                        item.GroupPermissions = group.RootChild.GroupMask & group.RootChild.NextOwnerMask;

                        // Magic number badness. Maybe this deserves an enum.
                        // bit 4 (16) is the "Slam" bit, it means treat as passed
                        // and apply next owner perms on rez
                        item.CurrentPermissions |= 16; // Slam!

                        item.SalePrice = group.RootChild.SalePrice;
                        item.SaleType = group.RootChild.ObjectSaleType;
                    }
                }
                else
                {
                    foreach (ISceneEntity group in objectGroups)
                    {
                        item.BasePermissions = group.GetEffectivePermissions();
                        item.CurrentPermissions = group.GetEffectivePermissions();
                        item.NextPermissions = group.RootChild.NextOwnerMask;
                        item.EveryOnePermissions = group.RootChild.EveryoneMask;
                        item.GroupPermissions = group.RootChild.GroupMask;

                        item.SalePrice = group.RootChild.SalePrice;
                        item.SaleType = group.RootChild.ObjectSaleType;

                        item.CurrentPermissions &=
                            ((uint) PermissionMask.Copy |
                             (uint) PermissionMask.Transfer |
                             (uint) PermissionMask.Modify |
                             (uint) PermissionMask.Move |
                             7); // Preserve folded permissions
                    }
                }

                if (objectGroups.Count != 1)
                    item.Flags |= (uint) InventoryItemFlags.ObjectHasMultipleItems;
                item.CreationDate = Util.UnixTimeSinceEpoch();

                m_LLCLientInventoryModule.AddInventoryItem(item);

                if (SP != null && SP.ControllingClient != null && item.Owner == SP.ControllingClient.AgentId)
                {
                    SP.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {
                    IScenePresence notifyUser = m_scene.GetScenePresence(item.Owner);
                    if (notifyUser != null)
                    {
                        notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
                    }
                }
            }
            itemID = item.ID;
            return assetID;
        }
        /// <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,
                List<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
        {
            // HACK: This is only working for lists containing a single item!
            // It's just a hack to make this WIP compile and run. Nothing
            // currently calls this with multiple items.
            UUID ret = UUID.Zero; 

            Dictionary<UUID, List<SceneObjectGroup>> deletes =
                    new Dictionary<UUID, List<SceneObjectGroup>>();

            foreach (SceneObjectGroup g in objectGroups)
            {
                if (!deletes.ContainsKey(g.OwnerID))
                    deletes[g.OwnerID] = new List<SceneObjectGroup>();

                deletes[g.OwnerID].Add(g);
            }

            foreach (List<SceneObjectGroup> objlist in deletes.Values)
            {
                foreach (SceneObjectGroup g in objlist)
                    ret = DeleteToInventory(action, folderID, g, remoteClient);
            }

            return ret;
        }
Пример #45
0
        public bool TriggerDeRezRequested(IClientAPI client, List<SceneObjectGroup> objs, DeRezAction action)
        {
            bool canDeRez = true;

            DeRezRequested handlerDeRezRequested = OnDeRezRequested;
            if (handlerDeRezRequested != null)
            {
                foreach (DeRezRequested d in handlerDeRezRequested.GetInvocationList())
                {
                    try
                    {
                        canDeRez &= d(client, objs, action);
                    }
                    catch (Exception e)
                    {
                        m_log.ErrorFormat(
                            "[EVENT MANAGER]: Delegate for TriggerDeRezRequested failed - continuing.  {0} {1}",
                            e.Message, e.StackTrace);
                    }
                }
            }

            return canDeRez;
        }
Пример #46
0
        /// <summary>
        /// Copy a bundle of objects to inventory.  If there is only one object, then this will create an object
        /// item.  If there are multiple objects then these will be saved as a single coalesced item.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="folderID"></param>
        /// <param name="objlist"></param>
        /// <param name="remoteClient"></param>
        /// <returns></returns>
        protected UUID CopyBundleToInventory(
            DeRezAction action, UUID folderID, List <SceneObjectGroup> objlist, IClientAPI remoteClient)
        {
            UUID assetID = UUID.Zero;

            CoalescedSceneObjects      coa = new CoalescedSceneObjects(UUID.Zero);
            Dictionary <UUID, Vector3> originalPositions = new Dictionary <UUID, Vector3>();

            foreach (SceneObjectGroup objectGroup in objlist)
            {
                Vector3 inventoryStoredPosition = new Vector3
                                                      (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
                                  ? 250
                                  : objectGroup.AbsolutePosition.X)
                                                      ,
                                                      (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
                                 ? 250
                                 : objectGroup.AbsolutePosition.Y,
                                                      objectGroup.AbsolutePosition.Z);

                originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;

                objectGroup.AbsolutePosition = inventoryStoredPosition;

                // Make sure all bits but the ones we want are clear
                // on take.
                // This will be applied to the current perms, so
                // it will do what we want.
                objectGroup.RootPart.NextOwnerMask &=
                    ((uint)PermissionMask.Copy |
                     (uint)PermissionMask.Transfer |
                     (uint)PermissionMask.Modify);
                objectGroup.RootPart.NextOwnerMask |=
                    (uint)PermissionMask.Move;

                coa.Add(objectGroup);
            }

            string itemXml;

            if (objlist.Count > 1)
            {
                itemXml = CoalescedSceneObjectsSerializer.ToXml(coa);
            }
            else
            {
                itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]);
            }

            // Restore the position of each group now that it has been stored to inventory.
            foreach (SceneObjectGroup objectGroup in objlist)
            {
                objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
            }

            InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);

            if (item == null)
            {
                return(UUID.Zero);
            }

            // Can't know creator is the same, so null it in inventory
            if (objlist.Count > 1)
            {
                item.CreatorId = UUID.Zero.ToString();
                item.Flags     = (uint)InventoryItemFlags.ObjectHasMultipleItems;
            }
            else
            {
                item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
                item.SaleType  = objlist[0].RootPart.ObjectSaleType;
                item.SalePrice = objlist[0].RootPart.SalePrice;
            }

            AssetBase asset = CreateAsset(
                objlist[0].GetPartName(objlist[0].RootPart.LocalId),
                objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
                (sbyte)AssetType.Object,
                Utils.StringToBytes(itemXml),
                objlist[0].OwnerID.ToString());

            m_Scene.AssetService.Store(asset);

            item.AssetID = asset.FullID;
            assetID      = asset.FullID;

            if (DeRezAction.SaveToExistingUserInventoryItem == action)
            {
                m_Scene.InventoryService.UpdateItem(item);
            }
            else
            {
                AddPermissions(item, objlist[0], objlist, remoteClient);

                item.CreationDate = Util.UnixTimeSinceEpoch();
                item.Description  = asset.Description;
                item.Name         = asset.Name;
                item.AssetType    = asset.Type;

                m_Scene.AddInventoryItem(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);
                    }
                }
            }

            // This is a hook to do some per-asset post-processing for subclasses that need that
            ExportAsset(remoteClient.AgentId, assetID);

            return(assetID);
        }
Пример #47
0
        public virtual void DeRezObjects(IClientAPI remoteClient, List<uint> localIDs,
                UUID groupID, DeRezAction action, UUID destinationID)
        {
            // First, see of we can perform the requested action and
            // build a list of eligible objects
            List<uint> deleteIDs = new List<uint>();
            List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();

            // Start with true for both, then remove the flags if objects
            // that we can't derez are part of the selection
            bool permissionToTake = true;
            bool permissionToTakeCopy = true;
            bool permissionToDelete = true;

            foreach (uint localID in localIDs)
            {
                // Invalid id
                SceneObjectPart part = GetSceneObjectPart(localID);
                if (part == null)
                    continue;

                // Already deleted by someone else
                if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
                    continue;

                // Can't delete child prims
                if (part != part.ParentGroup.RootPart)
                    continue;

                SceneObjectGroup grp = part.ParentGroup;

                deleteIDs.Add(localID);
                deleteGroups.Add(grp);

                ScenePresence SP = remoteClient == null ? null : GetScenePresence(remoteClient.AgentId);

                if (SP == null)
                {
                    // Autoreturn has a null client. Nothing else does. So
                    // allow only returns
                    if (action != DeRezAction.Return)
                        return;

                    permissionToTakeCopy = false;
                }
                else
                {
                    if (!Permissions.CanTakeCopyObject(grp.UUID, SP.UUID))
                        permissionToTakeCopy = false;
                    if (!Permissions.CanTakeObject(grp.UUID, SP.UUID))
                        permissionToTake = false;

                    if (!Permissions.CanDeleteObject(grp.UUID, SP.UUID))
                        permissionToDelete = false;
                }

            }

            // Handle god perms
            if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
            {
                permissionToTake = true;
                permissionToTakeCopy = true;
                permissionToDelete = true;
            }

            // If we're re-saving, we don't even want to delete
            if (action == DeRezAction.SaveToExistingUserInventoryItem)
                permissionToDelete = false;

            // if we want to take a copy, we also don't want to delete
            // Note: after this point, the permissionToTakeCopy flag
            // becomes irrelevant. It already includes the permissionToTake
            // permission and after excluding no copy items here, we can
            // just use that.
            if (action == DeRezAction.TakeCopy)
            {
                // If we don't have permission, stop right here
                if (!permissionToTakeCopy)
                    return;

                permissionToTake = true;
                // Don't delete
                permissionToDelete = false;
            }

            if (action == DeRezAction.Return)
            {
                if (remoteClient != null && Permissions.CanReturnObjects(
                                    null,
                                    remoteClient.AgentId,
                                    deleteGroups))
                {
                    permissionToTake = true;
                    permissionToDelete = true;

                    AddReturns(deleteGroups[0].OwnerID, deleteGroups[0].Name, deleteGroups.Count, deleteGroups[0].AbsolutePosition, "parcel owner return", deleteGroups);
                }
                else // Auto return passes through here with null agent
                {
                    permissionToTake = true;
                    permissionToDelete = true;
                }
            }

            //if (permissionToTake)
            //{
                m_asyncSceneObjectDeleter.DeleteToInventory(
                    action, destinationID, deleteGroups, remoteClient == null ? UUID.Zero : remoteClient.AgentId,
                        permissionToDelete, permissionToTake);
            //}
            //else if (permissionToDelete)
            //{
            //    foreach (SceneObjectGroup g in deleteGroups)
            //        DeleteSceneObject(g, false, true);
            //}
        }
Пример #48
0
        /// <summary>
        /// Create an item using details for the given scene object.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="remoteClient"></param>
        /// <param name="so"></param>
        /// <param name="folderID"></param>
        /// <returns></returns>
        protected InventoryItemBase CreateItemForObject(
            DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID)
        {
            // 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(null);
                }

                userID = remoteClient.AgentId;
            }
            else
            {
                // All returns / deletes go to the object owner
                //
                userID = so.RootPart.OwnerID;
            }

            if (userID == UUID.Zero) // Can't proceed
            {
                return(null);
            }

            // 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(so.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.",
                        so.Name, so.UUID);

                    return(null);
                }
            }
            else
            {
                // Folder magic
                //
                if (action == DeRezAction.Delete)
                {
                    // Deleting someone else's item
                    //
                    if (remoteClient == null ||
                        so.OwnerID != remoteClient.AgentId)
                    {
                        folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                    }
                    else
                    {
                        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
                    {
                        if (remoteClient == null || so.OwnerID != remoteClient.AgentId)
                        {
                            // Taking copy of another person's item. Take to
                            // Objects folder.
                            folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
                        }
                        else
                        {
                            // Catch all. Use lost & found
                            //

                            folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
                        }
                    }
                }

                // Override and put into where it came from, if it came
                // from anywhere in inventory
                //
                if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
                {
                    if (so.RootPart.FromFolderID != UUID.Zero)
                    {
                        InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
                        folder = m_Scene.InventoryService.GetFolder(f);
                    }
                }

                if (folder == null) // None of the above
                {
                    folder = new InventoryFolderBase(folderID);

                    if (folder == null) // Nowhere to put it
                    {
                        return(null);
                    }
                }

                item         = new InventoryItemBase();
                item.ID      = UUID.Random();
                item.InvType = (int)InventoryType.Object;
                item.Folder  = folder.ID;
                item.Owner   = userID;
            }

            return(item);
        }
Пример #49
0
        /// <summary>
        /// Delete the given objects from the Scene and move them into the client's inventory
        /// </summary>
        /// <param name="remoteClient">The client requesting the change (can be null if returning objects)</param>
        /// <param name="localIDs">A list of all the localIDs of the groups to delete</param>
        /// <param name="groupID">the GroupID of the objects</param>
        /// <param name="action">What type of action is causing this</param>
        /// <param name="destinationID">The folder ID to put the inventory items in</param>
        protected void DeRezObjects(IClientAPI remoteClient, List<uint> localIDs,
                UUID groupID, DeRezAction action, UUID destinationID)
        {
            // First, see of we can perform the requested action and
            // build a list of eligible objects
            List<uint> deleteIDs = new List<uint>();
            List<ISceneEntity> deleteGroups = new List<ISceneEntity> ();

            #region Permission Check

            // Start with true for both, then remove the flags if objects
            // that we can't derez are part of the selection
            bool permissionToTake = true;
            bool permissionToTakeCopy = true;
            bool permissionToDelete = true;

            foreach (uint localID in localIDs)
            {
                // Invalid id
                ISceneChildEntity part = m_scene.GetSceneObjectPart (localID);
                if (part == null)
                    continue;

                // Already deleted by someone else
                if (part.ParentEntity == null || part.ParentEntity.IsDeleted)
                    continue;

                // Can't delete child prims
                if (part != part.ParentEntity.RootChild)
                    continue;

                ISceneEntity grp = part.ParentEntity;

                deleteIDs.Add(localID);
                deleteGroups.Add(grp);

                IScenePresence SP = remoteClient == null ? null : m_scene.GetScenePresence (remoteClient.AgentId);

                if (SP == null)
                {
                    // Autoreturn has a null client. Nothing else does. So
                    // allow only returns
                    if (action != DeRezAction.Return)
                        return;

                    permissionToTakeCopy = false;
                }
                else
                {
                    if (!m_scene.Permissions.CanTakeCopyObject(grp.UUID, SP.UUID))
                        permissionToTakeCopy = false;
                    if (!m_scene.Permissions.CanTakeObject(grp.UUID, SP.UUID))
                        permissionToTake = false;

                    if (!m_scene.Permissions.CanDeleteObject(grp.UUID, SP.UUID))
                        permissionToDelete = false;
                }
            }

            #endregion

            // Handle god perms
            if ((remoteClient != null) && m_scene.Permissions.IsGod(remoteClient.AgentId))
            {
                permissionToTake = true;
                permissionToTakeCopy = true;
                permissionToDelete = true;
            }

            // If we're re-saving, we don't even want to delete
            if (action == DeRezAction.SaveToExistingUserInventoryItem)
                permissionToDelete = false;

            // if we want to take a copy, we also don't want to delete
            // Note: after this point, the permissionToTakeCopy flag
            // becomes irrelevant. It already includes the permissionToTake
            // permission and after excluding no copy items here, we can
            // just use that.
            if (action == DeRezAction.AcquireToUserInventory)
            {
                // If we don't have permission, stop right here
                if (!permissionToTakeCopy)
                    return;

                permissionToTake = true;
                // Don't delete
                permissionToDelete = false;
            }

            if (action == DeRezAction.Return)
            {
                if (remoteClient != null && m_scene.Permissions.CanReturnObjects(
                                    null,
                                    remoteClient.AgentId,
                                    deleteGroups))
                {
                    permissionToTake = true;
                    permissionToDelete = true;

                    IParcelManagementModule parcelManagement = m_scene.RequestModuleInterface<IParcelManagementModule>();
                    if (parcelManagement != null)
                    {
                        parcelManagement.AddReturns(deleteGroups[0].OwnerID, deleteGroups[0].Name, deleteGroups[0].AbsolutePosition, "Parcel Owner Return", deleteGroups);
                    }
                }
                else // Auto return passes through here with null agent
                {
                    permissionToTake = true;
                    permissionToDelete = true;
                }
            }

            IAsyncSceneObjectGroupDeleter asyncDelete = m_scene.RequestModuleInterface<IAsyncSceneObjectGroupDeleter>();
            if (asyncDelete != null)
            {
                asyncDelete.DeleteToInventory(
                       action, destinationID, deleteGroups, remoteClient == null ? UUID.Zero : remoteClient.AgentId,
                           permissionToDelete, permissionToTake);
            }
        }
        public virtual UUID CopyToInventory(DeRezAction action, UUID folderID,
                List<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
        {
            Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>();
            
            if (CoalesceMultipleObjectsToInventory)
            {
                // The following code groups the SOG's by owner. No objects
                // belonging to different people can be coalesced, for obvious
                // reasons.
                foreach (SceneObjectGroup g in objectGroups)
                {
                    if (!bundlesToCopy.ContainsKey(g.OwnerID))
                        bundlesToCopy[g.OwnerID] = new List<SceneObjectGroup>();
    
                    bundlesToCopy[g.OwnerID].Add(g);
                }
            }
            else
            {
                // If we don't want to coalesce then put every object in its own bundle.
                foreach (SceneObjectGroup g in objectGroups)
                {
                    List<SceneObjectGroup> bundle = new List<SceneObjectGroup>();
                    bundle.Add(g);
                    bundlesToCopy[g.UUID] = bundle;                    
                }
            }

            // This is method scoped and will be returned. It will be the
            // last created asset id
            UUID assetID = UUID.Zero;

            // Each iteration is really a separate asset being created,
            // with distinct destinations as well.
            foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values)
                assetID = CopyBundleToInventory(action, folderID, bundle, remoteClient);
            
            return assetID;
        }