Exemplo n.º 1
0
        // unpackedGroup is null for an actual user Inventory item. non-null for group from a coalesced inventory item.
        public virtual bool RestoreObject(IClientAPI remoteClient, CachedUserInfo userInfo, UUID itemID, InventoryItemBase item, SceneObjectGroup unpackedGroup, UUID groupID)
        {
            Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);

            AssetBase rezAsset = CommsManager.AssetCache.GetAsset(item.AssetID, AssetRequestInfo.InternalRequest());
            if (rezAsset == null)
                return false;

            UUID itemId = UUID.Zero;
            bool success = false;

            // If we have permission to copy then link the rezzed object back to the user inventory
            // item that it came from.  This allows us to enable 'save object to inventory'
            if (!Permissions.BypassPermissions())
            {
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
                {
                    itemId = item.ID;
                }
            }
            else
            {
                // Brave new fullperm world
                //
                itemId = item.ID;
            }

            if ((unpackedGroup==null) && item.ContainsMultipleItems)
            {
                CoalescedObject obj = this.DoDeserializeCoalesced(itemId, rezAsset.Data);
                //restore (rez) coalesced object
                success = this.RestoreCoalescedObject(remoteClient, userInfo, obj, itemID, item, groupID);
            }
            else
            {
                //rez single group
                SceneObjectGroup group = (unpackedGroup == null) ? this.DoDeserializeGroup(itemId, rezAsset.Data) : unpackedGroup;
                Vector3 pos = group.RootPart.GroupPositionNoUpdate;
                bool attachment = group.IsAttachment;
                uint attachPoint = group.AttachmentPoint;
                group.DisableUpdates = false;

                bool shouldTaint = false;

                if (attachment)
                {
                    remoteClient.SendAlertMessage("Inventory item is an attachment, use Wear or Add instead.");
                    return false;
                }

                // Save the previous attachment params if they've never been saved or default.
                if (group.RootPart.SavedAttachmentPos == Vector3.Zero)
                    group.RootPart.SavedAttachmentPos = group.RootPart.RawGroupPosition;
                if (group.RootPart.SavedAttachmentRot == Quaternion.Identity)
                    group.RootPart.SavedAttachmentRot = group.RootPart.RotationOffset;

                //after this, the group is no longer an attachment as it is being rezzed as a normal group.
                //this prevents an issue where the BB calculation tries to get the worldpos for the
                //attachment that is not yet attached and creates a null reference exception
                //when trying to access the scene to look up the wearer
                group.SetAttachmentPoint(0);

                Box bbox = group.BoundingBox();
                scale = bbox.Size; ; // update the 0.5 cube with the actual size
                pos = group.AbsolutePosition;
                float zCorrection = group.RootPart.GroupPosition.Z - bbox.Center.Z;
                pos.Z += zCorrection;

                SceneObjectGroup rezGroup =
                    this.RezSingleObjectToWorld(remoteClient, itemID,
                            group, pos, Vector3.Zero, UUID.Zero, 1, 1, false,
                            attachment, pos, group.Name, group.RootPart.Description,
                            item, ItemPermissionBlock.FromOther(item), 0, groupID, null);

                if (rezGroup != null)
                {
                    success = true;

                    if (shouldTaint)
                    {
                        rezGroup.HasGroupChanged = true;
                        rezGroup.TaintedAttachment = true;
                    }
                }
            }

            if (success && !Permissions.BypassPermissions())
            {
                //we check the inventory item permissions here instead of the prim permissions
                //if the group or item is no copy, it should be removed
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                {
                    // Not an attachment, so remove inventory copy, if no-copy.
                    if (userInfo != null)
                        userInfo.DeleteItem(item);
                }
            }

            return success;
        }
Exemplo n.º 2
0
        // Used to deliver group notice attachments.  Perms checks already done at send time.  May need to apply next owner perms.
        // Also called by GiveInventoryItem since it factors most of the guts of that operation.
        // Note: when sender is a group, senderID is groupID and senderUserInfo is null, otherwise senderUserInfo must be non-null.
        public virtual InventoryItemBase DeliverItem(InventoryItemBase item, UUID recipientId, UUID recipientFolderId, UUID senderId, CachedUserInfo senderUserInfo)
        {
            CachedUserInfo recipientUserInfo
                = CommsManager.UserService.GetUserDetails(recipientId);

            if (recipientUserInfo != null)
            {
                if (!recipientUserInfo.HasReceivedInventory)
                    recipientUserInfo.FetchInventory();

                // Insert a copy of the item into the recipient
                InventoryItemBase itemCopy = new InventoryItemBase();
                itemCopy.Owner = recipientId;
                itemCopy.CreatorId = item.CreatorId;
                itemCopy.ID = UUID.Random();
                itemCopy.AssetID = item.AssetID;
                itemCopy.Description = item.Description;
                itemCopy.Name = item.Name;
                itemCopy.AssetType = item.AssetType;
                itemCopy.InvType = item.InvType;
                itemCopy.Folder = recipientFolderId;

                CalcItemPermsFromInvItem(itemCopy, item, (recipientId != senderId));
                        
                // copy is never group owned
                itemCopy.GroupOwned = false;

                itemCopy.Flags = item.Flags;
                itemCopy.SalePrice = item.SalePrice;
                itemCopy.SaleType = item.SaleType;

                recipientUserInfo.AddItem(itemCopy);

                if (!Permissions.BypassPermissions())
                {
                    if (senderUserInfo != null) //  if not a group item (notice attachment)
                    {
                        if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                        {
                            senderUserInfo.DeleteItem(item);
                        }
                    }
                }

                return itemCopy;
            }
            else
            {
                m_log.ErrorFormat(
                    "[AGENT INVENTORY]: Could not find userinfo for recipient user {0} of item {1}, {2} from {3}",
                    recipientId, item.Name,
                    item.ID, senderId);
            }
            return null;
        }
