public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, bool append, bool silent,
     AttachFlags flags)
 {
     controllingClient.RunAttachmentOperation(() =>
         {
             m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, append, silent, flags);
         });
 }
示例#2
0
        public void AttachObject(
            IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool appendMode, bool silent,
            AttachFlags flags)
        {
            SceneObjectGroup group = GetGroupByPrim(objectLocalID);
            if (group == null)
            {
                m_log.ErrorFormat("[SCENE] Could not find localID {0} attach object to {1}.", objectLocalID, remoteClient.AgentId);
                return;
            }

            if (group.HasSittingAvatars)
            {
                m_log.ErrorFormat("[SCENE] Not allowing {0} to attach object '{1}'. Group has sitting avatars.", remoteClient.AgentId, group.Name);
                remoteClient.SendAgentAlertMessage("You can not attach an object that has seated avatars", false);
                return;
            }

            if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId) == false)
            {
                m_log.ErrorFormat("[SCENE] Insufficient permission for {0} to attach object '{1}'.", remoteClient.AgentId, group.Name);
                remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false);
                return;
            }

            // it's a HUD and someone else's...
            if (SceneObjectPart.IsAttachmentPointOnHUD(AttachmentPt) && (group.OwnerID != remoteClient.AgentId))
            {
                m_log.WarnFormat("[SCENE] Invalid wear HUD owned by {0} on {1} attachment point {2} object '{3}'.",
                    group.UUID, remoteClient.AgentId, AttachmentPt, group.Name);
                return;
            }

            bool isTainted = false;
            if ((flags & (AttachFlags.FromInWorld | AttachFlags.FromCrossing)) != 0) //if this object is from in-world, we need to prep it first
            {
                bool fromCrossing = (flags & AttachFlags.FromCrossing) == AttachFlags.FromCrossing;
                if (!group.PrepareForRezAsAttachment(AttachmentPt, out isTainted, fromCrossing))
                {
                    return;
                }
            }
            else
            {
                //this is an inventory based rez. check if the attachment point has changed
                isTainted = group.TaintedAttachment;
                group.TaintedAttachment = false;
            }

            //at this point attachment point has been set by one of the calls to PrepareForRezAsAttachment, we should trust what is in the object
            AttachmentPt = group.AttachmentPoint;

            //this shouldnt happen
            if (AttachmentPt == 0)
            {
                m_log.WarnFormat("[SCENE]: AttachmentPoint still ZERO and about to attach! PrepareForRezAsAttachment not called?");
                group.RootPart.Shape.State = (byte)AttachmentPoint.LeftHand;
            }

            // Now that we know which AttachmentPt, free up all objects on that attachment point except 'group'.
            if (appendMode == false)
                DetachSingleAttachmentPointToInv(AttachmentPt, remoteClient, group);

            // Saves and gets assetID
            UUID itemId = group.GetFromItemID();

            if ((flags & AttachFlags.FromInWorld) != 0 && (flags & AttachFlags.Temp) == 0)
                m_parentScene.AttachObjectAssetStore(remoteClient, group, remoteClient.AgentId, group.RezzedFromFolderId, out itemId);

            if ((flags & AttachFlags.Temp) != 0 || group.IsTempAttachment)
            {
                group.IsTempAttachment = true;
                group.SetFromItemID(UUID.Random());
            }
            else
            {
                group.IsTempAttachment = false;
            }


            group.AttachToAgent(remoteClient.AgentId, AttachmentPt, silent);

            // In case it is later dropped again, don't let
            // it get cleaned up
            //
            group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);

            //SETS or CLEARS HasGroupChanged in the case when the only change is the 
            //fact that a bunch of methods are called when the attachment rezzes
            group.HasGroupChanged = isTainted;
            if (!silent)
                group.SendFullUpdateToAllClientsImmediate();

            if ((flags & AttachFlags.DontFireOnAttach) == 0)
            {
                //this needs to be called here as well because attaching greated a brand new prim
                m_parentScene.EventManager.TriggerOnAttachObject(remoteClient.AgentId, group.LocalId);
            }
        }