コード例 #1
0
        /// <summary>
        /// Store the asset for the given item when it has been uploaded.
        /// </summary>
        /// <param name="item"></param>
        private bool CompleteItemUpdate(InventoryItemBase item)
        {
            //            m_log.DebugFormat(
            //                "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
            //                m_asset.FullID, item.Name, ourClient.Name);

            uint perms = ValidateAssets();

            if (perms == 0)
            {
                string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', update failed", item.Name);
                ourClient.SendAlertMessage(error);
                m_transactions.RemoveXferUploader(m_transactionID);
                ourClient.SendBulkUpdateInventory(item); // invalid the change item on viewer cache
            }
            else
            {
                m_Scene.AssetService.Store(m_asset);
                if (m_asset.FullID != UUID.Zero)
                {
                    item.AssetID = m_asset.FullID;
                    m_Scene.InventoryService.UpdateItem(item);
                }
                ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0);
                m_transactions.RemoveXferUploader(m_transactionID);
                m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0);
            }

            return(perms != 0);
        }
コード例 #2
0
        private void TaskInventoryOfferDecline(IClientAPI client, Scene scene, GridInstantMessage im)
        {
            // The inventory item/folder, back from it's trip
            UUID inventoryEntityID = new UUID(im.imSessionID);

            // Here, the recipient is local and we can assume that the inventory is loaded.
            // Courtesy of the above bulk update, it will have been pushed to the client, too.
            CachedUserInfo userInfo = scene.CommsManager.UserService.GetUserDetails(client.AgentId);

            if (userInfo != null)
            {
                InventoryFolderBase trashFolder = userInfo.FindFolderForType((int)AssetType.TrashFolder);
                if (null == trashFolder)
                {
                    client.SendAgentAlertMessage("Unable to decline received inventory: Trash folder not found.", false);
                    return;
                }

                // Is it a folder or an item?
                if (userInfo.QueryItem(inventoryEntityID))
                {   // It's an item.
                    InventoryItemBase item = userInfo.FindItem(inventoryEntityID);
                    if (item == null)
                    {
                        client.SendAgentAlertMessage("Unable to decline received inventory: item/folder not found.", false);
                        return;
                    }
                    userInfo.MoveItemToTrash(item, trashFolder);
                    scene.AddInventoryItem(client, item);
                    client.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {   // It's a folder.
                    InventoryFolderBase folder = userInfo.GetFolderAttributes(inventoryEntityID);
                    userInfo.MoveFolder(inventoryEntityID, trashFolder.ID);
                    folder = userInfo.GetFolder(inventoryEntityID);
                    if (folder != null)
                    {
                        client.SendBulkUpdateInventory(folder);
                        // If we don't send the descendents, viewer shows "Loading..." on the trash item.
                        userInfo.SendInventoryDecendents(client, folder.ID, false, true);
                    }
                }
            }
        }
コード例 #3
0
        //
        // These 2 are for local and foreign users coming back, respectively
        //

        private void ProcessInventoryForComingHome(IClientAPI client)
        {
            if (!client.IsActive)
            {
                return;
            }
            m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Restoring root folder for local user {0}", client.Name);
            InventoryFolderBase root    = m_Scene.InventoryService.GetRootFolder(client.AgentId);
            InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);

            List <InventoryFolderBase> keep = new List <InventoryFolderBase>();

            foreach (InventoryFolderBase f in content.Folders)
            {
                if (f.Name != "My Suitcase" && f.Name != "Current Outfit")
                {
                    keep.Add(f);
                }
            }
            client.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
        }
コード例 #4
0
        private void TaskInventoryOfferAccept(IClientAPI client, Scene scene, GridInstantMessage im)
        {
            InventoryFolderBase folder = null;
            InventoryItemBase   item   = null;

            // The inventory item/folder, back from it's trip
            UUID inventoryEntityID = new UUID(im.imSessionID);

            // Here, the recipient is local and we can assume that the inventory is loaded.
            // Courtesy of the above bulk update, it will have been pushed to the client, too.
            CachedUserInfo userInfo = scene.CommsManager.UserService.GetUserDetails(client.AgentId);

            if (userInfo != null)
            {
                // Is it a folder or an item?
                if (userInfo.QueryItem(inventoryEntityID))
                {   // It's an item.
                    item = userInfo.FindItem(inventoryEntityID);
                    if (item == null)
                    {
                        client.SendAgentAlertMessage("Unable to accept received inventory: item/folder not found.", false);
                        return;
                    }
                    client.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {   // It's a folder.
                    folder = userInfo.GetFolder(inventoryEntityID);
                    if (folder != null)
                    {
                        client.SendBulkUpdateInventory(folder);
                        // If we don't send the descendents, viewer shows "Loading..." on the trash item.
                        userInfo.SendInventoryDecendents(client, folder.ID, false, true);
                    }
                }
            }

            //            RelayInventoryOfferIM(scene, im); // we don't need to notify a box that the user accepted this
        }
コード例 #5
0
        //
        // These 2 are for local and foreign users going away respectively
        //

        private void ProcessInventoryForHypergriding(IClientAPI client)
        {
            if (!client.IsActive)
            {
                return;
            }

            InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);

            if (root != null)
            {
                m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name);
                InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);

                List <InventoryFolderBase> keep = new List <InventoryFolderBase>();

                foreach (InventoryFolderBase f in content.Folders)
                {
                    if (f.Name != "My Suitcase" && f.Name != "Current Outfit")
                    {
                        f.Name = f.Name + " (Unavailable)";
                        keep.Add(f);
                    }
                }

                // items directly under the root folder
                foreach (InventoryItemBase it in content.Items)
                {
                    it.Name = it.Name + " (Unavailable)";
                }
                ;

                // Send the new names
                client.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
            }
        }
コード例 #6
0
        private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
        {
            //            m_log.DebugFormat(
            //                "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}",
            //                (InstantMessageDialog)im.dialog, client.Name,
            //                im.fromAgentID, im.fromAgentName, im.toAgentID);

            Scene scene = FindClientScene(client.AgentId);

            if (scene == null) // Something seriously wrong here.
            {
                return;
            }

            UUID agentID = client.AgentId;

            switch ((InstantMessageDialog)im.dialog)
            {
            case InstantMessageDialog.InventoryOffered:
            {
                if (im.binaryBucket.Length < 17)     // Invalid
                {
                    return;
                }

                UUID          recipientID    = new UUID(im.toAgentID);
                ScenePresence recipientAgent = scene.GetScenePresence(recipientID);
                UUID          copyID;

                // First byte is the asset type
                AssetType assetType = (AssetType)im.binaryBucket[0];
                if (assetType == AssetType.LinkFolder || assetType == AssetType.Link)
                {
                    client.SendAgentAlertMessage("Can't give a link. Nothing given.", false);
                    return;
                }

                if (assetType == AssetType.Folder)
                {
                    UUID folderID = new UUID(im.binaryBucket, 1);
                    if (folderID == UUID.Zero)
                    {
                        client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false);
                        return;
                    }

                    Dictionary <UUID, AssetType> ids = new Dictionary <UUID, AssetType>();
                    ids[folderID] = assetType;

                    if (im.binaryBucket.Length >= 34 && im.binaryBucket.Length % 17 == 0)
                    {
                        byte[] iddata = im.binaryBucket;
                        for (int i = 17; i < im.binaryBucket.Length - 17; i += 17)
                        {
                            ids[new UUID(iddata, i + 1)] = (AssetType)im.binaryBucket[i];
                        }
                    }

                    m_log.DebugFormat("[INVENTORY TRANSFER]: offering folder {0} to agent {1}'s inventory",
                                      folderID, recipientID);

                    InventoryFolderBase folderCopy = scene.GiveInventoryFolder(client, recipientID, agentID, folderID, UUID.Zero, ids);

                    if (folderCopy == null)
                    {
                        client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false);
                        return;
                    }

                    copyID         = folderCopy.ID;
                    im.imSessionID = copyID.Guid;

                    if (recipientAgent != null)
                    {
                        recipientAgent.ControllingClient.SendBulkUpdateInventory(folderCopy);
                    }
                }
                else
                {
                    UUID itemID = new UUID(im.binaryBucket, 1);
                    if (itemID == UUID.Zero)
                    {
                        client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
                        return;
                    }

                    m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} " +
                                      "into agent {1}'s inventory",
                                      itemID, recipientID);

                    string            message;
                    InventoryItemBase itemCopy = scene.GiveInventoryItem(recipientID, agentID, itemID, out message);

                    if (itemCopy == null)
                    {
                        client.SendAgentAlertMessage(message, false);
                        return;
                    }

                    copyID = itemCopy.ID;

                    if (recipientAgent != null)
                    {
                        recipientAgent.ControllingClient.SendBulkUpdateInventory(itemCopy);
                    }

                    im.imSessionID = copyID.Guid;
                }

                // Send the IM to the recipient. The item is already
                // in their inventory, so it will not be lost if
                // they are offline.

                im.binaryBucket    = new byte[17];
                im.binaryBucket[0] = (byte)assetType;
                copyID.ToBytes(im.binaryBucket, 1);

                if (recipientAgent != null)
                {
                    im.offline = 0;
                    recipientAgent.ControllingClient.SendInstantMessage(im);
                    return;
                }
                else
                {
                    im.offline = 0;
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im, delegate(bool success)
                            {
                                if (!success)
                                {
                                    client.SendAlertMessage("User not online. Inventory has been saved");
                                }
                            });
                    }
                }
                break;
            }

            case InstantMessageDialog.InventoryAccepted:
            {
                UUID inventoryID = new UUID(im.imSessionID);     // The inventory item/folder, back from it's trip
                if (inventoryID == UUID.Zero)
                {
                    return;
                }

                IInventoryService invService = scene.InventoryService;

                ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
                if (user != null)     // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
                    }
                }
                break;
            }

            case InstantMessageDialog.TaskInventoryAccepted:
            {
                if (im.binaryBucket == null || im.binaryBucket.Length < 16)
                {
                    return;
                }

                UUID destinationFolderID = new UUID(im.binaryBucket, 0);
                if (destinationFolderID == UUID.Zero)    // uuid-zero is a valid folder ID(?) keeping old code assuming not
                {
                    return;
                }

                IInventoryService   invService        = scene.InventoryService;
                InventoryFolderBase destinationFolder = null;
                destinationFolder = invService.GetFolder(agentID, destinationFolderID);

                if (destinationFolder == null)
                {
                    return;                                  // no where to put it
                }
                UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
                if (inventoryID == UUID.Zero)
                {
                    return;
                }

                InventoryItemBase   item   = invService.GetItem(agentID, inventoryID);
                InventoryFolderBase folder = null;
                //UUID? previousParentFolderID = null;

                if (item != null)     // It's an item
                {
                    if (item.Folder != destinationFolderID)
                    {
                        //previousParentFolderID = item.Folder;
                        item.Folder = destinationFolderID;
                        invService.MoveItems(item.Owner, new List <InventoryItemBase>()
                            {
                                item
                            });
                        client.SendInventoryItemCreateUpdate(item, 0);
                    }
                }
                else
                {
                    folder = invService.GetFolder(agentID, inventoryID);

                    if (folder != null)     // It's a folder
                    {
                        if (folder.ParentID != destinationFolderID)
                        {
                            folder.ParentID = destinationFolderID;
                            invService.MoveFolder(folder);
                        }
                        client.SendBulkUpdateInventory(folder, folder.ID);
                    }
                }
                break;
            }

            case InstantMessageDialog.InventoryDeclined:
            case InstantMessageDialog.TaskInventoryDeclined:
            {
                IInventoryService   invService  = scene.InventoryService;
                InventoryFolderBase trashFolder = invService.GetFolderForType(agentID, FolderType.Trash);
                if (trashFolder == null)    //??
                {
                    client.SendAgentAlertMessage("Trash folder not found", false);
                    return;
                }

                UUID inventoryID = new UUID(im.imSessionID);     // The inventory item/folder, back from it's trip
                if (inventoryID == UUID.Zero)
                {
                    client.SendAgentAlertMessage("Item or folder not found", false);
                    return;
                }

                InventoryItemBase   item   = invService.GetItem(agentID, inventoryID);
                InventoryFolderBase folder = null;

                if (item != null)
                {
                    if (trashFolder.ID != item.Folder)
                    {
                        item.Folder = trashFolder.ID;
                        invService.MoveItems(item.Owner, new List <InventoryItemBase>()
                            {
                                item
                            });
                        client.SendInventoryItemCreateUpdate(item, 0);
                    }
                }
                else
                {
                    folder = invService.GetFolder(agentID, inventoryID);
                    if (folder != null)
                    {
                        if (trashFolder.ID != folder.ParentID)
                        {
                            folder.ParentID = trashFolder.ID;
                            invService.MoveFolder(folder);
                        }
                        client.SendBulkUpdateInventory(folder, folder.ID);
                    }
                }

                if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined)
                {
                    ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));

                    if (user != null)     // Local
                    {
                        user.ControllingClient.SendInstantMessage(im);
                    }
                    else
                    {
                        if (m_TransferModule != null)
                        {
                            m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
                        }
                    }
                }
                break;
            }

            default:
                break;
            }
        }
コード例 #7
0
        /// <summary>
        /// Rez an object into the scene from the user's inventory
        /// </summary>
        /// <remarks>
        /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
        /// things to the scene.  The caller should be doing that, I think.
        /// </remarks>
        /// <param name="remoteClient"></param>
        /// <param name="itemID"></param>
        /// <param name="RayEnd"></param>
        /// <param name="RayStart"></param>
        /// <param name="RayTargetID"></param>
        /// <param name="BypassRayCast"></param>
        /// <param name="RayEndIsIntersection"></param>
        /// <param name="RezSelected"></param>
        /// <param name="RemoveItem"></param>
        /// <param name="fromTaskID"></param>
        /// <param name="attachment"></param>
        /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
        public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                                  UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                                  bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
        {
//            m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);

            byte    bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
            Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
            Vector3 pos   = m_Scene.GetNewRezLocation(
                RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                BypassRayCast, bRayEndIsIntersection, true, scale, false);

            // Rez object
            InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);

            item = m_Scene.InventoryService.GetItem(item);

            if (item != null)
            {
                item.Owner = remoteClient.AgentId;

                AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());

                SceneObjectGroup group = null;

                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 (!m_Scene.Permissions.BypassPermissions())
                    {
                        if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                        {
                            itemId = item.ID;
                        }
                    }
                    else
                    {
                        if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                        {
                            // Brave new fullperm world
                            itemId = item.ID;
                        }
                    }

                    string xmlData = Utils.BytesToString(rezAsset.Data);
                    List <SceneObjectGroup> objlist =
                        new List <SceneObjectGroup>();
                    List <Vector3> veclist = new List <Vector3>();

                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(xmlData);
                    XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
                    if (e == null || attachment) // Single
                    {
                        SceneObjectGroup g =
                            SceneObjectSerializer.FromOriginalXmlFormat(
                                itemId, xmlData);
                        objlist.Add(g);
                        veclist.Add(new Vector3(0, 0, 0));

                        float offsetHeight = 0;
                        pos = m_Scene.GetNewRezLocation(
                            RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                            BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
                        pos.Z += offsetHeight;
                    }
                    else
                    {
                        XmlElement coll = (XmlElement)e;
                        float      bx   = Convert.ToSingle(coll.GetAttribute("x"));
                        float      by   = Convert.ToSingle(coll.GetAttribute("y"));
                        float      bz   = Convert.ToSingle(coll.GetAttribute("z"));
                        Vector3    bbox = new Vector3(bx, by, bz);

                        pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
                                                        RayTargetID, Quaternion.Identity,
                                                        BypassRayCast, bRayEndIsIntersection, true,
                                                        bbox, false);

                        pos -= bbox / 2;

                        XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
                        foreach (XmlNode n in groups)
                        {
                            SceneObjectGroup g =
                                SceneObjectSerializer.FromOriginalXmlFormat(
                                    itemId, n.OuterXml);
                            objlist.Add(g);
                            XmlElement el = (XmlElement)n;

                            string rawX = el.GetAttribute("offsetx");
                            string rawY = el.GetAttribute("offsety");
                            string rawZ = el.GetAttribute("offsetz");
//
//                            m_log.DebugFormat(
//                                "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>",
//                                g.Name, rawX, rawY, rawZ);

                            float x = Convert.ToSingle(rawX);
                            float y = Convert.ToSingle(rawY);
                            float z = Convert.ToSingle(rawZ);
                            veclist.Add(new Vector3(x, y, z));
                        }
                    }

                    int primcount = 0;
                    foreach (SceneObjectGroup g in objlist)
                    {
                        primcount += g.PrimCount;
                    }

                    if (!m_Scene.Permissions.CanRezObject(
                            primcount, remoteClient.AgentId, pos) &&
                        !attachment)
                    {
                        // The client operates in no fail mode. It will
                        // have already removed the item from the folder
                        // if it's no copy.
                        // Put it back if it's not an attachment
                        //
                        if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
                        {
                            remoteClient.SendBulkUpdateInventory(item);
                        }
                        return(null);
                    }

                    for (int i = 0; i < objlist.Count; i++)
                    {
                        group = objlist[i];

                        Vector3 storedPosition = group.AbsolutePosition;
                        if (group.UUID == UUID.Zero)
                        {
                            m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3");
                        }
                        group.RootPart.FromFolderID = item.Folder;

                        // If it's rezzed in world, select it. Much easier to
                        // find small items.
                        //
                        if (!attachment)
                        {
                            group.RootPart.CreateSelected = true;
                            foreach (SceneObjectPart child in group.Parts)
                            {
                                child.CreateSelected = true;
                            }
                        }
                        group.ResetIDs();

                        if (attachment)
                        {
                            group.RootPart.Flags       |= PrimFlags.Phantom;
                            group.RootPart.IsAttachment = true;
                        }

                        // If we're rezzing an attachment then don't ask
                        // AddNewSceneObject() to update the client since
                        // we'll be doing that later on.  Scheduling more than
                        // one full update during the attachment
                        // process causes some clients to fail to display the
                        // attachment properly.
                        m_Scene.AddNewSceneObject(group, true, 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)
                        {
                            group.ScheduleGroupForFullUpdate();

                            group.AbsolutePosition = pos + veclist[i];
                        }
                        else
                        {
                            group.SetFromItemID(itemID);
                        }

                        SceneObjectPart rootPart = null;

                        try
                        {
                            rootPart = group.GetChildPart(group.UUID);
                        }
                        catch (NullReferenceException)
                        {
                            string isAttachment = "";

                            if (attachment)
                            {
                                isAttachment = " Object was an attachment";
                            }

                            m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
                        }

                        // Since renaming the item in the inventory does not
                        // affect the name stored in the serialization, transfer
                        // the correct name from the inventory to the
                        // object itself before we rez.
                        //
                        // Only do these for the first object if we are rezzing a coalescence.
                        if (i == 0)
                        {
                            rootPart.Name           = item.Name;
                            rootPart.Description    = item.Description;
                            rootPart.ObjectSaleType = item.SaleType;
                            rootPart.SalePrice      = item.SalePrice;
                        }

                        group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
                        if ((rootPart.OwnerID != item.Owner) ||
                            (item.CurrentPermissions & 16) != 0)
                        {
                            //Need to kill the for sale here
                            rootPart.ObjectSaleType = 0;
                            rootPart.SalePrice      = 10;

                            if (m_Scene.Permissions.PropagatePermissions())
                            {
                                foreach (SceneObjectPart part in group.Parts)
                                {
                                    if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                                    {
                                        part.EveryoneMask  = item.EveryOnePermissions;
                                        part.NextOwnerMask = item.NextPermissions;
                                    }
                                    part.GroupMask = 0; // DO NOT propagate here
                                }

                                group.ApplyNextOwnerPermissions();
                            }
                        }

                        foreach (SceneObjectPart part in group.Parts)
                        {
                            if ((part.OwnerID != item.Owner) ||
                                (item.CurrentPermissions & 16) != 0)
                            {
                                part.LastOwnerID = part.OwnerID;
                                part.OwnerID     = item.Owner;
                                part.Inventory.ChangeInventoryOwner(item.Owner);
                                part.GroupMask = 0; // DO NOT propagate here
                            }
                            part.EveryoneMask  = item.EveryOnePermissions;
                            part.NextOwnerMask = item.NextPermissions;
                        }

                        rootPart.TrimPermissions();

                        if (!attachment)
                        {
                            if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
                            {
                                group.ClearPartAttachmentData();
                            }

                            // Fire on_rez
                            group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
                            rootPart.ParentGroup.ResumeScripts();

                            rootPart.ScheduleFullUpdate();
                        }
                    }

                    if (!m_Scene.Permissions.BypassPermissions())
                    {
                        if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                        {
                            // If this is done on attachments, no
                            // copy ones will be lost, so avoid it
                            //
                            if (!attachment)
                            {
                                List <UUID> uuids = new List <UUID>();
                                uuids.Add(item.ID);
                                m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
                            }
                        }
                    }
                }
                return(group);
            }

            return(null);
        }