Exemplo n.º 3
0
        public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID groupID, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                    UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                    bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment, uint attachPoint,
                                    int? startParam, CachedUserInfo userInfo, InventoryItemBase item, bool allowUpdates)
        {
            // Work out position details
            byte bRayEndIsIntersection = (byte)0;

            if (RayEndIsIntersection)
            {
                bRayEndIsIntersection = (byte)1;
            }
            else
            {
                bRayEndIsIntersection = (byte)0;
            }

            Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);


            Vector3 pos = GetNewRezLocation(
                      RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                      BypassRayCast, bRayEndIsIntersection, true, scale, false, remoteClient.AgentId);

            AssetBase rezAsset = CommsManager.AssetCache.GetAsset(item.AssetID, AssetRequestInfo.InternalRequest());

            if (rezAsset != null)
            {
                UUID itemId = UUID.Zero;

                // If we have permission to copy then link the rezzed object back to the user inventory
                // item that it came from.  This allows us to enable 'save object to inventory'
                if (!Permissions.BypassPermissions())
                {
                    if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
                    {
                        itemId = item.ID;
                    }
                }
                else
                {
                    // Brave new fullperm world
                    //
                    itemId = item.ID;
                }

                string xmlData = Utils.BytesToString(rezAsset.Data);
                bool success = false;
                SceneObjectGroup retGroup = null;

                if (item.ContainsMultipleItems)
                {
                    if (!attachment)
                    {
                        CoalescedObject obj = this.DoDeserializeCoalesced(itemId, rezAsset.Data);

                        //rez coalesced object
                        success = this.RezCoalescedObject(remoteClient, itemID, obj, RayEnd,
                                    RayStart, RayTargetID, BypassRayCast, bRayEndIsIntersection,
                                    RezSelected, false, pos, item, startParam, groupID,
                                    null);
                    }
                    else
                    {
                        return null; //rezzing a coalesced as an attachment doesnt make sense
                    }
                }
                else
                {
                    //rez single group
                    SceneObjectGroup group = this.DoDeserializeGroup(itemId, rezAsset.Data);

                    group.DisableUpdates = !allowUpdates;

                    bool shouldTaint = false;

                    // if attachment we set it's asset id so object updates can reflect that
                    // if not, we set it's position in world.
                    if (!attachment)
                    {
                        // Save the previous attachment params if they've never been saved or default.
                        if (group.RootPart.SavedAttachmentPos == Vector3.Zero)
                            group.RootPart.SavedAttachmentPos = group.RootPart.RawGroupPosition;
                        if (group.RootPart.SavedAttachmentRot == Quaternion.Identity)
                            group.RootPart.SavedAttachmentRot = group.RootPart.RotationOffset;

                        //after this, the group is no longer an attachment as it is being rezzed as a normal group.
                        //this prevents an issue where the BB calculation tries to get the worldpos for the
                        //attachment that is not yet attached and creates a null reference exception
                        //when trying to access the scene to look up the wearer
                        group.SetAttachmentPoint(0);

                        Box bbox = group.BoundingBox();
                        scale = bbox.Size; ; // update the 0.5 cube with the actual size
                        pos = GetNewRezLocation(
                            RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                            BypassRayCast, bRayEndIsIntersection, true, scale, false, remoteClient.AgentId);
                        float zCorrection = group.RootPart.GroupPosition.Z - bbox.Center.Z;
                        pos.Z += zCorrection;
                    }
                    else
                    {
                        //this is an attachment, prep the object for rez. particularly important so that it is not 
                        //first rezzed in world with physics in tact
                        if (!group.PrepareForRezAsAttachment(attachPoint, out shouldTaint, false))
                        {
                            return null;
                        }

                        //extract the saved position for sending to the rez method
                        pos = group.RawGroupPosition;
                    }

                    retGroup =
                        this.RezSingleObjectToWorld(remoteClient, itemID,
                                group, RayEnd, RayStart,
                                RayTargetID, BypassRayCast, bRayEndIsIntersection,
                                RezSelected, attachment, pos, item.Name,
                                item.Description, item, ItemPermissionBlock.FromOther(item),
                                startParam, groupID, null);

                    if (retGroup != null)
                    {
                        success = true;

                        if (shouldTaint)
                        {
                            retGroup.HasGroupChanged = true;
                            retGroup.TaintedAttachment = true;
                        }
                    }
                }

                if (success && !Permissions.BypassPermissions())
                {
                    //we check the inventory item permissions here instead of the prim permissions
                    //if the group or item is no copy, it should be removed
                    if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                    {
                        // If this is done on attachments, no
                        // copy ones will be lost, so avoid it
                        //
                        if (!attachment)
                        {
                            if (userInfo != null)
                                userInfo.DeleteItem(item);
                        }
                    }
                }

                return retGroup;
            }
            return null;
        }