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