コード例 #8
0
        /// <summary>
        /// Rez an object into the scene from the user's inventory
        /// </summary>
        /// <remarks>
        /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
        /// things to the scene.  The caller should be doing that, I think.
        /// </remarks>
        /// <param name="remoteClient"></param>
        /// <param name="itemID"></param>
        /// <param name="RayEnd"></param>
        /// <param name="RayStart"></param>
        /// <param name="RayTargetID"></param>
        /// <param name="BypassRayCast"></param>
        /// <param name="RayEndIsIntersection"></param>
        /// <param name="RezSelected"></param>
        /// <param name="RemoveItem"></param>
        /// <param name="fromTaskID"></param>
        /// <param name="attachment"></param>
        /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
        public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                    UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                    bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
        {
//            m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
            
            byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
            Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
            Vector3 pos = m_Scene.GetNewRezLocation(
                      RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                      BypassRayCast, bRayEndIsIntersection, true, scale, false);

            // Rez object
            InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
            item = m_Scene.InventoryService.GetItem(item);

            if (item != null)
            {
                item.Owner = remoteClient.AgentId;

                AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());

                SceneObjectGroup group = null;

                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 (!m_Scene.Permissions.BypassPermissions())
                    {
                        if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                        {
                            itemId = item.ID;
                        }
                    }
                    else
                    {
                        if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                        {
                            // Brave new fullperm world
                            itemId = item.ID;
                        }
                    }

                    string xmlData = Utils.BytesToString(rezAsset.Data);
                    List<SceneObjectGroup> objlist =
                            new List<SceneObjectGroup>();
                    List<Vector3> veclist = new List<Vector3>();

                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(xmlData);
                    XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
                    if (e == null || attachment) // Single
                    {
                        SceneObjectGroup g =
                                SceneObjectSerializer.FromOriginalXmlFormat(
                                itemId, xmlData);
                        objlist.Add(g);
                        veclist.Add(new Vector3(0, 0, 0));

                        float offsetHeight = 0;
                        pos = m_Scene.GetNewRezLocation(
                            RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                            BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
                        pos.Z += offsetHeight;
                    }
                    else
                    {
                        XmlElement coll = (XmlElement)e;
                        float bx = Convert.ToSingle(coll.GetAttribute("x"));
                        float by = Convert.ToSingle(coll.GetAttribute("y"));
                        float bz = Convert.ToSingle(coll.GetAttribute("z"));
                        Vector3 bbox = new Vector3(bx, by, bz);

                        pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
                                RayTargetID, Quaternion.Identity,
                                BypassRayCast, bRayEndIsIntersection, true,
                                bbox, false);

                        pos -= bbox / 2;

                        XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
                        foreach (XmlNode n in groups)
                        {
                            SceneObjectGroup g =
                                    SceneObjectSerializer.FromOriginalXmlFormat(
                                    itemId, n.OuterXml);
                            objlist.Add(g);
                            XmlElement el = (XmlElement)n;
                            
                            string rawX = el.GetAttribute("offsetx");
                            string rawY = el.GetAttribute("offsety");
                            string rawZ = el.GetAttribute("offsetz");
//                        
//                            m_log.DebugFormat(
//                                "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", 
//                                g.Name, rawX, rawY, rawZ);
                            
                            float x = Convert.ToSingle(rawX);
                            float y = Convert.ToSingle(rawY);
                            float z = Convert.ToSingle(rawZ);
                            veclist.Add(new Vector3(x, y, z));
                        }
                    }

                    int primcount = 0;
                    foreach (SceneObjectGroup g in objlist)
                        primcount += g.PrimCount;

                    if (!m_Scene.Permissions.CanRezObject(
                        primcount, remoteClient.AgentId, pos)
                        && !attachment)
                    {
                        // The client operates in no fail mode. It will
                        // have already removed the item from the folder
                        // if it's no copy.
                        // Put it back if it's not an attachment
                        //
                        if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
                            remoteClient.SendBulkUpdateInventory(item);
                        return null;
                    }

                    for (int i = 0 ; i < objlist.Count ; i++ )
                    {
                        group = objlist[i];

                        Vector3 storedPosition = group.AbsolutePosition;
                        if (group.UUID == UUID.Zero)
                        {
                            m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3");
                        }
                        group.RootPart.FromFolderID = item.Folder;

                        // If it's rezzed in world, select it. Much easier to 
                        // find small items.
                        //
                        if (!attachment)
                        {
                            group.RootPart.CreateSelected = true;
                            foreach (SceneObjectPart child in group.Parts)
                                child.CreateSelected = true;
                        }
                        group.ResetIDs();

                        if (attachment)
                        {
                            group.RootPart.Flags |= PrimFlags.Phantom;
                            group.RootPart.IsAttachment = true;
                        }

                        // If we're rezzing an attachment then don't ask
                        // AddNewSceneObject() to update the client since
                        // we'll be doing that later on.  Scheduling more than
                        // one full update during the attachment
                        // process causes some clients to fail to display the
                        // attachment properly.
                        m_Scene.AddNewSceneObject(group, true, 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)
                        {
                            group.ScheduleGroupForFullUpdate();
                            
                            group.AbsolutePosition = pos + veclist[i];
                        }
                        else
                        {
                            group.SetFromItemID(itemID);
                        }

                        SceneObjectPart rootPart = null;

                        try
                        {
                            rootPart = group.GetChildPart(group.UUID);
                        }
                        catch (NullReferenceException)
                        {
                            string isAttachment = "";

                            if (attachment)
                                isAttachment = " Object was an attachment";

                            m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
                        }

                        // Since renaming the item in the inventory does not
                        // affect the name stored in the serialization, transfer
                        // the correct name from the inventory to the
                        // object itself before we rez.
                        //
                        // Only do these for the first object if we are rezzing a coalescence.
                        if (i == 0)
                        {
                            rootPart.Name = item.Name;
                            rootPart.Description = item.Description;
                            rootPart.ObjectSaleType = item.SaleType;
                            rootPart.SalePrice = item.SalePrice;
                        }

                        group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
                        if ((rootPart.OwnerID != item.Owner) ||
                            (item.CurrentPermissions & 16) != 0)
                        {
                            //Need to kill the for sale here
                            rootPart.ObjectSaleType = 0;
                            rootPart.SalePrice = 10;

                            if (m_Scene.Permissions.PropagatePermissions())
                            {
                                foreach (SceneObjectPart part in group.Parts)
                                {
                                    if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                                    {
                                        part.EveryoneMask = item.EveryOnePermissions;
                                        part.NextOwnerMask = item.NextPermissions;
                                    }
                                    part.GroupMask = 0; // DO NOT propagate here
                                }
                                
                                group.ApplyNextOwnerPermissions();
                            }
                        }

                        foreach (SceneObjectPart part in group.Parts)
                        {
                            if ((part.OwnerID != item.Owner) ||
                                (item.CurrentPermissions & 16) != 0)
                            {
                                part.LastOwnerID = part.OwnerID;
                                part.OwnerID = item.Owner;
                                part.Inventory.ChangeInventoryOwner(item.Owner);
                                part.GroupMask = 0; // DO NOT propagate here
                            }
                            part.EveryoneMask = item.EveryOnePermissions;
                            part.NextOwnerMask = item.NextPermissions;
                        }

                        rootPart.TrimPermissions();

                        if (!attachment)
                        {
                            if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
                                group.ClearPartAttachmentData();
                            
                            // Fire on_rez
                            group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
                            rootPart.ParentGroup.ResumeScripts();

                            rootPart.ScheduleFullUpdate();
                        }
                    }

                    if (!m_Scene.Permissions.BypassPermissions())
                    {
                        if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                        {
                            // If this is done on attachments, no
                            // copy ones will be lost, so avoid it
                            //
                            if (!attachment)
                            {
                                List<UUID> uuids = new List<UUID>();
                                uuids.Add(item.ID);
                                m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
                            }
                        }
                    }
                }
                return group;
            }

            return null;
        }
コード例 #9
0
        private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
        {
            if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);

            // Group invitations
            if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline))
            {
                UUID inviteID = new UUID(im.imSessionID);
                GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID);

                if (inviteInfo == null)
                {
                    if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Received an Invite IM for an invite that does not exist {0}.", inviteID);
                    return;
                }

                if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID);

                UUID fromAgentID = new UUID(im.fromAgentID);
                if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID))
                {
                    // Accept
                    if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept)
                    {
                        if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice.");

                        // and the sessionid is the role
                        m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID);

                        GridInstantMessage msg = new GridInstantMessage();
                        msg.imSessionID = UUID.Zero.Guid;
                        msg.fromAgentID = UUID.Zero.Guid;
                        msg.toAgentID = inviteInfo.AgentID.Guid;
                        msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
                        msg.fromAgentName = "Groups";
                        msg.message = string.Format("You have been added to the group.");
                        msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox;
                        msg.fromGroup = false;
                        msg.offline = (byte)0;
                        msg.ParentEstateID = 0;
                        msg.Position = Vector3.Zero;
                        msg.RegionID = UUID.Zero.Guid;
                        msg.binaryBucket = new byte[0];

                        OutgoingInstantMessage(msg, inviteInfo.AgentID);

                        //WTH??? noone but the invitee needs to know
                        //UpdateAllClientsWithGroupInfo(inviteInfo.AgentID);
                        SendAgentGroupDataUpdate(remoteClient);
                        // XTODO: If the inviter is still online, they need an agent dataupdate 
                        // and maybe group membership updates for the invitee
                        // Reply: why do they need that? they will get told about the new user when they reopen the groups panel

                        m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID);
                    }

                    // Reject
                    if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)
                    {
                        if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice.");
                        m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID);
                    }
                }
            }

            // Group notices
            if ((im.dialog == (byte)InstantMessageDialog.GroupNotice))
            {
                if (!m_groupNoticesEnabled)
                    return;

                UUID GroupID = new UUID(im.toAgentID);
                if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null)
                {
                    UUID NoticeID = UUID.Random();
                    string Subject = im.message.Substring(0, im.message.IndexOf('|'));
                    string Message = im.message.Substring(Subject.Length + 1);

                    byte[] bucket;
                    UUID ItemID = UUID.Zero;
                    int AssetType = 0;
                    string ItemName = "";
                    
                    if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0))
                    {
                        bucket = new byte[19];
                        bucket[0] = 0;
                        bucket[1] = 0;
                        GroupID.ToBytes(bucket, 2);
                        bucket[18] = 0;
                    }
                    else
                    {
                        bucket = im.binaryBucket;
                        string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
                        binBucket = binBucket.Remove(0, 14).Trim();

                        OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
                        if (binBucketOSD.ContainsKey("item_id"))
                        {
                            ItemID = binBucketOSD["item_id"].AsUUID();

                            InventoryItemBase item = new InventoryItemBase(ItemID, GetRequestingAgentID(remoteClient));
                            item = m_sceneList[0].InventoryService.GetItem(item);
                            if (item != null)
                            {
                                AssetType = item.AssetType;
                                ItemName = item.Name;
                            }
                            else
                                ItemID = UUID.Zero;
                        }
                    }

                    m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, ItemID, AssetType, ItemName);
                    if (OnNewGroupNotice != null)
                        OnNewGroupNotice(GroupID, NoticeID);

                    // Send notice out to everyone that wants notices
                    foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID))
                    {
                        if (m_debugEnabled)
                        {
                            UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, member.AgentID);
                            if (targetUser != null)
                            {
                                m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices);
                            }
                            else
                            {
                                m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices);
                            }
                        }

                        if (member.AcceptNotices)
                        {
                            // Build notice IIM
                            GridInstantMessage msg = CreateGroupNoticeIM(GetRequestingAgentID(remoteClient), NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);

                            msg.toAgentID = member.AgentID.Guid;
                            OutgoingInstantMessage(msg, member.AgentID);
                        }
                    }
                }
            }
            if ((im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryDeclined) || (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryDeclined))
            {
                GroupAttachmentCache.Remove(im.imSessionID);
            }
            if ((im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) || (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted))
            {
                UUID FolderID = new UUID(im.binaryBucket, 0);
                InventoryItemBase item = new InventoryItemBase(GroupAttachmentCache[im.imSessionID]);
                item = ((Scene)remoteClient.Scene).InventoryService.GetItem(item);
                
                ILLClientInventory inventoryModule = remoteClient.Scene.RequestModuleInterface<ILLClientInventory>();
                if (inventoryModule != null)
                    item = inventoryModule.GiveInventoryItem(remoteClient.AgentId, item.Owner, GroupAttachmentCache[im.imSessionID], FolderID);

                if (item != null)
                    remoteClient.SendBulkUpdateInventory(item);
                GroupAttachmentCache.Remove(im.imSessionID);
            }
            
            if ((im.dialog == 210))
            {
                // This is sent from the region that the ejectee was ejected from
                // if it's being delivered here, then the ejectee is here
                // so we need to send local updates to the agent.

                UUID ejecteeID = new UUID(im.toAgentID);

                im.dialog = (byte)InstantMessageDialog.MessageFromAgent;
                OutgoingInstantMessage(im, ejecteeID);

                IClientAPI ejectee = GetActiveClient(ejecteeID);
                if (ejectee != null)
                {
                    UUID groupID = new UUID(im.imSessionID);
                    ejectee.SendAgentDropGroup(groupID);
                }
            }

            // Interop, received special 211 code for offline group notice
            if ((im.dialog == 211))
            {
                im.dialog = (byte)InstantMessageDialog.GroupNotice;

                //In offline group notices, imSessionID is replaced with the NoticeID so that we can rebuild the packet here
                GroupNoticeInfo GND = m_groupData.GetGroupNotice(new UUID(im.toAgentID), new UUID(im.imSessionID));

                //We reset the ID so that if this was set before, it won't be misadded or anything to the cache
                im.imSessionID = UUID.Random().Guid; 

                //Rebuild the binary bucket
                if (GND.noticeData.HasAttachment)
                {
                    im.binaryBucket = CreateBitBucketForGroupAttachment(GND.noticeData, GND.GroupID);
                    //Save the sessionID for the callback by the client (reject or accept)
                    //Only save if has attachment
                    GroupAttachmentCache[im.imSessionID] = GND.noticeData.ItemID;
                }
                else
                {
                    byte[] bucket = new byte[19];
                    bucket[0] = 0; //Attachment enabled == false so 0
                    bucket[1] = 0; //No attachment, so no asset type
                    GND.GroupID.ToBytes(bucket, 2);
                    bucket[18] = 0; //dunno
                    im.binaryBucket = bucket;
                }

                OutgoingInstantMessage(im, new UUID(im.toAgentID));

                //You MUST reset this, otherwise the client will get it twice,
                // as it goes through OnGridInstantMessage
                // which will check and then reresent the notice
                im.dialog = 211;
            }
        }
コード例 #10
0
        public virtual SceneObjectGroup RezObject(
            IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart,
            UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
            bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
        {
            AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());           

            if (rezAsset == null)
            {
                if (item != null)
                {
                    m_log.WarnFormat(
                        "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()",
                        assetID, item.Name, item.ID, remoteClient.Name);
                    remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: could not find asset {0} for item {1}.", assetID, item.Name), false);
                }
                else
                {
                    m_log.WarnFormat(
                        "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()",
                        assetID, remoteClient.Name);
                    remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: could not find asset {0}.", assetID), false);
                }

                return null;
            }

            SceneObjectGroup group = null;

            List<SceneObjectGroup> objlist;
            List<Vector3> veclist;
            Vector3 bbox;
            float offsetHeight;
            byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
            Vector3 pos;

            bool single 
                = m_Scene.GetObjectsToRez(
                    rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight);

            if (single)
            {
                pos = m_Scene.GetNewRezLocation(
                    RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                    BypassRayCast, bRayEndIsIntersection, true, bbox, false);
                pos.Z += offsetHeight;
            }
            else
            {
                pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
                        RayTargetID, Quaternion.Identity,
                        BypassRayCast, bRayEndIsIntersection, true,
                        bbox, false);
                pos -= bbox / 2;
            }

            int primcount = 0;
            foreach (SceneObjectGroup g in objlist)
                primcount += g.PrimCount;

            if (!m_Scene.Permissions.CanRezObject(
                primcount, remoteClient.AgentId, pos)
                && !attachment)
            {
                // The client operates in no fail mode. It will
                // have already removed the item from the folder
                // if it's no copy.
                // Put it back if it's not an attachment
                //
                if (item != null)
                {
                    if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
                        remoteClient.SendBulkUpdateInventory(item);
                }

                return null;
            }

            if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment))
                return null;

            for (int i = 0; i < objlist.Count; i++)
            {
                group = objlist[i];
                SceneObjectPart rootPart = group.RootPart;

//                m_log.DebugFormat(
//                    "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
//                    group.Name, group.LocalId, group.UUID,
//                    group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
//                    remoteClient.Name);

//                        Vector3 storedPosition = group.AbsolutePosition;
                if (group.UUID == UUID.Zero)
                {
                    m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3");
                }

                // if this was previously an attachment and is now being rezzed,
                // save the old attachment info.
                if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
                {
                    group.RootPart.AttachedPos = group.AbsolutePosition;
                    group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
                }

                if (item == null)
                {
                    // Change ownership. Normally this is done in DoPreRezWhenFromItem(), but in this case we must do it here.
                    foreach (SceneObjectPart part in group.Parts)
                    {
                        // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
                        part.LastOwnerID = part.OwnerID;
                        part.OwnerID = remoteClient.AgentId;
                    }
                }

                group.ResetIDs();

                if (!attachment)
                {
                    // If it's rezzed in world, select it. Much easier to
                    // find small items.
                    //
                    foreach (SceneObjectPart part in group.Parts)
                    {
                        part.CreateSelected = true;
                    }

                    if (rootPart.Shape.PCode == (byte)PCode.Prim)
                        group.ClearPartAttachmentData();
                }
                else
                {
                    group.IsAttachment = true;
                }

                // If we're rezzing an attachment then don't ask
                // AddNewSceneObject() to update the client since
                // we'll be doing that later on.  Scheduling more than
                // one full update during the attachment
                // process causes some clients to fail to display the
                // attachment properly.
                m_Scene.AddNewSceneObject(group, true, false);

                if (!attachment)
                    group.AbsolutePosition = pos + veclist[i];

                group.SetGroup(remoteClient.ActiveGroupId, remoteClient);

                if (!attachment)
                {
                    // Fire on_rez
                    group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
                    rootPart.ParentGroup.ResumeScripts();

                    group.ScheduleGroupForFullUpdate();
                }

//                m_log.DebugFormat(
//                    "[INVENTORY ACCESS MODULE]:  Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
//                    group.Name, group.LocalId, group.UUID,
//                    group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
//                    remoteClient.Name);
            }

//            group.SetGroup(remoteClient.ActiveGroupId, remoteClient);

            if (item != null)
                DoPostRezWhenFromItem(item, attachment);

            return group;
        }
コード例 #11
0
        private List <SceneObjectGroup> RezMultipleObjectsFromInventory(XmlNodeList nodes, UUID itemId, IClientAPI remoteClient, Vector3 pos, bool RezSelected,
                                                                        InventoryItemBase item, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, Vector3 RayEnd, Vector3 RayStart, byte bRayEndIsIntersection)
        {
            Vector3 OldMiddlePos             = Vector3.Zero;
            List <SceneObjectGroup> NewGroup = new List <SceneObjectGroup>();

            foreach (System.Xml.XmlNode aPrimNode in nodes)
            {
                if (aPrimNode.OuterXml.StartsWith("<middle>"))
                {
                    string Position = aPrimNode.OuterXml.Remove(0, 13);
                    Position = Position.Remove(Position.Length - 16, 16);
                    string[] XYZ = Position.Split(' ');
                    OldMiddlePos = new Vector3(float.Parse(XYZ[0]), float.Parse(XYZ[1]), float.Parse(XYZ[2]));
                    continue;
                }
                SceneObjectGroup group
                    = SceneObjectSerializer.FromOriginalXmlFormat(aPrimNode.OuterXml, m_scene);
                if (group == null)
                {
                    return(null);
                }

                group.IsDeleted  = false;
                group.m_isLoaded = true;
                foreach (SceneObjectPart part in group.ChildrenList)
                {
                    part.IsLoading = false;
                }
                NewGroup.Add(group);

                string reason;
                if (!m_scene.Permissions.CanRezObject(
                        group.ChildrenList.Count, remoteClient.AgentId, pos, out reason))
                {
                    // The client operates in no fail mode. It will
                    // have already removed the item from the folder
                    // if it's no copy.
                    // Put it back if it's not an attachment
                    //
                    if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0))
                    {
                        remoteClient.SendBulkUpdateInventory(item);
                    }
                    return(null);
                }

                if (RezSelected)
                {
                    group.RootPart.AddFlag(PrimFlags.CreateSelected);
                }
                // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
                // we'll be doing that later on.  Scheduling more than one full update during the attachment
                // process causes some clients to fail to display the attachment properly.
                m_scene.SceneGraph.AddPrimToScene(group);

                //  m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
                // if attachment we set it's asset id so object updates can reflect that
                // if not, we set it's position in world.
                float offsetHeight = 0;
                pos = m_scene.SceneGraph.GetNewRezLocation(
                    RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                    BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
                pos.Z += offsetHeight;
                //group.AbsolutePosition = pos;
                //   m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);

                SceneObjectPart rootPart = (SceneObjectPart)group.GetChildPart(group.UUID);

                // Since renaming the item in the inventory does not affect the name stored
                // in the serialization, transfer the correct name from the inventory to the
                // object itself before we rez.
                rootPart.Name        = item.Name;
                rootPart.Description = item.Description;

                List <SceneObjectPart> partList = new List <SceneObjectPart>(group.ChildrenList);

                group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
                item.Owner = remoteClient.AgentId;
                if (rootPart.OwnerID != item.Owner)
                {
                    //Need to kill the for sale here
                    rootPart.ObjectSaleType = 0;
                    rootPart.SalePrice      = 10;

                    if (m_scene.Permissions.PropagatePermissions())
                    {
                        if ((item.CurrentPermissions & 8) != 0)
                        {
                            foreach (SceneObjectPart part in partList)
                            {
                                part.EveryoneMask  = item.EveryOnePermissions;
                                part.NextOwnerMask = item.NextPermissions;
                                part.GroupMask     = 0; // DO NOT propagate here
                            }
                        }

                        group.ApplyNextOwnerPermissions();
                    }
                }

                foreach (SceneObjectPart part in partList)
                {
                    if (part.OwnerID != item.Owner)
                    {
                        part.LastOwnerID = part.OwnerID;
                        part.OwnerID     = item.Owner;
                        part.Inventory.ChangeInventoryOwner(item.Owner);
                    }
                    else if ((item.CurrentPermissions & 8) != 0) // Slam!
                    {
                        part.EveryoneMask  = item.EveryOnePermissions;
                        part.NextOwnerMask = item.NextPermissions;

                        part.GroupMask = 0; // DO NOT propagate here
                    }
                }

                rootPart.TrimPermissions();

                if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
                {
                    group.ClearPartAttachmentData();
                }

                // Fire on_rez
                group.CreateScriptInstances(0, true, 0, UUID.Zero);
                rootPart.ParentGroup.ResumeScripts();

                if (!m_scene.Permissions.BypassPermissions())
                {
                    if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                    {
                        // If this is done on attachments, no
                        // copy ones will be lost, so avoid it
                        //
                        List <UUID> uuids = new List <UUID>();
                        uuids.Add(item.ID);
                        m_scene.InventoryService.DeleteItems(item.Owner, uuids);
                    }
                }
            }
            foreach (SceneObjectGroup group in NewGroup)
            {
                if (OldMiddlePos != Vector3.Zero)
                {
                    Vector3 NewPosOffset = Vector3.Zero;
                    NewPosOffset.X         = group.AbsolutePosition.X - OldMiddlePos.X;
                    NewPosOffset.Y         = group.AbsolutePosition.Y - OldMiddlePos.Y;
                    NewPosOffset.Z         = group.AbsolutePosition.Z - OldMiddlePos.Z;
                    group.AbsolutePosition = pos + NewPosOffset;
                }
                group.ScheduleGroupUpdate(PrimUpdateFlags.FullUpdate);
            }
            return(NewGroup);
        }
コード例 #12
0
        /// <summary>
        /// Give an inventory item from one user to another
        /// </summary>
        /// <param name="recipientClient"></param>
        /// <param name="senderId">ID of the sender of the item</param>
        /// <param name="itemId"></param>
        public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId)
        {
            InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId);

            if (itemCopy != null)
                recipientClient.SendBulkUpdateInventory(itemCopy);
        }
コード例 #13
0
        /// <summary>
        ///     Rez an object into the scene from the user's inventory
        /// </summary>
        /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
        /// things to the scene.  The caller should be doing that, I think.
        /// <param name="remoteClient"></param>
        /// <param name="itemID"></param>
        /// <param name="RayEnd"></param>
        /// <param name="RayStart"></param>
        /// <param name="RayTargetID"></param>
        /// <param name="BypassRayCast"></param>
        /// <param name="RayEndIsIntersection"></param>
        /// <param name="RezSelected"></param>
        /// <param name="RemoveItem"></param>
        /// <param name="fromTaskID"></param>
        /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
        public virtual ISceneEntity RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
            UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
            bool RezSelected, bool RemoveItem, UUID fromTaskID)
        {
            // Work out position details
            byte bRayEndIsIntersection = (byte) 0;

            bRayEndIsIntersection = (byte) (RayEndIsIntersection ? 1 : 0);

            XmlDocument doc;
            //It might be a library item, send UUID.Zero
            InventoryItemBase item = m_scene.InventoryService.GetItem(UUID.Zero, itemID);
            if (item == null)
            {
                remoteClient.SendAlertMessage("Failed to find the item you requested.");
                return null;
            }
            ISceneEntity group = CreateObjectFromInventory(item, remoteClient, itemID, out doc);

            Vector3 pos = m_scene.SceneGraph.GetNewRezLocation(
                RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                BypassRayCast, bRayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false);

            if (doc == null)
            {
                //No asset, check task inventory
                IEntity e;
                m_scene.SceneGraph.TryGetEntity(fromTaskID, out e);
                if (e != null && e is ISceneEntity)
                {
                    ISceneEntity grp = (ISceneEntity) e;
                    TaskInventoryItem taskItem = grp.RootChild.Inventory.GetInventoryItem(itemID);
                    item = new InventoryItemBase
                               {
                                   ID = UUID.Random(),
                                   CreatorId = taskItem.CreatorID.ToString(),
                                   Owner = remoteClient.AgentId,
                                   AssetID = taskItem.AssetID,
                                   Description = taskItem.Description,
                                   Name = taskItem.Name,
                                   AssetType = taskItem.Type,
                                   InvType = taskItem.InvType,
                                   Flags = taskItem.Flags,
                                   SalePrice = taskItem.SalePrice,
                                   SaleType = taskItem.SaleType
                               };

                    if (m_scene.Permissions.PropagatePermissions())
                    {
                        item.BasePermissions = taskItem.BasePermissions &
                                               (taskItem.NextPermissions | (uint) PermissionMask.Move);
                        if (taskItem.InvType == (int) InventoryType.Object)
                            item.CurrentPermissions = item.BasePermissions &
                                                      (((taskItem.CurrentPermissions & 7) << 13) |
                                                       (taskItem.CurrentPermissions & (uint) PermissionMask.Move));
                        else
                            item.CurrentPermissions = item.BasePermissions & taskItem.CurrentPermissions;

                        item.CurrentPermissions |= 16; // Slam
                        item.NextPermissions = taskItem.NextPermissions;
                        item.EveryOnePermissions = taskItem.EveryonePermissions &
                                                   (taskItem.NextPermissions | (uint) PermissionMask.Move);
                        item.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions;
                    }
                    else
                    {
                        item.BasePermissions = taskItem.BasePermissions;
                        item.CurrentPermissions = taskItem.CurrentPermissions;
                        item.NextPermissions = taskItem.NextPermissions;
                        item.EveryOnePermissions = taskItem.EveryonePermissions;
                        item.GroupPermissions = taskItem.GroupPermissions;
                    }
                    group = CreateObjectFromInventory(item, remoteClient, itemID, out doc);
                }
            }
            if (group == null && doc != null && doc.FirstChild != null &&
                (doc.FirstChild.OuterXml.StartsWith("<groups>") ||
                 (doc.FirstChild.NextSibling != null &&
                  doc.FirstChild.NextSibling.OuterXml.StartsWith("<groups>"))))
            {
                XmlNodeList nodes;
                if (doc.FirstChild.OuterXml.StartsWith("<groups>")) nodes = doc.FirstChild.ChildNodes;
                else if (doc.FirstChild.NextSibling != null) nodes = doc.FirstChild.NextSibling.ChildNodes;
                else
                {
                    remoteClient.SendAlertMessage("Failed to find the item you requested.");
                    return null;
                }
                List<ISceneEntity> Groups = RezMultipleObjectsFromInventory(nodes, itemID, remoteClient, pos,
                                                                            RezSelected, item, RayTargetID,
                                                                            BypassRayCast, RayEndIsIntersection, RayEnd,
                                                                            RayStart, bRayEndIsIntersection);
                if (Groups.Count != 0)
                    return Groups[0];
                remoteClient.SendAlertMessage("Failed to rez the item you requested.");
                return null;
            }
            if (group == null)
            {
                remoteClient.SendAlertMessage("Failed to find the item you requested.");
                return null;
            }

            string reason;
            if (!m_scene.Permissions.CanRezObject(
                group.ChildrenEntities().Count, remoteClient.AgentId, pos, out reason))
            {
                // The client operates in no fail mode. It will
                // have already removed the item from the folder
                // if it's no copy.
                // Put it back if it's not an attachment
                //
                if ((item.CurrentPermissions & (uint) PermissionMask.Copy) == 0)
                    remoteClient.SendBulkUpdateInventory(item);
                remoteClient.SendAlertMessage("You do not have permission to rez objects here.");
                return null;
            }

            if (RezSelected)
                group.RootChild.AddFlag(PrimFlags.CreateSelected);
            // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
            // we'll be doing that later on.  Scheduling more than one full update during the attachment
            // process causes some clients to fail to display the attachment properly.
            m_scene.SceneGraph.AddPrimToScene(group);

            //  MainConsole.Instance.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
            //  Set it's position in world.
            const float offsetHeight = 0;
            //The OOBsize is only half the size, x2
            Vector3 newSize = (group.OOBsize*2)*Quaternion.Inverse(group.GroupRotation);
            pos = m_scene.SceneGraph.GetNewRezLocation(
                RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                BypassRayCast, bRayEndIsIntersection, true, newSize, false);
            pos.Z += offsetHeight;
            group.AbsolutePosition = pos;
            //   MainConsole.Instance.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);

            ISceneChildEntity rootPart = group.GetChildPart(group.UUID);
            if (rootPart == null)
            {
                MainConsole.Instance.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID +
                                           " object has no rootpart.");
                return null;
            }

            // Since renaming the item in the inventory does not affect the name stored
            // in the serialization, transfer the correct name from the inventory to the
            // object itself before we rez.
            rootPart.Name = item.Name;
            rootPart.Description = item.Description;

            List<ISceneChildEntity> partList = group.ChildrenEntities();

            group.SetGroup(remoteClient.ActiveGroupId, remoteClient.AgentId, false);
            item.Owner = remoteClient.AgentId;
            if (rootPart.OwnerID != item.Owner)
            {
                //Need to kill the for sale here
                rootPart.ObjectSaleType = 0;
                rootPart.SalePrice = 10;

                if (m_scene.Permissions.PropagatePermissions())
                {
                    if ((item.CurrentPermissions & 8) != 0)
                    {
                        foreach (ISceneChildEntity part in partList)
                        {
                            part.EveryoneMask = item.EveryOnePermissions;
                            part.NextOwnerMask = item.NextPermissions;
                            part.GroupMask = 0; // DO NOT propagate here
                        }
                    }

                    group.ApplyNextOwnerPermissions();
                }
            }

            foreach (ISceneChildEntity part in partList)
            {
                if (part.OwnerID != item.Owner)
                {
                    part.LastOwnerID = part.OwnerID;
                    part.OwnerID = item.Owner;
                    part.Inventory.ChangeInventoryOwner(item.Owner);
                }
                else if ((item.CurrentPermissions & 8) != 0) // Slam!
                {
                    part.EveryoneMask = item.EveryOnePermissions;
                    part.NextOwnerMask = item.NextPermissions;

                    part.GroupMask = 0; // DO NOT propagate here
                }
            }

            rootPart.TrimPermissions();

            if (group.RootChild.Shape.PCode == (byte) PCode.Prim)
            {
                group.ClearPartAttachmentData();
            }

            // Fire on_rez
            group.CreateScriptInstances(0, true, StateSource.NewRez, UUID.Zero, false);

            group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate);
            if (!m_scene.Permissions.BypassPermissions())
            {
                if ((item.CurrentPermissions & (uint) PermissionMask.Copy) == 0)
                {
                    List<UUID> uuids = new List<UUID> {item.ID};
                    m_scene.InventoryService.DeleteItems(item.Owner, uuids);
                }
            }
            return group;
        }
コード例 #14
0
        private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
        {
            if (m_debugEnabled)
                MainConsole.Instance.DebugFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name);

            // Group invitations
            if ((im.Dialog == (byte) InstantMessageDialog.GroupInvitationAccept) ||
                (im.Dialog == (byte) InstantMessageDialog.GroupInvitationDecline))
            {
                UUID inviteID = im.SessionID;
                GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient),
                                                                               inviteID);

                if (inviteInfo == null)
                {
                    if (m_debugEnabled)
                        MainConsole.Instance.WarnFormat(
                            "[GROUPS]: Received an Invite IM for an invite that does not exist {0}.",
                            inviteID);
                    return;
                }

                if (m_debugEnabled)
                    MainConsole.Instance.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.",
                                                     inviteInfo.AgentID,
                                                     inviteInfo.GroupID);

                UUID fromAgentID = im.FromAgentID;
                if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID))
                {
                    // Accept
                    if (im.Dialog == (byte) InstantMessageDialog.GroupInvitationAccept)
                    {
                        if (m_debugEnabled)
                            MainConsole.Instance.DebugFormat("[GROUPS]: Received an accept invite notice.");

                        // and the sessionid is the role
                        UserAccount account = m_scene.UserAccountService.GetUserAccount(remoteClient.AllScopeIDs,
                                                                                        inviteInfo.FromAgentName);
                        if (account != null)
                        {
                            m_groupData.AddAgentToGroup(account.PrincipalID, inviteInfo.AgentID, inviteInfo.GroupID,
                                                        inviteInfo.RoleID);

                            GridInstantMessage msg = new GridInstantMessage
                                                         {
                                                             SessionID = UUID.Zero,
                                                             FromAgentID = UUID.Zero,
                                                             ToAgentID = inviteInfo.AgentID,
                                                             Timestamp = (uint) Util.UnixTimeSinceEpoch(),
                                                             FromAgentName = "Groups",
                                                             Message =
                                                                 string.Format("You have been added to the group."),
                                                             Dialog = (byte) InstantMessageDialog.MessageBox,
                                                             FromGroup = false,
                                                             Offline = 0,
                                                             ParentEstateID = 0,
                                                             Position = Vector3.Zero,
                                                             RegionID = UUID.Zero,
                                                             BinaryBucket = new byte[0]
                                                         };

                            OutgoingInstantMessage(msg, inviteInfo.AgentID);

                            GroupMembershipData gmd =
                                AttemptFindGroupMembershipData(inviteInfo.AgentID, inviteInfo.AgentID,
                                                               inviteInfo.GroupID);
                            m_cachedGroupTitles[inviteInfo.AgentID] = gmd;
                            m_cachedGroupMemberships.Remove(remoteClient.AgentId);
                            RemoveFromGroupPowersCache(inviteInfo.AgentID, inviteInfo.GroupID);
                            UpdateAllClientsWithGroupInfo(inviteInfo.AgentID, gmd.GroupTitle);
                            SendAgentGroupDataUpdate(remoteClient);

                            m_groupData.RemoveAgentInvite(GetRequestingAgentID(remoteClient), inviteID);
                        }
                    }

                    // Reject
                    if (im.Dialog == (byte) InstantMessageDialog.GroupInvitationDecline)
                    {
                        if (m_debugEnabled)
                            MainConsole.Instance.DebugFormat("[GROUPS]: Received a reject invite notice.");
                        m_groupData.RemoveAgentInvite(GetRequestingAgentID(remoteClient), inviteID);
                    }
                    RemoveFromGroupPowersCache(remoteClient.AgentId, inviteInfo.GroupID);
                }
            }

            // Group notices
            switch (im.Dialog)
            {
                case (byte) InstantMessageDialog.GroupNotice:
                    {
                        if (!m_groupNoticesEnabled)
                            return;

                        UUID GroupID = im.ToAgentID;
                        if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null)
                        {
                            UUID NoticeID = UUID.Random();
                            string Subject = im.Message.Substring(0, im.Message.IndexOf('|'));
                            string Message = im.Message.Substring(Subject.Length + 1);

                            byte[] bucket;
                            UUID ItemID = UUID.Zero;
                            int AssetType = 0;
                            string ItemName = "";

                            if ((im.BinaryBucket.Length == 1) && (im.BinaryBucket[0] == 0))
                            {
                                bucket = new byte[19];
                                bucket[0] = 0;
                                bucket[1] = 0;
                                GroupID.ToBytes(bucket, 2);
                                bucket[18] = 0;
                            }
                            else
                            {
                                bucket = im.BinaryBucket;
                                string binBucket = Utils.BytesToString(im.BinaryBucket);
                                binBucket = binBucket.Remove(0, 14).Trim();

                                OSDMap binBucketOSD = (OSDMap) OSDParser.DeserializeLLSDXml(binBucket);
                                if (binBucketOSD.ContainsKey("item_id"))
                                {
                                    ItemID = binBucketOSD["item_id"].AsUUID();

                                    InventoryItemBase item =
                                        m_scene.InventoryService.GetItem(GetRequestingAgentID(remoteClient), ItemID);
                                    if (item != null)
                                    {
                                        AssetType = item.AssetType;
                                        ItemName = item.Name;
                                    }
                                    else
                                        ItemID = UUID.Zero;
                                }
                            }

                            m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID,
                                                       im.FromAgentName,
                                                       Subject, Message, ItemID, AssetType, ItemName);
                            if (OnNewGroupNotice != null)
                                OnNewGroupNotice(GroupID, NoticeID);
                            GroupNoticeInfo notice = new GroupNoticeInfo()
                                                         {
                                                             BinaryBucket = im.BinaryBucket,
                                                             GroupID = GroupID,
                                                             Message = Message,
                                                             noticeData = new GroupNoticeData()
                                                                              {
                                                                                  AssetType = (byte) AssetType,
                                                                                  FromName = im.FromAgentName,
                                                                                  GroupID = GroupID,
                                                                                  HasAttachment = ItemID != UUID.Zero,
                                                                                  ItemID = ItemID,
                                                                                  ItemName = ItemName,
                                                                                  NoticeID = NoticeID,
                                                                                  Subject = Subject,
                                                                                  Timestamp = im.Timestamp
                                                                              }
                                                         };

                            SendGroupNoticeToUsers(remoteClient, notice, false);
                        }
                    }
                    break;
                case (byte) InstantMessageDialog.GroupNoticeInventoryDeclined:
                    break;
                case (byte) InstantMessageDialog.GroupNoticeInventoryAccepted:
                    {
                        UUID FolderID = new UUID(im.BinaryBucket, 0);
                        remoteClient.Scene.InventoryService.GiveInventoryItemAsync(remoteClient.AgentId, UUID.Zero,
                                                                                   im.SessionID, FolderID, false,
                                                                                   (item) =>
                                                                                       {
                                                                                           if (item != null)
                                                                                               remoteClient
                                                                                                   .SendBulkUpdateInventory
                                                                                                   (item);
                                                                                       });
                    }
                    break;
                case 210:
                    {
                        // This is sent from the region that the ejectee was ejected from
                        // if it's being delivered here, then the ejectee is here
                        // so we need to send local updates to the agent.

                        UUID ejecteeID = im.ToAgentID;

                        im.Dialog = (byte) InstantMessageDialog.MessageFromAgent;
                        OutgoingInstantMessage(im, ejecteeID);

                        IClientAPI ejectee = GetActiveClient(ejecteeID);
                        if (ejectee != null)
                        {
                            UUID groupID = im.SessionID;
                            ejectee.SendAgentDropGroup(groupID);
                            if (ejectee.ActiveGroupId == groupID)
                                GroupTitleUpdate(ejectee, UUID.Zero, UUID.Zero);
                            RemoveFromGroupPowersCache(ejecteeID, groupID);
                        }
                    }
                    break;
                case 211:
                    {
                        im.Dialog = (byte) InstantMessageDialog.GroupNotice;

                        //In offline group notices, imSessionID is replaced with the NoticeID so that we can rebuild the packet here
                        GroupNoticeInfo GND = m_groupData.GetGroupNotice(im.ToAgentID, im.SessionID);

                        //Rebuild the binary bucket
                        if (GND.noticeData.HasAttachment)
                        {
                            im.BinaryBucket = CreateBitBucketForGroupAttachment(GND.noticeData, GND.GroupID);
                            //Save the sessionID for the callback by the client (reject or accept)
                            //Only save if has attachment
                            im.SessionID = GND.noticeData.ItemID;
                        }
                        else
                        {
                            byte[] bucket = new byte[19];
                            bucket[0] = 0; //Attachment enabled == false so 0
                            bucket[1] = 0; //No attachment, so no asset type
                            GND.GroupID.ToBytes(bucket, 2);
                            bucket[18] = 0; //dunno
                            im.BinaryBucket = bucket;
                        }

                        OutgoingInstantMessage(im, im.ToAgentID);

                        //You MUST reset this, otherwise the client will get it twice,
                        // as it goes through OnGridInstantMessage
                        // which will check and then reresent the notice
                        im.Dialog = 211;
                    }
                    break;
            }
        }
コード例 #15
0
        /// <summary>
        /// Do pre-rez processing when the object comes from an item.
        /// </summary>
        /// <param name="remoteClient"></param>
        /// <param name="item"></param>
        /// <param name="objlist"></param>
        /// <param name="pos"></param>
        /// <param name="veclist">
        /// List of vector position adjustments for a coalesced objects.  For ordinary objects
        /// this list will contain just Vector3.Zero.  The order of adjustments must match the order of objlist
        /// </param>
        /// <param name="isAttachment"></param>
        /// <returns>true if we can processed with rezzing, false if we need to abort</returns>
        private bool DoPreRezWhenFromItem(
            IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, 
            Vector3 pos, List<Vector3> veclist, bool isAttachment)
        {
            UUID fromUserInventoryItemId = 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 (!m_Scene.Permissions.BypassPermissions())
            {
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy)
                    == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                {
                    fromUserInventoryItemId = item.ID;
                }
            }
            else
            {
                if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                {
                    // Brave new fullperm world
                    fromUserInventoryItemId = item.ID;
                }
            }

            for (int i = 0; i < objlist.Count; i++)
            {
                SceneObjectGroup g = objlist[i];

                if (!m_Scene.Permissions.CanRezObject(
                    g.PrimCount, remoteClient.AgentId, pos + veclist[i])
                    && !isAttachment)
                {
                    // The client operates in no fail mode. It will
                    // have already removed the item from the folder
                    // if it's no copy.
                    // Put it back if it's not an attachment
                    //
                    if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
                        remoteClient.SendBulkUpdateInventory(item);

                    ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
                    remoteClient.SendAlertMessage(string.Format(
                        "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
                        item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name));

                    return false;
                }
            }

            for (int i = 0; i < objlist.Count; i++)
            {
                SceneObjectGroup so = objlist[i];
                SceneObjectPart rootPart = so.RootPart;

                // Since renaming the item in the inventory does not
                // affect the name stored in the serialization, transfer
                // the correct name from the inventory to the
                // object itself before we rez.
                //
                // Only do these for the first object if we are rezzing a coalescence.
                if (i == 0)
                {
                    rootPart.Name = item.Name;
                    rootPart.Description = item.Description;
                    rootPart.ObjectSaleType = item.SaleType;
                    rootPart.SalePrice = item.SalePrice;
                }

                so.FromFolderID = item.Folder;

//                m_log.DebugFormat(
//                    "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
//                    rootPart.OwnerID, item.Owner, item.CurrentPermissions);

                if ((rootPart.OwnerID != item.Owner) ||
                    (item.CurrentPermissions & 16) != 0)
                {
                    //Need to kill the for sale here
                    rootPart.ObjectSaleType = 0;
                    rootPart.SalePrice = 10;
    
                    if (m_Scene.Permissions.PropagatePermissions())
                    {
                        foreach (SceneObjectPart part in so.Parts)
                        {
                            if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                            {
                                part.EveryoneMask = item.EveryOnePermissions;
                                part.NextOwnerMask = item.NextPermissions;
                            }
                            part.GroupMask = 0; // DO NOT propagate here
                        }
    
                        so.ApplyNextOwnerPermissions();
                    }
                }
    
                foreach (SceneObjectPart part in so.Parts)
                {
                    part.FromUserInventoryItemID = fromUserInventoryItemId;

                    if ((part.OwnerID != item.Owner) ||
                        (item.CurrentPermissions & 16) != 0)
                    {
                        part.Inventory.ChangeInventoryOwner(item.Owner);
                        part.GroupMask = 0; // DO NOT propagate here
                    }

                    part.EveryoneMask = item.EveryOnePermissions;
                    part.NextOwnerMask = item.NextPermissions;
                }
    
                rootPart.TrimPermissions();

                if (isAttachment)
                    so.FromItemID = item.ID;
            }

            return true;
        }
コード例 #16
0
        /// <summary>
        /// Do pre-rez processing when the object comes from an item.
        /// </summary>
        /// <param name="remoteClient"></param>
        /// <param name="item"></param>
        /// <param name="objlist"></param>
        /// <param name="pos"></param>
        /// <param name="isAttachment"></param>
        /// <returns>true if we can processed with rezzing, false if we need to abort</returns>
        private bool DoPreRezWhenFromItem(
            IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, Vector3 pos, bool isAttachment)
        {
            UUID fromUserInventoryItemId = 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 (!m_Scene.Permissions.BypassPermissions())
            {
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy)
                    == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                {
                    fromUserInventoryItemId = item.ID;
                }
            }
            else
            {
                if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                {
                    // Brave new fullperm world
                    fromUserInventoryItemId = item.ID;
                }
            }

            int primcount = 0;
            foreach (SceneObjectGroup g in objlist)
                primcount += g.PrimCount;

            if (!m_Scene.Permissions.CanRezObject(
                primcount, remoteClient.AgentId, pos)
                && !isAttachment)
            {
                // The client operates in no fail mode. It will
                // have already removed the item from the folder
                // if it's no copy.
                // Put it back if it's not an attachment
                //
                if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
                    remoteClient.SendBulkUpdateInventory(item);

                return false;
            }

            for (int i = 0; i < objlist.Count; i++)
            {
                SceneObjectGroup so = objlist[i];
                SceneObjectPart rootPart = so.RootPart;

                // Since renaming the item in the inventory does not
                // affect the name stored in the serialization, transfer
                // the correct name from the inventory to the
                // object itself before we rez.
                //
                // Only do these for the first object if we are rezzing a coalescence.
                if (i == 0)
                {
                    rootPart.Name = item.Name;
                    rootPart.Description = item.Description;
                    rootPart.ObjectSaleType = item.SaleType;
                    rootPart.SalePrice = item.SalePrice;
                }

                rootPart.FromFolderID = item.Folder;
    
                if ((rootPart.OwnerID != item.Owner) ||
                    (item.CurrentPermissions & 16) != 0)
                {
                    //Need to kill the for sale here
                    rootPart.ObjectSaleType = 0;
                    rootPart.SalePrice = 10;
    
                    if (m_Scene.Permissions.PropagatePermissions())
                    {
                        foreach (SceneObjectPart part in so.Parts)
                        {
                            if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                            {
                                part.EveryoneMask = item.EveryOnePermissions;
                                part.NextOwnerMask = item.NextPermissions;
                            }
                            part.GroupMask = 0; // DO NOT propagate here
                        }
    
                        so.ApplyNextOwnerPermissions();
                    }
                }
    
                foreach (SceneObjectPart part in so.Parts)
                {
                    part.FromUserInventoryItemID = fromUserInventoryItemId;

                    if ((part.OwnerID != item.Owner) ||
                        (item.CurrentPermissions & 16) != 0)
                    {
                        part.Inventory.ChangeInventoryOwner(item.Owner);
                        part.GroupMask = 0; // DO NOT propagate here
                    }

                    part.EveryoneMask = item.EveryOnePermissions;
                    part.NextOwnerMask = item.NextPermissions;
                }
    
                rootPart.TrimPermissions();

                if (isAttachment)
                    so.SetFromItemID(item.ID);
            }

            return true;
        }
コード例 #17
0
        /// <summary>
        /// Rez an object into the scene from the user's inventory
        /// </summary>
        /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
        /// things to the scene.  The caller should be doing that, I think.
        /// <param name="remoteClient"></param>
        /// <param name="itemID"></param>
        /// <param name="RayEnd"></param>
        /// <param name="RayStart"></param>
        /// <param name="RayTargetID"></param>
        /// <param name="BypassRayCast"></param>
        /// <param name="RayEndIsIntersection"></param>
        /// <param name="RezSelected"></param>
        /// <param name="RemoveItem"></param>
        /// <param name="fromTaskID"></param>
        /// <param name="attachment"></param>
        /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
        public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                                  UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                                  bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
        {
            // 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 = m_Scene.GetNewRezLocation(
                RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                BypassRayCast, bRayEndIsIntersection, true, scale, false);

            // Rez object
            InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);

            item = m_Scene.InventoryService.GetItem(item);

            if (item != null)
            {
                AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());

                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 (!m_Scene.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);
                    SceneObjectGroup group
                        = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData);

                    if (!m_Scene.Permissions.CanRezObject(
                            group.Children.Count, remoteClient.AgentId, pos) &&
                        !attachment)
                    {
                        // The client operates in no fail mode. It will
                        // have already removed the item from the folder
                        // if it's no copy.
                        // Put it back if it's not an attachment
                        //
                        if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
                        {
                            remoteClient.SendBulkUpdateInventory(item);
                        }
                        return(null);
                    }

                    group.ResetIDs();

                    if (attachment)
                    {
                        group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom;
                        group.RootPart.IsAttachment = true;
                    }

                    // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
                    // we'll be doing that later on.  Scheduling more than one full update during the attachment
                    // process causes some clients to fail to display the attachment properly.
                    m_Scene.AddNewSceneObject(group, true, false);

                    //  m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
                    // 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)
                    {
                        group.ScheduleGroupForFullUpdate();

                        float offsetHeight = 0;
                        pos = m_Scene.GetNewRezLocation(
                            RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                            BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
                        pos.Z += offsetHeight;
                        group.AbsolutePosition = pos;
                        //   m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);
                    }
                    else
                    {
                        group.SetFromItemID(itemID);
                    }

                    SceneObjectPart rootPart = null;
                    try
                    {
                        rootPart = group.GetChildPart(group.UUID);
                    }
                    catch (NullReferenceException)
                    {
                        string isAttachment = "";

                        if (attachment)
                        {
                            isAttachment = " Object was an attachment";
                        }

                        m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
                    }

                    // Since renaming the item in the inventory does not affect the name stored
                    // in the serialization, transfer the correct name from the inventory to the
                    // object itself before we rez.
                    rootPart.Name        = item.Name;
                    rootPart.Description = item.Description;

                    List <SceneObjectPart> partList = new List <SceneObjectPart>(group.Children.Values);

                    group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
                    if (rootPart.OwnerID != item.Owner)
                    {
                        //Need to kill the for sale here
                        rootPart.ObjectSaleType = 0;
                        rootPart.SalePrice      = 10;

                        if (m_Scene.Permissions.PropagatePermissions())
                        {
                            if ((item.CurrentPermissions & 8) != 0)
                            {
                                foreach (SceneObjectPart part in partList)
                                {
                                    part.EveryoneMask  = item.EveryOnePermissions;
                                    part.NextOwnerMask = item.NextPermissions;
                                    part.GroupMask     = 0; // DO NOT propagate here
                                }
                            }

                            group.ApplyNextOwnerPermissions();
                        }
                    }

                    foreach (SceneObjectPart part in partList)
                    {
                        if (part.OwnerID != item.Owner)
                        {
                            part.LastOwnerID = part.OwnerID;
                            part.OwnerID     = item.Owner;
                            part.Inventory.ChangeInventoryOwner(item.Owner);
                        }
                        else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam!
                        {
                            part.EveryoneMask  = item.EveryOnePermissions;
                            part.NextOwnerMask = item.NextPermissions;

                            part.GroupMask = 0; // DO NOT propagate here
                        }
                    }

                    rootPart.TrimPermissions();

                    if (!attachment)
                    {
                        if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
                        {
                            group.ClearPartAttachmentData();
                        }

                        // Fire on_rez
                        group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0);
                        rootPart.ParentGroup.ResumeScripts();

                        rootPart.ScheduleFullUpdate();
                    }

                    if (!m_Scene.Permissions.BypassPermissions())
                    {
                        if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                        {
                            // If this is done on attachments, no
                            // copy ones will be lost, so avoid it
                            //
                            if (!attachment)
                            {
                                List <UUID> uuids = new List <UUID>();
                                uuids.Add(item.ID);
                                m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
                            }
                        }
                    }

                    return(rootPart.ParentGroup);
                }
            }

            return(null);
        }
コード例 #18
0
        private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
        {
//            m_log.DebugFormat(
//                "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}",
//                (InstantMessageDialog)im.dialog, client.Name,
//                im.fromAgentID, im.fromAgentName, im.toAgentID);

            Scene scene = FindClientScene(client.AgentId);

            if (scene == null) // Something seriously wrong here.
            {
                return;
            }

            if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
            {
                //m_log.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0]));

                if (im.binaryBucket.Length < 17) // Invalid
                {
                    return;
                }

                UUID          recipientID = new UUID(im.toAgentID);
                ScenePresence user        = scene.GetScenePresence(recipientID);
                UUID          copyID;

                // First byte is the asset type
                AssetType assetType = (AssetType)im.binaryBucket[0];

                if (AssetType.Folder == assetType)
                {
                    UUID folderID = new UUID(im.binaryBucket, 1);

                    m_log.DebugFormat(
                        "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory",
                        folderID, new UUID(im.toAgentID));

                    InventoryFolderBase folderCopy
                        = scene.GiveInventoryFolder(client, recipientID, client.AgentId, folderID, UUID.Zero);

                    if (folderCopy == null)
                    {
                        client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false);
                        return;
                    }

                    // The outgoing binary bucket should contain only the byte which signals an asset folder is
                    // being copied and the following bytes for the copied folder's UUID
                    copyID = folderCopy.ID;
                    byte[] copyIDBytes = copyID.GetBytes();
                    im.binaryBucket    = new byte[1 + copyIDBytes.Length];
                    im.binaryBucket[0] = (byte)AssetType.Folder;
                    Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length);

                    if (user != null)
                    {
                        user.ControllingClient.SendBulkUpdateInventory(folderCopy);
                    }

                    // HACK!!
                    // Insert the ID of the copied folder into the IM so that we know which item to move to trash if it
                    // is rejected.
                    // XXX: This is probably a misuse of the session ID slot.
                    im.imSessionID = copyID.Guid;
                }
                else
                {
                    // First byte of the array is probably the item type
                    // Next 16 bytes are the UUID

                    UUID itemID = new UUID(im.binaryBucket, 1);

                    m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} " +
                                      "into agent {1}'s inventory",
                                      itemID, new UUID(im.toAgentID));

                    string            message;
                    InventoryItemBase itemCopy = scene.GiveInventoryItem(new UUID(im.toAgentID), client.AgentId, itemID, out message);

                    if (itemCopy == null)
                    {
                        client.SendAgentAlertMessage(message, false);
                        return;
                    }

                    copyID = itemCopy.ID;
                    Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16);

                    if (user != null)
                    {
                        user.ControllingClient.SendBulkUpdateInventory(itemCopy);
                    }

                    // HACK!!
                    // Insert the ID of the copied item into the IM so that we know which item to move to trash if it
                    // is rejected.
                    // XXX: This is probably a misuse of the session ID slot.
                    im.imSessionID = copyID.Guid;
                }

                im.offline = 0;

                // Send the IM to the recipient. The item is already
                // in their inventory, so it will not be lost if
                // they are offline.
                //
                if (user != null)
                {
                    user.ControllingClient.SendInstantMessage(im);
                    return;
                }
                else
                {
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im, delegate(bool success)
                        {
                            if (!success)
                            {
                                client.SendAlertMessage("User not online. Inventory has been saved");
                            }
                        });
                    }
                }
            }
            else if (im.dialog == (byte)InstantMessageDialog.InventoryAccepted ||
                     im.dialog == (byte)InstantMessageDialog.TaskInventoryAccepted)
            {
                UUID inventoryID             = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
                IInventoryService invService = scene.InventoryService;

                // Special case: folder redirect.
                // RLV uses this
                if (im.dialog == (byte)InstantMessageDialog.TaskInventoryAccepted)
                {
                    InventoryFolderBase folder = invService.GetFolder(client.AgentId, inventoryID);

                    if (folder != null)
                    {
                        if (im.binaryBucket.Length >= 16)
                        {
                            UUID destFolderID = new UUID(im.binaryBucket, 0);
                            if (destFolderID != UUID.Zero)
                            {
                                InventoryFolderBase destFolder = invService.GetFolder(client.AgentId, destFolderID);
                                if (destFolder != null)
                                {
                                    if (folder.ParentID != destFolder.ID)
                                    {
                                        folder.ParentID = destFolder.ID;
                                        invService.MoveFolder(folder);
                                        client.SendBulkUpdateInventory(folder);
                                    }
                                }
                            }
                        }
                    }
                }

                ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
                    }
                }
            }

            // XXX: This code was placed here to try and accomodate RLV which moves given folders named #RLV/~<name>
            // to the requested folder, which in this case is #RLV.  However, it is the viewer that appears to be
            // response from renaming the #RLV/~example folder to ~example.  For some reason this is not yet
            // happening, possibly because we are not sending the correct inventory update messages with the correct
            // transaction IDs
            else if (im.dialog == (byte)InstantMessageDialog.TaskInventoryAccepted)
            {
                UUID destinationFolderID = UUID.Zero;

                if (im.binaryBucket != null && im.binaryBucket.Length >= 16)
                {
                    destinationFolderID = new UUID(im.binaryBucket, 0);
                }

                if (destinationFolderID != UUID.Zero)
                {
                    InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId);
                    IInventoryService   invService        = scene.InventoryService;

                    UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip

                    InventoryItemBase   item    = invService.GetItem(client.AgentId, inventoryID);
                    InventoryFolderBase folder  = null;
                    UUID?previousParentFolderID = null;

                    if (item != null) // It's an item
                    {
                        previousParentFolderID = item.Folder;
                        item.Folder            = destinationFolderID;

                        invService.DeleteItems(item.Owner, new List <UUID>()
                        {
                            item.ID
                        });
                        scene.AddInventoryItem(client, item);
                    }
                    else
                    {
                        folder = invService.GetFolder(client.AgentId, inventoryID);

                        if (folder != null) // It's a folder
                        {
                            previousParentFolderID = folder.ParentID;
                            folder.ParentID        = destinationFolderID;
                            invService.MoveFolder(folder);
                        }
                    }

                    // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
                    if (previousParentFolderID != null)
                    {
                        InventoryFolderBase previousParentFolder = invService.GetFolder(client.AgentId, (UUID)previousParentFolderID);
                        scene.SendInventoryUpdate(client, previousParentFolder, true, true);

                        scene.SendInventoryUpdate(client, destinationFolder, true, true);
                    }
                }
            }
            else if (
                im.dialog == (byte)InstantMessageDialog.InventoryDeclined ||
                im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined)
            {
                // Here, the recipient is local and we can assume that the
                // inventory is loaded. Courtesy of the above bulk update,
                // It will have been pushed to the client, too
                //
                IInventoryService invService = scene.InventoryService;

                InventoryFolderBase trashFolder =
                    invService.GetFolderForType(client.AgentId, FolderType.Trash);

                UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip

                InventoryItemBase   item    = invService.GetItem(client.AgentId, inventoryID);
                InventoryFolderBase folder  = null;
                UUID?previousParentFolderID = null;

                if (item != null && trashFolder != null)
                {
                    previousParentFolderID = item.Folder;
                    item.Folder            = trashFolder.ID;

                    // Diva comment: can't we just update this item???
                    List <UUID> uuids = new List <UUID>();
                    uuids.Add(item.ID);
                    invService.DeleteItems(item.Owner, uuids);
                    scene.AddInventoryItem(client, item);
                }
                else
                {
                    folder = invService.GetFolder(client.AgentId, inventoryID);

                    if (folder != null && trashFolder != null)
                    {
                        previousParentFolderID = folder.ParentID;
                        folder.ParentID        = trashFolder.ID;
                        invService.MoveFolder(folder);
                        client.SendBulkUpdateInventory(folder);
                    }
                }

                if ((null == item && null == folder) || null == trashFolder)
                {
                    string reason = String.Empty;

                    if (trashFolder == null)
                    {
                        reason += " Trash folder not found.";
                    }
                    if (item == null)
                    {
                        reason += " Item not found.";
                    }
                    if (folder == null)
                    {
                        reason += " Folder not found.";
                    }

                    client.SendAgentAlertMessage("Unable to delete " +
                                                 "received inventory" + reason, false);
                }
                // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
                else if (previousParentFolderID != null)
                {
                    InventoryFolderBase previousParentFolder = invService.GetFolder(client.AgentId, (UUID)previousParentFolderID);
                    scene.SendInventoryUpdate(client, previousParentFolder, true, true);

                    scene.SendInventoryUpdate(client, trashFolder, true, true);
                }

                if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined)
                {
                    ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));

                    if (user != null) // Local
                    {
                        user.ControllingClient.SendInstantMessage(im);
                    }
                    else
                    {
                        if (m_TransferModule != null)
                        {
                            m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
                        }
                    }
                }
            }
        }
コード例 #19
0
        private void TaskInventoryOfferAccept(IClientAPI client, Scene scene, GridInstantMessage im)
        {
            InventoryFolderBase folder = null;
            InventoryItemBase item = null;

            // The inventory item/folder, back from it's trip
            UUID inventoryEntityID = new UUID(im.imSessionID);

            // Here, the recipient is local and we can assume that the inventory is loaded.
            // Courtesy of the above bulk update, it will have been pushed to the client, too.
            CachedUserInfo userInfo = scene.CommsManager.UserService.GetUserDetails(client.AgentId);
            if (userInfo != null)
            {
                // Is it a folder or an item?
                if (userInfo.QueryItem(inventoryEntityID))
                {   // It's an item.
                    item = userInfo.FindItem(inventoryEntityID);
                    if (item == null)
                    {
                        client.SendAgentAlertMessage("Unable to accept received inventory: item/folder not found.", false);
                        return;
                    }
                    client.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {   // It's a folder.
                    folder = userInfo.GetFolder(inventoryEntityID);
                    if (folder != null)
                    {
                        client.SendBulkUpdateInventory(folder);
                        // If we don't send the descendents, viewer shows "Loading..." on the trash item.
                        userInfo.SendInventoryDecendents(client, folder.ID, false, true);
                    }
                }
            }

            //            RelayInventoryOfferIM(scene, im); // we don't need to notify a box that the user accepted this
        }
コード例 #20
0
        private void TaskInventoryOfferDecline(IClientAPI client, Scene scene, GridInstantMessage im)
        {
            // The inventory item/folder, back from it's trip
            UUID inventoryEntityID = new UUID(im.imSessionID);

            // Here, the recipient is local and we can assume that the inventory is loaded.
            // Courtesy of the above bulk update, it will have been pushed to the client, too.
            CachedUserInfo userInfo = scene.CommsManager.UserService.GetUserDetails(client.AgentId);
            if (userInfo != null)
            {
                InventoryFolderBase trashFolder = userInfo.FindFolderForType((int)FolderType.Trash);
                if (null == trashFolder)
                {
                    client.SendAgentAlertMessage("Unable to decline received inventory: Trash folder not found.", false);
                    return;
                }

                // Is it a folder or an item?
                if (userInfo.QueryItem(inventoryEntityID))
                {   // It's an item.
                    InventoryItemBase item = userInfo.FindItem(inventoryEntityID);
                    if (item == null)
                    {
                        client.SendAgentAlertMessage("Unable to decline received inventory: item/folder not found.", false);
                        return;
                    }
                    userInfo.MoveItemToTrash(item, trashFolder);
                    scene.AddInventoryItem(client, item);
                    client.SendInventoryItemCreateUpdate(item, 0);
                }
                else
                {   // It's a folder.
                    InventoryFolderBase folder = userInfo.GetFolderAttributes(inventoryEntityID);
                    userInfo.MoveFolder(inventoryEntityID, trashFolder.ID);
                    folder = userInfo.GetFolder(inventoryEntityID);
                    if (folder != null)
                    {
                        client.SendBulkUpdateInventory(folder);
                        // If we don't send the descendents, viewer shows "Loading..." on the trash item.
                        userInfo.SendInventoryDecendents(client, folder.ID, false, true);
                    }
                }
            }
        }
コード例 #21
0
        /// <summary>
        /// Hot patches inventory items that may have the wrong flags set and thus will not wear in the viewer
        /// </summary>
        /// <param name="baseItem"></param>
        /// <param name="uinfo"></param>
        /// <param name="clientView"></param>
        /// <returns></returns>
        private bool FixupItemFlagsOnWearableTypeMismatch(InventoryItemBase baseItem, CachedUserInfo uinfo, IClientAPI clientView)
        {
            if (baseItem.InvType != (int)InventoryType.Wearable) return false;

            //download the asset and extract the type. make sure the type matches the lower byte
            //of the inventory item flags

            AssetBase asset;
            try
            {
                asset = CommsManager.AssetCache.GetAsset(baseItem.AssetID, AssetRequestInfo.InternalRequest());
                if (asset == null) return false;    // not found
            }
            catch
            {
                //we couldnt get the asset, cant apply fixups
                return false;
            }

            //do we have the correct asset type to parse?
            if (asset.Type != (sbyte)AssetType.Clothing && asset.Type != (sbyte)AssetType.Bodypart) return false;

            try
            {
                uint wearableTypeInAsset = this.ParseWearableAndGetType(asset);

                //do they match?
                if (wearableTypeInAsset != (baseItem.Flags & 0xFF))
                {
                    //no. we need a fixup
                    m_log.ErrorFormat("[APPEARANCE]: Hotpatching item {0} due to flags mismatch: Got {1}, should be {2}",
                        baseItem.ID, baseItem.Flags & 0xFF, wearableTypeInAsset);

                    //remove the first byte
                    baseItem.Flags = baseItem.Flags & 0xFFFFFF00;
                    //combine our type
                    baseItem.Flags = baseItem.Flags | (wearableTypeInAsset & 0xFF);

                    //save back the inventory item with updated flags
                    uinfo.UpdateItem(baseItem);

                    //inform viewer
                    clientView.SendBulkUpdateInventory(baseItem);

                    return true;
                }

                return false;
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[APPEARANCE]: Error when attempting to parse wearable and update item for Flags hotpatch {0}", e);

                //couldnt parse wearable
                return false;
            }
        }
コード例 #22
0
        private List<SceneObjectGroup> RezMultipleObjectsFromInventory(XmlNodeList nodes, UUID itemId, IClientAPI remoteClient, bool attachment, Vector3 pos, bool RezSelected,
            InventoryItemBase item, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, Vector3 RayEnd, Vector3 RayStart, byte bRayEndIsIntersection)
        {
            Vector3 OldMiddlePos = Vector3.Zero;
            List<SceneObjectGroup> NewGroup = new List<SceneObjectGroup>();

            foreach (System.Xml.XmlNode aPrimNode in nodes)
            {
                if (aPrimNode.OuterXml.StartsWith("<middle>"))
                {
                    string Position = aPrimNode.OuterXml.Remove(0, 13);
                    Position = Position.Remove(Position.Length - 16, 16);
                    string[] XYZ = Position.Split(' ');
                    OldMiddlePos = new Vector3(float.Parse(XYZ[0]), float.Parse(XYZ[1]), float.Parse(XYZ[2]));
                    continue;
                }
                SceneObjectGroup group
                       = SceneObjectSerializer.FromOriginalXmlFormat(aPrimNode.OuterXml, m_Scene);
                if (group == null)
                    continue;
                NewGroup.Add(group);

                string reason; 
                if (!m_Scene.Permissions.CanRezObject(
                    group.ChildrenList.Count, remoteClient.AgentId, pos, out reason)
                    && !attachment)
                {
                    // The client operates in no fail mode. It will
                    // have already removed the item from the folder
                    // if it's no copy.
                    // Put it back if it's not an attachment
                    //
                    if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
                        remoteClient.SendBulkUpdateInventory(item);
                    return null;
                }

                group.ResetIDs(true);

                if (attachment)
                {
                    group.RootPart.Flags |= PrimFlags.Phantom;
                    group.RootPart.IsAttachment = true;
                }
                if (RezSelected)
                    group.RootPart.AddFlag(PrimFlags.CreateSelected);
                // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
                // we'll be doing that later on.  Scheduling more than one full update during the attachment
                // process causes some clients to fail to display the attachment properly.
                m_Scene.AddNewSceneObject(group, true, false);

                //  m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
                // 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)
                {
                    float offsetHeight = 0;
                    pos = m_Scene.GetNewRezLocation(
                        RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                        BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
                    pos.Z += offsetHeight;
                    //group.AbsolutePosition = pos;
                    //   m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);

                }
                else
                {
                    group.SetFromItemID(item.ID);
                }

                SceneObjectPart rootPart = null;
                try
                {
                    rootPart = group.GetChildPart(group.UUID);
                }
                catch (NullReferenceException)
                {
                    string isAttachment = "";

                    if (attachment)
                        isAttachment = " Object was an attachment";

                    m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + item.ID + " object has no rootpart." + isAttachment);
                }

                // Since renaming the item in the inventory does not affect the name stored
                // in the serialization, transfer the correct name from the inventory to the
                // object itself before we rez.
                rootPart.Name = item.Name;
                rootPart.Description = item.Description;

                List<SceneObjectPart> partList = new List<SceneObjectPart>(group.ChildrenList);

                group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
                if (rootPart.OwnerID != item.Owner)
                {
                    //Need to kill the for sale here
                    rootPart.ObjectSaleType = 0;
                    rootPart.SalePrice = 10;

                    if (m_Scene.Permissions.PropagatePermissions())
                    {
                        if ((item.CurrentPermissions & 8) != 0)
                        {
                            foreach (SceneObjectPart part in partList)
                            {
                                part.EveryoneMask = item.EveryOnePermissions;
                                part.NextOwnerMask = item.NextPermissions;
                                part.GroupMask = 0; // DO NOT propagate here
                            }
                        }

                        group.ApplyNextOwnerPermissions();
                    }
                }

                foreach (SceneObjectPart part in partList)
                {
                    if (part.OwnerID != item.Owner)
                    {
                        part.LastOwnerID = part.OwnerID;
                        part.OwnerID = item.Owner;
                        part.Inventory.ChangeInventoryOwner(item.Owner);
                    }
                    else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam!
                    {
                        part.EveryoneMask = item.EveryOnePermissions;
                        part.NextOwnerMask = item.NextPermissions;

                        part.GroupMask = 0; // DO NOT propagate here
                    }
                }

                rootPart.TrimPermissions();

                if (!attachment)
                {
                    if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
                    {
                        group.ClearPartAttachmentData();
                    }

                    // Fire on_rez
                    group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0, UUID.Zero);
                    rootPart.ParentGroup.ResumeScripts();
                }

                if (!m_Scene.Permissions.BypassPermissions())
                {
                    if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                    {
                        // If this is done on attachments, no
                        // copy ones will be lost, so avoid it
                        //
                        if (!attachment)
                        {
                            List<UUID> uuids = new List<UUID>();
                            uuids.Add(item.ID);
                            m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
                        }
                    }
                }
            }
            foreach (SceneObjectGroup group in NewGroup)
            {
                if (!attachment && OldMiddlePos != Vector3.Zero)
                {
                    Vector3 NewPosOffset = Vector3.Zero;
                    NewPosOffset.X = group.AbsolutePosition.X - OldMiddlePos.X;
                    NewPosOffset.Y = group.AbsolutePosition.Y - OldMiddlePos.Y;
                    NewPosOffset.Z = group.AbsolutePosition.Z - OldMiddlePos.Z;
                    group.AbsolutePosition = pos + NewPosOffset;
                }
                group.ScheduleGroupForFullUpdate(PrimUpdateFlags.FullUpdate);
            }
            return NewGroup;
        }
コード例 #23
0
        /// <summary>
        /// Rez an object into the scene from the user's inventory
        /// </summary>
        /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
        /// things to the scene.  The caller should be doing that, I think.
        /// <param name="remoteClient"></param>
        /// <param name="itemID"></param>
        /// <param name="RayEnd"></param>
        /// <param name="RayStart"></param>
        /// <param name="RayTargetID"></param>
        /// <param name="BypassRayCast"></param>
        /// <param name="RayEndIsIntersection"></param>
        /// <param name="RezSelected"></param>
        /// <param name="RemoveItem"></param>
        /// <param name="fromTaskID"></param>
        /// <param name="attachment"></param>
        /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
        public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                    UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                    bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
        {
            // 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 = m_Scene.GetNewRezLocation(
                      RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                      BypassRayCast, bRayEndIsIntersection, true, scale, false);

            // Rez object
            InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
            item = m_Scene.InventoryService.GetItem(item);

            if (item != null)
            {
                AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());

                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 (!m_Scene.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);
                    SceneObjectGroup group
                        = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData);

                    if (!m_Scene.Permissions.CanRezObject(
                        group.Children.Count, remoteClient.AgentId, pos)
                        && !attachment)
                    {
                        // The client operates in no fail mode. It will
                        // have already removed the item from the folder
                        // if it's no copy.
                        // Put it back if it's not an attachment
                        //
                        if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
                            remoteClient.SendBulkUpdateInventory(item);
                        return null;
                    }

                    group.ResetIDs();

                    if (attachment)
                    {
                        group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom;
                        group.RootPart.IsAttachment = true;
                    }

                    // For attachments, we must make sure that only a single object update occurs after we've finished
                    // all the necessary operations.
                    m_Scene.AddNewSceneObject(group, true, false);

                    //  m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
                    // 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)
                    {
                        group.ScheduleGroupForFullUpdate();
                        
                        float offsetHeight = 0;
                        pos = m_Scene.GetNewRezLocation(
                            RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                            BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
                        pos.Z += offsetHeight;
                        group.AbsolutePosition = pos;
                        //   m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);

                    }
                    else
                    {
                        group.SetFromItemID(itemID);
                    }

                    SceneObjectPart rootPart = null;
                    try
                    {
                        rootPart = group.GetChildPart(group.UUID);
                    }
                    catch (NullReferenceException)
                    {
                        string isAttachment = "";

                        if (attachment)
                            isAttachment = " Object was an attachment";

                        m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
                    }

                    // Since renaming the item in the inventory does not affect the name stored
                    // in the serialization, transfer the correct name from the inventory to the
                    // object itself before we rez.
                    rootPart.Name = item.Name;
                    rootPart.Description = item.Description;

                    List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);

                    group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
                    if (rootPart.OwnerID != item.Owner)
                    {
                        //Need to kill the for sale here
                        rootPart.ObjectSaleType = 0;
                        rootPart.SalePrice = 10;

                        if (m_Scene.Permissions.PropagatePermissions())
                        {
                            if ((item.CurrentPermissions & 8) != 0)
                            {
                                foreach (SceneObjectPart part in partList)
                                {
                                    part.EveryoneMask = item.EveryOnePermissions;
                                    part.NextOwnerMask = item.NextPermissions;
                                    part.GroupMask = 0; // DO NOT propagate here
                                }
                            }
                            
                            group.ApplyNextOwnerPermissions();
                        }
                    }

                    foreach (SceneObjectPart part in partList)
                    {
                        if (part.OwnerID != item.Owner)
                        {
                            part.LastOwnerID = part.OwnerID;
                            part.OwnerID = item.Owner;
                            part.Inventory.ChangeInventoryOwner(item.Owner);
                        }
                        else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam!
                        {
                            part.EveryoneMask = item.EveryOnePermissions;
                            part.NextOwnerMask = item.NextPermissions;

                            part.GroupMask = 0; // DO NOT propagate here
                        }
                    }

                    rootPart.TrimPermissions();

                    if (!attachment)
                    {
                        if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
                        {
                            group.ClearPartAttachmentData();
                        }
                        
                        // Fire on_rez
                        group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0);
                        rootPart.ParentGroup.ResumeScripts();

                        rootPart.ScheduleFullUpdate();
                    }

                    if (!m_Scene.Permissions.BypassPermissions())
                    {
                        if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                        {
                            // If this is done on attachments, no
                            // copy ones will be lost, so avoid it
                            //
                            if (!attachment)
                            {
                                List<UUID> uuids = new List<UUID>();
                                uuids.Add(item.ID);
                                m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
                            }
                        }
                    }

                    return rootPart.ParentGroup;
                }
            }

            return null;
        }
コード例 #24
0
ファイル: BunchOfCaps.cs プロジェクト: p07r0457/opensim
        /// <summary>
        /// Called by the CopyInventoryFromNotecard caps handler.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="path"></param>
        /// <param name="param"></param>
        public string CopyInventoryFromNotecard(string request, string path, string param,
                                                IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
        {
            Hashtable response = new Hashtable();

            response["int_response_code"]   = 404;
            response["content_type"]        = "text/plain";
            response["keepalive"]           = false;
            response["str_response_string"] = "";

            try
            {
                OSDMap content    = (OSDMap)OSDParser.DeserializeLLSDXml(request);
                UUID   objectID   = content["object-id"].AsUUID();
                UUID   notecardID = content["notecard-id"].AsUUID();
                UUID   folderID   = content["folder-id"].AsUUID();
                UUID   itemID     = content["item-id"].AsUUID();

                //  m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, FolderID:{0}, ItemID:{1}, NotecardID:{2}, ObjectID:{3}", folderID, itemID, notecardID, objectID);

                if (objectID != UUID.Zero)
                {
                    SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
                    if (part != null)
                    {
//                        TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
                        if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
                        {
                            return(LLSDHelpers.SerialiseLLSDReply(response));
                        }
                    }
                }

                InventoryItemBase item     = null;
                InventoryItemBase copyItem = null;
                IClientAPI        client   = null;

                m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
                item = m_Scene.InventoryService.GetItem(new InventoryItemBase(itemID));
                if (item != null)
                {
                    copyItem = m_Scene.GiveInventoryItem(m_HostCapsObj.AgentID, item.Owner, itemID, folderID);
                    if (copyItem != null && client != null)
                    {
                        m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0}, FolderID:{1}", copyItem.ID, copyItem.Folder);
                        client.SendBulkUpdateInventory(copyItem);
                    }
                }
                else
                {
                    m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard - Failed to retrieve item {0} from notecard {1}", itemID, notecardID);
                    if (client != null)
                    {
                        client.SendAlertMessage("Failed to retrieve item");
                    }
                }
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard : {0}", e.ToString());
            }

            response["int_response_code"] = 200;
            return(LLSDHelpers.SerialiseLLSDReply(response));
        }
コード例 #25
0
        private List<ISceneEntity> RezMultipleObjectsFromInventory(XmlNodeList nodes, UUID itemId,
            IClientAPI remoteClient, Vector3 pos,
            bool RezSelected,
            InventoryItemBase item, UUID RayTargetID,
            byte BypassRayCast, bool RayEndIsIntersection,
            Vector3 RayEnd, Vector3 RayStart,
            byte bRayEndIsIntersection)
        {
            Vector3 OldMiddlePos = Vector3.Zero;
            List<ISceneEntity> NewGroup = new List<ISceneEntity>();

            foreach (XmlNode aPrimNode in nodes)
            {
                if (aPrimNode.OuterXml.StartsWith("<middle>"))
                {
                    string Position = aPrimNode.OuterXml.Remove(0, 13);
                    Position = Position.Remove(Position.Length - 16, 16);
                    string[] XYZ = Position.Split(' ');
                    OldMiddlePos = new Vector3(float.Parse(XYZ[0]), float.Parse(XYZ[1]), float.Parse(XYZ[2]));
                    continue;
                }
                ISceneEntity group
                    = SceneEntitySerializer.SceneObjectSerializer.FromOriginalXmlFormat(aPrimNode.OuterXml, m_scene);
                if (group == null)
                    return null;

                group.IsDeleted = false;
                foreach (ISceneChildEntity part in group.ChildrenEntities())
                {
                    part.IsLoading = false;
                }
                NewGroup.Add(group);

                string reason;
                if (!m_scene.Permissions.CanRezObject(
                    group.ChildrenEntities().Count, remoteClient.AgentId, pos, out reason))
                {
                    // The client operates in no fail mode. It will
                    // have already removed the item from the folder
                    // if it's no copy.
                    // Put it back if it's not an attachment
                    //
                    if (((item.CurrentPermissions & (uint) PermissionMask.Copy) == 0))
                        remoteClient.SendBulkUpdateInventory(item);
                    return null;
                }

                if (RezSelected)
                    group.RootChild.AddFlag(PrimFlags.CreateSelected);
                // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
                // we'll be doing that later on.  Scheduling more than one full update during the attachment
                // process causes some clients to fail to display the attachment properly.
                m_scene.SceneGraph.AddPrimToScene(group);

                //  MainConsole.Instance.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
                // if attachment we set it's asset id so object updates can reflect that
                // if not, we set it's position in world.
                float offsetHeight = 0;
                pos = m_scene.SceneGraph.GetNewRezLocation(
                    RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                    BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
                pos.Z += offsetHeight;
                //group.AbsolutePosition = pos;
                //   MainConsole.Instance.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);

                ISceneChildEntity rootPart = group.GetChildPart(group.UUID);

                // Since renaming the item in the inventory does not affect the name stored
                // in the serialization, transfer the correct name from the inventory to the
                // object itself before we rez.
                if (NewGroup.Count == 1)
                {
                    //Only do this to the first object, as it is the only one that will need to be renamed
                    rootPart.Name = item.Name;
                    rootPart.Description = item.Description;
                }

                List<ISceneChildEntity> partList = group.ChildrenEntities();

                group.SetGroup(remoteClient.ActiveGroupId, remoteClient.AgentId, false);
                item.Owner = remoteClient.AgentId;
                if (rootPart.OwnerID != item.Owner)
                {
                    //Need to kill the for sale here
                    rootPart.ObjectSaleType = 0;
                    rootPart.SalePrice = 10;

                    if (m_scene.Permissions.PropagatePermissions())
                    {
                        if ((item.CurrentPermissions & 8) != 0)
                        {
                            foreach (ISceneChildEntity part in partList)
                            {
                                part.EveryoneMask = item.EveryOnePermissions;
                                part.NextOwnerMask = item.NextPermissions;
                                part.GroupMask = 0; // DO NOT propagate here
                            }
                        }

                        group.ApplyNextOwnerPermissions();
                    }
                }

                foreach (ISceneChildEntity part in partList)
                {
                    if (part.OwnerID != item.Owner)
                    {
                        part.LastOwnerID = part.OwnerID;
                        part.OwnerID = item.Owner;
                        part.Inventory.ChangeInventoryOwner(item.Owner);
                    }
                    else if ((item.CurrentPermissions & 8) != 0) // Slam!
                    {
                        part.EveryoneMask = item.EveryOnePermissions;
                        part.NextOwnerMask = item.NextPermissions;

                        part.GroupMask = 0; // DO NOT propagate here
                    }
                }

                rootPart.TrimPermissions();

                if (group.RootChild.Shape.PCode == (byte) PCode.Prim)
                    group.ClearPartAttachmentData();

                // Fire on_rez
                group.CreateScriptInstances(0, true, StateSource.NewRez, UUID.Zero, false);

                if (!m_scene.Permissions.BypassPermissions())
                {
                    if ((item.CurrentPermissions & (uint) PermissionMask.Copy) == 0)
                    {
                        // If this is done on attachments, no
                        // copy ones will be lost, so avoid it
                        //
                        List<UUID> uuids = new List<UUID> {item.ID};
                        m_scene.InventoryService.DeleteItems(item.Owner, uuids);
                    }
                }
            }
            foreach (ISceneEntity group in NewGroup)
            {
                if (OldMiddlePos != Vector3.Zero)
                {
                    Vector3 NewPosOffset = Vector3.Zero;
                    NewPosOffset.X = group.AbsolutePosition.X - OldMiddlePos.X;
                    NewPosOffset.Y = group.AbsolutePosition.Y - OldMiddlePos.Y;
                    NewPosOffset.Z = group.AbsolutePosition.Z - OldMiddlePos.Z;
                    group.AbsolutePosition = pos + NewPosOffset;
                }
                group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate);
            }
            return NewGroup;
        }
コード例 #26
0
        private UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID, bool isGod)
        {
            IUserAccountService userv = m_Scenes[0].UserAccountService;

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

            UserAccount info = userv.GetUserAccount(UUID.Zero, creatorID);

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

            IInventoryService inv = m_Scenes[0].InventoryService;

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

            if (folderID == UUID.Zero)
            {
                InventoryFolderBase folder = inv.GetFolderForType(userID,
                                                                  AssetType.CallingCard);

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

                folderID = folder.ID;
            }

            m_log.DebugFormat("[XCALLINGCARD]: Creating calling card for {0} in inventory of {1}", info.Name, userID);

            InventoryItemBase item = new InventoryItemBase();

            item.AssetID         = UUID.Zero;
            item.AssetType       = (int)AssetType.CallingCard;
            item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
            if (isGod)
            {
                item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Move);
            }

            item.EveryOnePermissions = (uint)PermissionMask.None;
            item.CurrentPermissions  = item.BasePermissions;
            item.NextPermissions     = (uint)(PermissionMask.Copy | PermissionMask.Modify);

            item.ID         = UUID.Random();
            item.CreatorId  = creatorID.ToString();
            item.Owner      = userID;
            item.GroupID    = UUID.Zero;
            item.GroupOwned = false;
            item.Folder     = folderID;

            item.CreationDate = Util.UnixTimeSinceEpoch();
            item.InvType      = (int)InventoryType.CallingCard;
            item.Flags        = 0;

            item.Name        = info.Name;
            item.Description = "";

            item.SalePrice = 10;
            item.SaleType  = (byte)SaleType.Not;

            inv.AddItem(item);

            IClientAPI client = FindClientObject(userID);

            if (client != null)
            {
                client.SendBulkUpdateInventory(item);
            }

            return(item.ID);
        }
コード例 #27
0
        /// <summary>
        /// Rez an object into the scene from the user's inventory
        /// </summary>
        /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
        /// things to the scene.  The caller should be doing that, I think.
        /// <param name="remoteClient"></param>
        /// <param name="itemID"></param>
        /// <param name="RayEnd"></param>
        /// <param name="RayStart"></param>
        /// <param name="RayTargetID"></param>
        /// <param name="BypassRayCast"></param>
        /// <param name="RayEndIsIntersection"></param>
        /// <param name="RezSelected"></param>
        /// <param name="RemoveItem"></param>
        /// <param name="fromTaskID"></param>
        /// <param name="attachment"></param>
        /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
        public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                                  UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                                  bool RezSelected, bool RemoveItem, UUID fromTaskID)
        {
            // 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 = m_scene.SceneGraph.GetNewRezLocation(
                RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                BypassRayCast, bRayEndIsIntersection, true, scale, false);

            System.Xml.XmlDocument doc;
            InventoryItemBase      item = new InventoryItemBase(itemID, remoteClient.AgentId);

            item = m_scene.InventoryService.GetItem(item);
            SceneObjectGroup group = CreateObjectFromInventory(item, remoteClient, itemID, out doc);

            if (doc == null)
            {
                //No asset, check task inventory
                IEntity e;
                m_scene.SceneGraph.TryGetEntity(fromTaskID, out e);
                if (e != null && e is SceneObjectGroup)
                {
                    SceneObjectGroup  grp      = (SceneObjectGroup)e;
                    TaskInventoryItem taskItem = grp.RootPart.Inventory.GetInventoryItem(itemID);
                    item = new InventoryItemBase();

                    item.ID          = UUID.Random();
                    item.CreatorId   = taskItem.CreatorID.ToString();
                    item.Owner       = remoteClient.AgentId;
                    item.AssetID     = taskItem.AssetID;
                    item.Description = taskItem.Description;
                    item.Name        = taskItem.Name;
                    item.AssetType   = taskItem.Type;
                    item.InvType     = taskItem.InvType;
                    item.Flags       = taskItem.Flags;
                    item.SalePrice   = taskItem.SalePrice;
                    item.SaleType    = taskItem.SaleType;

                    if (m_scene.Permissions.PropagatePermissions())
                    {
                        item.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
                        if (taskItem.InvType == (int)InventoryType.Object)
                        {
                            item.CurrentPermissions = item.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move));
                        }
                        else
                        {
                            item.CurrentPermissions = item.BasePermissions & taskItem.CurrentPermissions;
                        }

                        item.CurrentPermissions |= 16; // Slam
                        item.NextPermissions     = taskItem.NextPermissions;
                        item.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
                        item.GroupPermissions    = taskItem.GroupPermissions & taskItem.NextPermissions;
                    }
                    else
                    {
                        item.BasePermissions     = taskItem.BasePermissions;
                        item.CurrentPermissions  = taskItem.CurrentPermissions;
                        item.NextPermissions     = taskItem.NextPermissions;
                        item.EveryOnePermissions = taskItem.EveryonePermissions;
                        item.GroupPermissions    = taskItem.GroupPermissions;
                    }
                    group = CreateObjectFromInventory(item, remoteClient, itemID, out doc);
                }
                else
                {
                    return(null);
                }
            }
            if (group == null && doc.FirstChild.OuterXml.StartsWith("<groups>"))
            {
                List <SceneObjectGroup> Groups = RezMultipleObjectsFromInventory(doc.FirstChild.ChildNodes, itemID, remoteClient, pos, RezSelected, item, RayTargetID, BypassRayCast, RayEndIsIntersection, RayEnd, RayStart, bRayEndIsIntersection);
                if (Groups.Count != 0)
                {
                    return(Groups[0]);
                }
                else
                {
                    return(null);
                }
            }

            string reason;

            if (!m_scene.Permissions.CanRezObject(
                    group.ChildrenList.Count, remoteClient.AgentId, pos, out reason))
            {
                // The client operates in no fail mode. It will
                // have already removed the item from the folder
                // if it's no copy.
                // Put it back if it's not an attachment
                //
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                {
                    remoteClient.SendBulkUpdateInventory(item);
                }
                remoteClient.SendAlertMessage("You do not have permission to rez objects here.");
                return(null);
            }

            if (RezSelected)
            {
                group.RootPart.AddFlag(PrimFlags.CreateSelected);
            }
            // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
            // we'll be doing that later on.  Scheduling more than one full update during the attachment
            // process causes some clients to fail to display the attachment properly.
            m_scene.SceneGraph.AddPrimToScene(group);

            //  m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
            //  Set it's position in world.
            float offsetHeight = 0;

            pos = m_scene.SceneGraph.GetNewRezLocation(
                RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
            pos.Z += offsetHeight;
            group.AbsolutePosition = pos;
            //   m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);

            SceneObjectPart rootPart = (SceneObjectPart)group.GetChildPart(group.UUID);

            if (rootPart == null)
            {
                m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart.");
                return(null);
            }

            // Since renaming the item in the inventory does not affect the name stored
            // in the serialization, transfer the correct name from the inventory to the
            // object itself before we rez.
            rootPart.Name        = item.Name;
            rootPart.Description = item.Description;

            List <SceneObjectPart> partList = new List <SceneObjectPart> (group.ChildrenList);

            group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
            item.Owner = remoteClient.AgentId;
            if (rootPart.OwnerID != item.Owner)
            {
                //Need to kill the for sale here
                rootPart.ObjectSaleType = 0;
                rootPart.SalePrice      = 10;

                if (m_scene.Permissions.PropagatePermissions())
                {
                    if ((item.CurrentPermissions & 8) != 0)
                    {
                        foreach (SceneObjectPart part in partList)
                        {
                            part.EveryoneMask  = item.EveryOnePermissions;
                            part.NextOwnerMask = item.NextPermissions;
                            part.GroupMask     = 0; // DO NOT propagate here
                        }
                    }

                    group.ApplyNextOwnerPermissions();
                }
            }

            foreach (SceneObjectPart part in partList)
            {
                if (part.OwnerID != item.Owner)
                {
                    part.LastOwnerID = part.OwnerID;
                    part.OwnerID     = item.Owner;
                    part.Inventory.ChangeInventoryOwner(item.Owner);
                }
                else if ((item.CurrentPermissions & 8) != 0) // Slam!
                {
                    part.EveryoneMask  = item.EveryOnePermissions;
                    part.NextOwnerMask = item.NextPermissions;

                    part.GroupMask = 0; // DO NOT propagate here
                }
            }

            rootPart.TrimPermissions();

            if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
            {
                group.ClearPartAttachmentData();
            }

            // Fire on_rez
            group.CreateScriptInstances(0, true, 0, UUID.Zero);
            rootPart.ParentGroup.ResumeScripts();

            group.ScheduleGroupUpdate(PrimUpdateFlags.FullUpdate);
            if (!m_scene.Permissions.BypassPermissions())
            {
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                {
                    List <UUID> uuids = new List <UUID> ();
                    uuids.Add(item.ID);
                    m_scene.InventoryService.DeleteItems(item.Owner, uuids);
                }
            }
            return(group);
        }
コード例 #28
0
        /// <summary>
        /// Do pre-rez processing when the object comes from an item.
        /// </summary>
        /// <param name="remoteClient"></param>
        /// <param name="item"></param>
        /// <param name="objlist"></param>
        /// <param name="pos"></param>
        /// <param name="veclist">
        /// List of vector position adjustments for a coalesced objects.  For ordinary objects
        /// this list will contain just Vector3.Zero.  The order of adjustments must match the order of objlist
        /// </param>
        /// <param name="isAttachment"></param>
        /// <returns>true if we can processed with rezzing, false if we need to abort</returns>
        private bool DoPreRezWhenFromItem(
            IClientAPI remoteClient, InventoryItemBase item, List <SceneObjectGroup> objlist,
            Vector3 pos, List <Vector3> veclist, bool isAttachment)
        {
            UUID fromUserInventoryItemId = 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 (!m_Scene.Permissions.BypassPermissions())
            {
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy)
                    == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                {
                    fromUserInventoryItemId = item.ID;
                }
            }
            else
            {
                if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                {
                    // Brave new fullperm world
                    fromUserInventoryItemId = item.ID;
                }
            }

            for (int i = 0; i < objlist.Count; i++)
            {
                SceneObjectGroup g = objlist[i];

                if (!m_Scene.Permissions.CanRezObject(
                        g.PrimCount, remoteClient.AgentId, pos + veclist[i]) &&
                    !isAttachment)
                {
                    // The client operates in no fail mode. It will
                    // have already removed the item from the folder
                    // if it's no copy.
                    // Put it back if it's not an attachment
                    //
                    if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
                    {
                        remoteClient.SendBulkUpdateInventory(item);
                    }

                    ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
                    remoteClient.SendAlertMessage(string.Format(
                                                      "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
                                                      item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name));

                    return(false);
                }
            }

            for (int i = 0; i < objlist.Count; i++)
            {
                SceneObjectGroup so       = objlist[i];
                SceneObjectPart  rootPart = so.RootPart;

                // Since renaming the item in the inventory does not
                // affect the name stored in the serialization, transfer
                // the correct name from the inventory to the
                // object itself before we rez.
                //
                // Only do these for the first object if we are rezzing a coalescence.
                if (i == 0)
                {
                    rootPart.Name           = item.Name;
                    rootPart.Description    = item.Description;
                    rootPart.ObjectSaleType = item.SaleType;
                    rootPart.SalePrice      = item.SalePrice;
                }

                so.FromFolderID = item.Folder;

//                m_log.DebugFormat(
//                    "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
//                    rootPart.OwnerID, item.Owner, item.CurrentPermissions);

                if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & SceneObjectGroup.SLAM) != 0)
                {
                    //Need to kill the for sale here
                    rootPart.ObjectSaleType = 0;
                    rootPart.SalePrice      = 10;
                }

                foreach (SceneObjectPart part in so.Parts)
                {
                    part.FromUserInventoryItemID = fromUserInventoryItemId;
                    part.ApplyPermissionsOnRez(item, true, m_Scene);
                }

                rootPart.TrimPermissions();

                if (isAttachment)
                {
                    so.FromItemID = item.ID;
                }
            }

            return(true);
        }
コード例 #29
0
        /// <summary>
        /// Update an item which is either already in the client's inventory or is within
        /// a transaction
        /// </summary>
        /// <param name="remoteClient"></param>
        /// <param name="transactionID">The transaction ID.  If this is UUID.Zero we will
        /// assume that we are not in a transaction</param>
        /// <param name="itemID">The ID of the updated item</param>
        /// <param name="name">The name of the updated item</param>
        /// <param name="description">The description of the updated item</param>
        /// <param name="nextOwnerMask">The permissions of the updated item</param>
/*        public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
                                             UUID itemID, string name, string description,
                                             uint nextOwnerMask)*/
        public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
                                             UUID itemID, InventoryItemBase itemUpd)
        {
//            m_log.DebugFormat(
//                "[USER INVENTORY]: Updating asset for item {0} {1}, transaction ID {2} for {3}",
//                itemID, itemUpd.Name, transactionID, remoteClient.Name);

            // This one will let people set next perms on items in agent
            // inventory. Rut-Roh. Whatever. Make this secure. Yeah.
            //
            // Passing something to another avatar or a an object will already
            InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
            item = InventoryService.GetItem(item);

            if (item != null)
            {
                if (item.Owner != remoteClient.AgentId)
                    return;

                item.Name = itemUpd.Name;
                item.Description = itemUpd.Description;

//                    m_log.DebugFormat(
//                        "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}",
//                        itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
//                        item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);

                bool sendUpdate = false;

                if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid
                {
                    // Create a set of base permissions that will not include export if the user
                    // is not allowed to change the export flag.
                    bool denyExportChange = false;

//                    m_log.DebugFormat("[XXX]: B: {0} O: {1} E: {2}", itemUpd.BasePermissions, itemUpd.CurrentPermissions, itemUpd.EveryOnePermissions);

                    // If the user is not the creator or doesn't have "E" in both "B" and "O", deny setting export
                    if ((item.BasePermissions & (uint)(PermissionMask.All | PermissionMask.Export)) != (uint)(PermissionMask.All | PermissionMask.Export) || (item.CurrentPermissions & (uint)PermissionMask.Export) == 0 || item.CreatorIdAsUuid != item.Owner)
                        denyExportChange = true;

//                    m_log.DebugFormat("[XXX]: Deny Export Update {0}", denyExportChange);

                    // If it is already set, force it set and also force full perm
                    // else prevent setting it. It can and should never be set unless
                    // set in base, so the condition above is valid
                    if (denyExportChange)
                    {
                        // If we are not allowed to change it, then force it to the
                        // original item's setting and if it was on, also force full perm
                        if ((item.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
                        {
                            itemUpd.NextPermissions = (uint)(PermissionMask.All);
                            itemUpd.EveryOnePermissions |= (uint)PermissionMask.Export;
                        }
                        else
                        {
                            itemUpd.EveryOnePermissions &= ~(uint)PermissionMask.Export;
                        }
                    }
                    else
                    {
                        // If the new state is exportable, force full perm
                        if ((itemUpd.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
                        {
//                            m_log.DebugFormat("[XXX]: Force full perm");
                            itemUpd.NextPermissions = (uint)(PermissionMask.All);
                        }
                    }

                    if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
                        item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
                    item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;

                    if (item.EveryOnePermissions != (itemUpd.EveryOnePermissions & item.BasePermissions))
                        item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
                    item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions;

                    if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions))
                        item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
                    item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions;

                    item.GroupID = itemUpd.GroupID;
                    item.GroupOwned = itemUpd.GroupOwned;
                    item.CreationDate = itemUpd.CreationDate;
                    // The client sends zero if its newly created?

                    if (itemUpd.CreationDate == 0)
                        item.CreationDate = Util.UnixTimeSinceEpoch();
                    else
                        item.CreationDate = itemUpd.CreationDate;

                    // TODO: Check if folder changed and move item
                    //item.NextPermissions = itemUpd.Folder;
                    item.InvType = itemUpd.InvType;

                    if (item.SalePrice != itemUpd.SalePrice ||
                        item.SaleType != itemUpd.SaleType)
                        item.Flags |= (uint)InventoryItemFlags.ObjectSlamSale;
                    item.SalePrice = itemUpd.SalePrice;
                    item.SaleType = itemUpd.SaleType;

                    if (item.InvType == (int)InventoryType.Wearable && (item.Flags & 0xf) == 0 && (itemUpd.Flags & 0xf) != 0)
                    {
                        item.Flags = (uint)(item.Flags & 0xfffffff0) | (itemUpd.Flags & 0xf);
                        sendUpdate = true;
                    }

                    InventoryService.UpdateItem(item);
                }

                if (UUID.Zero != transactionID)
                {
                    if (AgentTransactionsModule != null)
                    {
                        AgentTransactionsModule.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
                    }
                }
                else
                {
                    // This MAY be problematic, if it is, another solution
                    // needs to be found. If inventory item flags are updated
                    // the viewer's notion of the item needs to be refreshed.
                    //
                    // In other situations we cannot send out a bulk update here, since this will cause editing of clothing to start 
                    // failing frequently.  Possibly this is a race with a separate transaction that uploads the asset.
                    if (sendUpdate)
                        remoteClient.SendBulkUpdateInventory(item);
                }
            }
            else
            {
                m_log.ErrorFormat(
                    "[AGENTINVENTORY]: Item id {0} not found for an inventory item update for {1}.",
                    itemID, remoteClient.Name);
            }
        }
コード例 #30
0
        /// <summary>
        /// Rez an object into the scene from the user's inventory
        /// </summary>
        /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
        /// things to the scene.  The caller should be doing that, I think.
        /// <param name="remoteClient"></param>
        /// <param name="itemID"></param>
        /// <param name="RayEnd"></param>
        /// <param name="RayStart"></param>
        /// <param name="RayTargetID"></param>
        /// <param name="BypassRayCast"></param>
        /// <param name="RayEndIsIntersection"></param>
        /// <param name="RezSelected"></param>
        /// <param name="RemoveItem"></param>
        /// <param name="fromTaskID"></param>
        /// <param name="attachment"></param>
        /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
        public virtual SceneObjectGroup RezObject (IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                    UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                    bool RezSelected, bool RemoveItem, UUID fromTaskID)
        {
            // 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 = m_scene.SceneGraph.GetNewRezLocation (
                      RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                      BypassRayCast, bRayEndIsIntersection, true, scale, false);

            System.Xml.XmlDocument doc;
            InventoryItemBase item = new InventoryItemBase (itemID, remoteClient.AgentId);
            item = m_scene.InventoryService.GetItem (item);
            SceneObjectGroup group = CreateObjectFromInventory (item, remoteClient, itemID, out doc);
            if (doc == null)
            {
                //No asset, check task inventory
                IEntity e;
                m_scene.SceneGraph.TryGetEntity (fromTaskID, out e);
                if (e != null && e is SceneObjectGroup)
                {
                    SceneObjectGroup grp = (SceneObjectGroup)e;
                    TaskInventoryItem taskItem = grp.RootPart.Inventory.GetInventoryItem (itemID);
                    item = new InventoryItemBase ();

                    item.ID = UUID.Random ();
                    item.CreatorId = taskItem.CreatorID.ToString ();
                    item.Owner = remoteClient.AgentId;
                    item.AssetID = taskItem.AssetID;
                    item.Description = taskItem.Description;
                    item.Name = taskItem.Name;
                    item.AssetType = taskItem.Type;
                    item.InvType = taskItem.InvType;
                    item.Flags = taskItem.Flags;
                    item.SalePrice = taskItem.SalePrice;
                    item.SaleType = taskItem.SaleType;

                    if (m_scene.Permissions.PropagatePermissions ())
                    {
                        item.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
                        if (taskItem.InvType == (int)InventoryType.Object)
                            item.CurrentPermissions = item.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move));
                        else
                            item.CurrentPermissions = item.BasePermissions & taskItem.CurrentPermissions;

                        item.CurrentPermissions |= 16; // Slam
                        item.NextPermissions = taskItem.NextPermissions;
                        item.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
                        item.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions;
                    }
                    else
                    {
                        item.BasePermissions = taskItem.BasePermissions;
                        item.CurrentPermissions = taskItem.CurrentPermissions;
                        item.NextPermissions = taskItem.NextPermissions;
                        item.EveryOnePermissions = taskItem.EveryonePermissions;
                        item.GroupPermissions = taskItem.GroupPermissions;
                    }
                    group = CreateObjectFromInventory (item, remoteClient, itemID, out doc);
                }
                else
                    return null;
            }
            if (group == null && doc.FirstChild.OuterXml.StartsWith ("<groups>"))
            {
                List<SceneObjectGroup> Groups = RezMultipleObjectsFromInventory (doc.FirstChild.ChildNodes, itemID, remoteClient, pos, RezSelected, item, RayTargetID, BypassRayCast, RayEndIsIntersection, RayEnd, RayStart, bRayEndIsIntersection);
                if (Groups.Count != 0)
                    return Groups[0];
                else
                    return null;
            }

            string reason;
            if (!m_scene.Permissions.CanRezObject (
                    group.ChildrenList.Count, remoteClient.AgentId, pos, out reason))
            {
                // The client operates in no fail mode. It will
                // have already removed the item from the folder
                // if it's no copy.
                // Put it back if it's not an attachment
                //
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                    remoteClient.SendBulkUpdateInventory (item);
                remoteClient.SendAlertMessage ("You do not have permission to rez objects here.");
                return null;
            }

            if (RezSelected)
                group.RootPart.AddFlag (PrimFlags.CreateSelected);
            // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
            // we'll be doing that later on.  Scheduling more than one full update during the attachment
            // process causes some clients to fail to display the attachment properly.
            m_scene.SceneGraph.AddPrimToScene (group);

            //  m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
            //  Set it's position in world.
            float offsetHeight = 0;
            pos = m_scene.SceneGraph.GetNewRezLocation (
                RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox (out offsetHeight), false);
            pos.Z += offsetHeight;
            group.AbsolutePosition = pos;
            //   m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);

            SceneObjectPart rootPart = (SceneObjectPart)group.GetChildPart (group.UUID);
            if (rootPart == null)
            {
                m_log.Error ("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart.");
                return null;
            }

            // Since renaming the item in the inventory does not affect the name stored
            // in the serialization, transfer the correct name from the inventory to the
            // object itself before we rez.
            rootPart.Name = item.Name;
            rootPart.Description = item.Description;

            List<SceneObjectPart> partList = new List<SceneObjectPart> (group.ChildrenList);

            group.SetGroup (remoteClient.ActiveGroupId, remoteClient);
            item.Owner = remoteClient.AgentId;
            if (rootPart.OwnerID != item.Owner)
            {
                //Need to kill the for sale here
                rootPart.ObjectSaleType = 0;
                rootPart.SalePrice = 10;

                if (m_scene.Permissions.PropagatePermissions ())
                {
                    if ((item.CurrentPermissions & 8) != 0)
                    {
                        foreach (SceneObjectPart part in partList)
                        {
                            part.EveryoneMask = item.EveryOnePermissions;
                            part.NextOwnerMask = item.NextPermissions;
                            part.GroupMask = 0; // DO NOT propagate here
                        }
                    }

                    group.ApplyNextOwnerPermissions ();
                }
            }

            foreach (SceneObjectPart part in partList)
            {
                if (part.OwnerID != item.Owner)
                {
                    part.LastOwnerID = part.OwnerID;
                    part.OwnerID = item.Owner;
                    part.Inventory.ChangeInventoryOwner (item.Owner);
                }
                else if ((item.CurrentPermissions & 8) != 0) // Slam!
                {
                    part.EveryoneMask = item.EveryOnePermissions;
                    part.NextOwnerMask = item.NextPermissions;

                    part.GroupMask = 0; // DO NOT propagate here
                }
            }

            rootPart.TrimPermissions ();

            if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
            {
                group.ClearPartAttachmentData ();
            }

            // Fire on_rez
            group.CreateScriptInstances (0, true, 0, UUID.Zero);
            rootPart.ParentGroup.ResumeScripts ();

            group.ScheduleGroupUpdate (PrimUpdateFlags.FullUpdate);
            if (!m_scene.Permissions.BypassPermissions ())
            {
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                {
                    List<UUID> uuids = new List<UUID> ();
                    uuids.Add (item.ID);
                    m_scene.InventoryService.DeleteItems (item.Owner, uuids);
                }
            }
            return group;
        }
コード例 #31
0
        void OnInstantMessage(IClientAPI client, GridInstantMessage im)
        {
            //MainConsole.Instance.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog);
            IScene clientScene = FindClientScene(client.AgentId);
            if (clientScene == null) // Something seriously wrong here.
            {
                MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Cannot find originating user scene");
                return;
            }

            if (im.Dialog == (byte) InstantMessageDialog.InventoryOffered)
            {
                //MainConsole.Instance.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0]));

                if (im.BinaryBucket.Length < 17) // Invalid
                {
                    MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Invalid length {0} for asset type {1}",
                        im.BinaryBucket.Length, ((AssetType)im.BinaryBucket[0]));
                    return;
                }

                UUID receipientID = im.ToAgentID;
                IScenePresence recipientUser = null;
                IScene recipientUserScene = FindClientScene(client.AgentId);
                if (recipientUserScene != null)
                    recipientUser = recipientUserScene.GetScenePresence(receipientID);
                UUID copyID;

                // user is online now...
                if (recipientUser != null)
                {

                    // First byte is the asset type
                    AssetType assetType = (AssetType)im.BinaryBucket [0];

                    if (assetType == AssetType.Folder)
                    {
                        UUID folderID = new UUID (im.BinaryBucket, 1);

                        MainConsole.Instance.DebugFormat (
                            "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory",
                            folderID, im.ToAgentID);


                        clientScene.InventoryService.GiveInventoryFolderAsync (
                            receipientID,
                            client.AgentId,
                            folderID,
                            UUID.Zero,
                            (folder) =>
                            {
                                if (folder == null)
                                {
                                    client.SendAgentAlertMessage ("Can't find folder to give. Nothing given.", false);
                                    return;
                                }

                                // The outgoing binary bucket should contain only the byte which signals an asset folder is
                                // being copied and the following bytes for the copied folder's UUID
                                copyID = folder.ID;
                                byte[] copyIDBytes = copyID.GetBytes ();
                                im.BinaryBucket = new byte[ 1 + copyIDBytes.Length ];
                                im.BinaryBucket [0] = (byte)AssetType.Folder;
                                Array.Copy (copyIDBytes, 0, im.BinaryBucket, 1, copyIDBytes.Length);

//                                m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0,
//                                    "Inworld inventory folder transfer", TransactionType.GiveInventory, UUID.Zero);
                            if (moneyService != null)
                                moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                "Inworld inventory folder transfer", TransactionType.GiveInventory);

                                if (recipientUser != null)
                                {
                                    recipientUser.ControllingClient.SendBulkUpdateInventory (folder);
                                    im.SessionID = copyID;
                                    recipientUser.ControllingClient.SendInstantMessage (im);
                                }
                            });

                    } else
                    {
                        // First byte of the array is probably the item type
                        // Next 16 bytes are the UUID

                        UUID itemID = new UUID (im.BinaryBucket, 1);

                        MainConsole.Instance.DebugFormat (
                            "[INVENTORY TRANSFER]: (giving) Inserting item {0} into agent {1}'s inventory",
                            itemID, im.ToAgentID);

                        clientScene.InventoryService.GiveInventoryItemAsync (
                            im.ToAgentID,
                            im.FromAgentID,
                            itemID,
                            UUID.Zero,
                            false,
                            (itemCopy) =>
                            {
                                if (itemCopy == null)
                                {
                                    MainConsole.Instance.DebugFormat (
                                        "[INVENTORY TRANSFER]: (giving) Unable to find item {0} to give to agent {1}'s inventory",
                                        itemID, im.ToAgentID);
                                    client.SendAgentAlertMessage ("Can't find item to give. Nothing given.", false);
                                    return;
                                }

                                copyID = itemCopy.ID;
                                Array.Copy (copyID.GetBytes (), 0, im.BinaryBucket, 1, 16);
                                
                               if (moneyService != null)
                                  moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                          "Inworld inventory item transfer", TransactionType.GiveInventory);

                                if (recipientUser != null)
                                {
                                    recipientUser.ControllingClient.SendBulkUpdateInventory (itemCopy);
                                    im.SessionID = itemCopy.ID;
                                    recipientUser.ControllingClient.SendInstantMessage (im);
                                }
                            });
  
                    
                    }
                }  else
                {
                    // recipient is offline.
                    // Send the IM to the recipient. The item is already
                    // in their inventory, so it will not be lost if
                    // they are offline.
                    //
                     if (m_TransferModule != null)
                        m_TransferModule.SendInstantMessage(im);
                }
            }
            else if (im.Dialog == (byte) InstantMessageDialog.InventoryAccepted)
            {
                IScenePresence user = clientScene.GetScenePresence(im.ToAgentID);
                MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Acceptance message received");

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                        m_TransferModule.SendInstantMessage(im);
                }
            }
            else if (im.Dialog == (byte) InstantMessageDialog.InventoryDeclined)
            {
                // Here, the recipient is local and we can assume that the
                // inventory is loaded. Courtesy of the above bulk update,
                // It will have been pushed to the client, too
                //
                IInventoryService invService = clientScene.InventoryService;
                MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Declined message received");

                InventoryFolderBase trashFolder =
                    invService.GetFolderForType(client.AgentId, InventoryType.Unknown, FolderType.Trash);

                UUID inventoryID = im.SessionID; // The inventory item/folder, back from it's trip

                InventoryItemBase item = invService.GetItem(client.AgentId, inventoryID);
                InventoryFolderBase folder = null;

                if (item != null && trashFolder != null)
                {
                    item.Folder = trashFolder.ID;

                    // Diva comment: can't we just update this item???
                    List<UUID> uuids = new List<UUID> {item.ID};
                    invService.DeleteItems(item.Owner, uuids);
                    ILLClientInventory inventory = client.Scene.RequestModuleInterface<ILLClientInventory>();
                    if (inventory != null)
                        inventory.AddInventoryItemAsync(client, item);
                }
                else
                {
                    folder = new InventoryFolderBase(inventoryID, client.AgentId);
                    folder = invService.GetFolder(folder);

                    if (folder != null & trashFolder != null)
                    {
                        folder.ParentID = trashFolder.ID;
                        invService.MoveFolder(folder);
                        client.SendBulkUpdateInventory(folder);
                    }
                }

                if ((null == item && null == folder) | null == trashFolder)
                {
                    string reason = String.Empty;

                    if (trashFolder == null)
                        reason += " Trash folder not found.";
                    if (item == null)
                        reason += " Item not found.";
                    if (folder == null)
                        reason += " Folder not found.";

                    client.SendAgentAlertMessage("Unable to delete " +
                                                 "received inventory" + reason, false);
                }

                //m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0,
                //    "Inworld inventory transfer declined", TransactionType.GiveInventory, UUID.Zero);
                if (moneyService != null)
                    moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                        "Inworld inventory transfer declined", TransactionType.GiveInventory);

                IScenePresence user = clientScene.GetScenePresence(im.ToAgentID);

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                        m_TransferModule.SendInstantMessage(im);
                }
            }
        }
コード例 #32
0
        /// <summary>
        /// Rez an object into the scene from the user's inventory
        /// </summary>
        /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
        /// things to the scene.  The caller should be doing that, I think.
        /// <param name="remoteClient"></param>
        /// <param name="itemID"></param>
        /// <param name="RayEnd"></param>
        /// <param name="RayStart"></param>
        /// <param name="RayTargetID"></param>
        /// <param name="BypassRayCast"></param>
        /// <param name="RayEndIsIntersection"></param>
        /// <param name="RezSelected"></param>
        /// <param name="RemoveItem"></param>
        /// <param name="fromTaskID"></param>
        /// <param name="attachment"></param>
        /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
        public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
                                    UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
                                    bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
        {
            // 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 = m_Scene.SceneGraph.GetNewRezLocation(
                      RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                      BypassRayCast, bRayEndIsIntersection, true, scale, false);

            // Rez object
            InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
            item = m_Scene.InventoryService.GetItem(item);

            if (item != null)
            {
                AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());

                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 (!m_Scene.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);
                    System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                    doc.LoadXml(xmlData);
                    System.Xml.XmlNode rootNode = doc.FirstChild;

                    if (doc.FirstChild.OuterXml.StartsWith("<groups>"))
                    {
                        List<SceneObjectGroup> Groups = RezMultipleObjectsFromInventory(rootNode.ChildNodes, itemId, remoteClient, attachment, pos, RezSelected, item, RayTargetID, BypassRayCast, RayEndIsIntersection, RayEnd, RayStart, bRayEndIsIntersection);
                        if (Groups.Count != 0)
                            return Groups[0];
                        else
                            return null;
                    }

                    SceneObjectGroup group
                                = SceneObjectSerializer.FromOriginalXmlFormat(itemId, doc.FirstChild.OuterXml, m_Scene);
                    if (group == null)
                        return null;

                    group.IsDeleted = false;
                    group.m_isLoaded = true;
                    foreach (SceneObjectPart part in group.ChildrenList)
                    {
                        part.IsLoading = false;
                    }
                    string reason; 
                    if (!m_Scene.Permissions.CanRezObject(
                            group.ChildrenList.Count, remoteClient.AgentId, pos, out reason)
                            && !attachment)
                        {
                            // The client operates in no fail mode. It will
                            // have already removed the item from the folder
                            // if it's no copy.
                            // Put it back if it's not an attachment
                            //
                            if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
                                remoteClient.SendBulkUpdateInventory(item);
                            remoteClient.SendAlertMessage("You do not have permission to rez objects here.");
                            return null;
                        }

                        if (attachment)
                        {
                            group.RootPart.Flags |= PrimFlags.Phantom;
                            group.RootPart.IsAttachment = true;
                        }
                        if (RezSelected)
                            group.RootPart.AddFlag(PrimFlags.CreateSelected);
                        // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
                        // we'll be doing that later on.  Scheduling more than one full update during the attachment
                        // process causes some clients to fail to display the attachment properly.
                        m_Scene.SceneGraph.AddPrimToScene(group);

                        //  m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
                        // 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)
                        {
                            float offsetHeight = 0;
                            pos = m_Scene.SceneGraph.GetNewRezLocation(
                                RayStart, RayEnd, RayTargetID, Quaternion.Identity,
                                BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
                            pos.Z += offsetHeight;
                            group.AbsolutePosition = pos;
                            //   m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2}  and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);

                        }
                        else
                        {
                            group.SetFromItemID(itemID);
                        }

                        SceneObjectPart rootPart = null;
                        try
                        {
                            rootPart = group.GetChildPart(group.UUID);
                            if (rootPart == null)
                            {
                                //Just throw the null
                                rootPart.Acceleration = new Vector3();
                            }
                        }
                        catch (NullReferenceException)
                        {
                            string isAttachment = "";

                            if (attachment)
                                isAttachment = " Object was an attachment";

                            m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
                            return null;
                        }

                        // Since renaming the item in the inventory does not affect the name stored
                        // in the serialization, transfer the correct name from the inventory to the
                        // object itself before we rez.
                        rootPart.Name = item.Name;
                        rootPart.Description = item.Description;

                        List<SceneObjectPart> partList = new List<SceneObjectPart>(group.ChildrenList);

                        group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
                        if (rootPart.OwnerID != item.Owner)
                        {
                            //Need to kill the for sale here
                            rootPart.ObjectSaleType = 0;
                            rootPart.SalePrice = 10;

                            if (m_Scene.Permissions.PropagatePermissions())
                            {
                                if ((item.CurrentPermissions & 8) != 0)
                                {
                                    foreach (SceneObjectPart part in partList)
                                    {
                                        part.EveryoneMask = item.EveryOnePermissions;
                                        part.NextOwnerMask = item.NextPermissions;
                                        part.GroupMask = 0; // DO NOT propagate here
                                    }
                                }

                                group.ApplyNextOwnerPermissions();
                            }
                        }

                        foreach (SceneObjectPart part in partList)
                        {
                            if (part.OwnerID != item.Owner)
                            {
                                part.LastOwnerID = part.OwnerID;
                                part.OwnerID = item.Owner;
                                part.Inventory.ChangeInventoryOwner(item.Owner);
                            }
                            else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam!
                            {
                                part.EveryoneMask = item.EveryOnePermissions;
                                part.NextOwnerMask = item.NextPermissions;

                                part.GroupMask = 0; // DO NOT propagate here
                            }
                        }

                        rootPart.TrimPermissions();

                        if (!attachment)
                        {
                            if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
                            {
                                group.ClearPartAttachmentData();
                            }

                            // Fire on_rez
                            group.CreateScriptInstances(0, true, 0, UUID.Zero);
                            rootPart.ParentGroup.ResumeScripts();
                        }

                        group.ScheduleGroupUpdate(PrimUpdateFlags.FullUpdate);
                        if (!m_Scene.Permissions.BypassPermissions())
                        {
                            if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
                            {
                                // If this is done on attachments, no
                                // copy ones will be lost, so avoid it
                                //
                                if (!attachment)
                                {
                                    List<UUID> uuids = new List<UUID>();
                                    uuids.Add(item.ID);
                                    m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
                                }
                            }
                        }
                        return group;
                }
            }

            return null;
        }
コード例 #33
0
        private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
        {
            //MainConsole.Instance.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog);
            IScene clientScene = FindClientScene(client.AgentId);

            if (clientScene == null) // Something seriously wrong here.
            {
                MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Cannot find originating user scene");
                return;
            }

            if (im.Dialog == (byte)InstantMessageDialog.InventoryOffered)
            {
                //MainConsole.Instance.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0]));

                if (im.BinaryBucket.Length < 17) // Invalid
                {
                    MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Invalid length {0} for asset type {1}",
                                                     im.BinaryBucket.Length, ((AssetType)im.BinaryBucket[0]));
                    return;
                }

                UUID           receipientID       = im.ToAgentID;
                IScenePresence recipientUser      = null;
                IScene         recipientUserScene = FindClientScene(client.AgentId);
                if (recipientUserScene != null)
                {
                    recipientUser = recipientUserScene.GetScenePresence(receipientID);
                }
                UUID copyID;

                // user is online now...
                if (recipientUser != null)
                {
                    // First byte is the asset type
                    AssetType assetType = (AssetType)im.BinaryBucket [0];

                    if (assetType == AssetType.Folder)
                    {
                        UUID folderID = new UUID(im.BinaryBucket, 1);

                        MainConsole.Instance.DebugFormat(
                            "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory",
                            folderID, im.ToAgentID);


                        clientScene.InventoryService.GiveInventoryFolderAsync(
                            receipientID,
                            client.AgentId,
                            folderID,
                            UUID.Zero,
                            (folder) =>
                        {
                            if (folder == null)
                            {
                                client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false);
                                return;
                            }

                            // The outgoing binary bucket should contain only the byte which signals an asset folder is
                            // being copied and the following bytes for the copied folder's UUID
                            copyID              = folder.ID;
                            byte[] copyIDBytes  = copyID.GetBytes();
                            im.BinaryBucket     = new byte[1 + copyIDBytes.Length];
                            im.BinaryBucket [0] = (byte)AssetType.Folder;
                            Array.Copy(copyIDBytes, 0, im.BinaryBucket, 1, copyIDBytes.Length);

//                                m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0,
//                                    "Inworld inventory folder transfer", TransactionType.GiveInventory, UUID.Zero);
                            if (moneyService != null)
                            {
                                moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                                      "Inworld inventory folder transfer", TransactionType.GiveInventory);
                            }

                            if (recipientUser != null)
                            {
                                recipientUser.ControllingClient.SendBulkUpdateInventory(folder);
                                im.SessionID = copyID;
                                recipientUser.ControllingClient.SendInstantMessage(im);
                            }
                        });
                    }
                    else
                    {
                        // First byte of the array is probably the item type
                        // Next 16 bytes are the UUID

                        UUID itemID = new UUID(im.BinaryBucket, 1);

                        MainConsole.Instance.DebugFormat(
                            "[INVENTORY TRANSFER]: (giving) Inserting item {0} into agent {1}'s inventory",
                            itemID, im.ToAgentID);

                        clientScene.InventoryService.GiveInventoryItemAsync(
                            im.ToAgentID,
                            im.FromAgentID,
                            itemID,
                            UUID.Zero,
                            false,
                            (itemCopy) =>
                        {
                            if (itemCopy == null)
                            {
                                MainConsole.Instance.DebugFormat(
                                    "[INVENTORY TRANSFER]: (giving) Unable to find item {0} to give to agent {1}'s inventory",
                                    itemID, im.ToAgentID);
                                client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
                                return;
                            }

                            copyID = itemCopy.ID;
                            Array.Copy(copyID.GetBytes(), 0, im.BinaryBucket, 1, 16);

                            if (moneyService != null)
                            {
                                moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                                      "Inworld inventory item transfer", TransactionType.GiveInventory);
                            }

                            if (recipientUser != null)
                            {
                                recipientUser.ControllingClient.SendBulkUpdateInventory(itemCopy);
                                im.SessionID = itemCopy.ID;
                                recipientUser.ControllingClient.SendInstantMessage(im);
                            }
                        });
                    }
                }
                else
                {
                    // recipient is offline.
                    // Send the IM to the recipient. The item is already
                    // in their inventory, so it will not be lost if
                    // they are offline.
                    //
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im);
                    }
                }
            }
            else if (im.Dialog == (byte)InstantMessageDialog.InventoryAccepted)
            {
                IScenePresence user = clientScene.GetScenePresence(im.ToAgentID);
                MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Acceptance message received");

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im);
                    }
                }
            }
            else if (im.Dialog == (byte)InstantMessageDialog.InventoryDeclined)
            {
                // Here, the recipient is local and we can assume that the
                // inventory is loaded. Courtesy of the above bulk update,
                // It will have been pushed to the client, too
                //
                IInventoryService invService = clientScene.InventoryService;
                MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Declined message received");

                InventoryFolderBase trashFolder =
                    invService.GetFolderForType(client.AgentId, InventoryType.Unknown, AssetType.TrashFolder);

                UUID inventoryID = im.SessionID; // The inventory item/folder, back from it's trip

                InventoryItemBase   item   = invService.GetItem(client.AgentId, inventoryID);
                InventoryFolderBase folder = null;

                if (item != null && trashFolder != null)
                {
                    item.Folder = trashFolder.ID;

                    // Diva comment: can't we just update this item???
                    List <UUID> uuids = new List <UUID> {
                        item.ID
                    };
                    invService.DeleteItems(item.Owner, uuids);
                    ILLClientInventory inventory = client.Scene.RequestModuleInterface <ILLClientInventory>();
                    if (inventory != null)
                    {
                        inventory.AddInventoryItemAsync(client, item);
                    }
                }
                else
                {
                    folder = new InventoryFolderBase(inventoryID, client.AgentId);
                    folder = invService.GetFolder(folder);

                    if (folder != null & trashFolder != null)
                    {
                        folder.ParentID = trashFolder.ID;
                        invService.MoveFolder(folder);
                        client.SendBulkUpdateInventory(folder);
                    }
                }

                if ((null == item && null == folder) | null == trashFolder)
                {
                    string reason = String.Empty;

                    if (trashFolder == null)
                    {
                        reason += " Trash folder not found.";
                    }
                    if (item == null)
                    {
                        reason += " Item not found.";
                    }
                    if (folder == null)
                    {
                        reason += " Folder not found.";
                    }

                    client.SendAgentAlertMessage("Unable to delete " +
                                                 "received inventory" + reason, false);
                }

                //m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0,
                //    "Inworld inventory transfer declined", TransactionType.GiveInventory, UUID.Zero);
                if (moneyService != null)
                {
                    moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                          "Inworld inventory transfer declined", TransactionType.GiveInventory);
                }

                IScenePresence user = clientScene.GetScenePresence(im.ToAgentID);

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                    {
                        m_TransferModule.SendInstantMessage(im);
                    }
                }
            }
        }
コード例 #34
0
        /// <summary>
        /// Do pre-rez processing when the object comes from an item.
        /// </summary>
        /// <param name="remoteClient"></param>
        /// <param name="item"></param>
        /// <param name="objlist"></param>
        /// <param name="pos"></param>
        /// <param name="isAttachment"></param>
        /// <returns>true if we can processed with rezzing, false if we need to abort</returns>
        private bool DoPreRezWhenFromItem(
            IClientAPI remoteClient, InventoryItemBase item, List <SceneObjectGroup> objlist, Vector3 pos, bool isAttachment)
        {
            UUID fromUserInventoryItemId = 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 (!m_Scene.Permissions.BypassPermissions())
            {
                if ((item.CurrentPermissions & (uint)PermissionMask.Copy)
                    == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                {
                    fromUserInventoryItemId = item.ID;
                }
            }
            else
            {
                if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                {
                    // Brave new fullperm world
                    fromUserInventoryItemId = item.ID;
                }
            }

            int primcount = 0;

            foreach (SceneObjectGroup g in objlist)
            {
                primcount += g.PrimCount;
            }

            if (!m_Scene.Permissions.CanRezObject(
                    primcount, remoteClient.AgentId, pos) &&
                !isAttachment)
            {
                // The client operates in no fail mode. It will
                // have already removed the item from the folder
                // if it's no copy.
                // Put it back if it's not an attachment
                //
                if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
                {
                    remoteClient.SendBulkUpdateInventory(item);
                }

                return(false);
            }

            for (int i = 0; i < objlist.Count; i++)
            {
                SceneObjectGroup so       = objlist[i];
                SceneObjectPart  rootPart = so.RootPart;

                // Since renaming the item in the inventory does not
                // affect the name stored in the serialization, transfer
                // the correct name from the inventory to the
                // object itself before we rez.
                //
                // Only do these for the first object if we are rezzing a coalescence.
                if (i == 0)
                {
                    rootPart.Name           = item.Name;
                    rootPart.Description    = item.Description;
                    rootPart.ObjectSaleType = item.SaleType;
                    rootPart.SalePrice      = item.SalePrice;
                }

                rootPart.FromFolderID = item.Folder;

//                Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
//                                  rootPart.OwnerID, item.Owner, item.CurrentPermissions);

                if ((rootPart.OwnerID != item.Owner) ||
                    (item.CurrentPermissions & 16) != 0)
                {
                    //Need to kill the for sale here
                    rootPart.ObjectSaleType = 0;
                    rootPart.SalePrice      = 10;

                    if (m_Scene.Permissions.PropagatePermissions())
                    {
                        foreach (SceneObjectPart part in so.Parts)
                        {
                            if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
                            {
                                part.EveryoneMask  = item.EveryOnePermissions;
                                part.NextOwnerMask = item.NextPermissions;
                            }
                            part.GroupMask = 0; // DO NOT propagate here
                        }

                        so.ApplyNextOwnerPermissions();
                    }
                }

                foreach (SceneObjectPart part in so.Parts)
                {
                    part.FromUserInventoryItemID = fromUserInventoryItemId;

                    if ((part.OwnerID != item.Owner) ||
                        (item.CurrentPermissions & 16) != 0)
                    {
                        part.Inventory.ChangeInventoryOwner(item.Owner);
                        part.GroupMask = 0; // DO NOT propagate here
                    }

                    part.EveryoneMask  = item.EveryOnePermissions;
                    part.NextOwnerMask = item.NextPermissions;
                }

                rootPart.TrimPermissions();

                if (isAttachment)
                {
                    so.SetFromItemID(item.ID);
                }
            }

            return(true);
        }