CreateScriptInstances() public method

Start the scripts contained in all the prims in this group.
public CreateScriptInstances ( int startParam, bool postOnRez, string engine, int stateSource ) : void
startParam int
postOnRez bool
engine string
stateSource int
return void
Ejemplo n.º 1
0
        /// <summary>
        /// Internal method which actually does all the work for attaching an object.
        /// </summary>
        /// <returns>The object attached.</returns>
        /// <param name='sp'></param>
        /// <param name='group'>The object to attach.</param>
        /// <param name='attachmentPt'></param>
        /// <param name='silent'></param>
        /// <param name='addToInventory'>If true then add object to user inventory.</param>
        /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param>
        /// <param name='append'>Append to attachment point rather than replace.</param>
        private bool AttachObjectInternal(
            IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool resumeScripts, bool append)
        {
            if (group.GetSittingAvatarsCount() != 0)
            {
                if (DebugLevel > 0)
                    m_log.WarnFormat(
                        "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
                        group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());

                return false;
            }

            Vector3 attachPos = group.AbsolutePosition;
            // If the attachment point isn't the same as the one previously used
            // set it's offset position = 0 so that it appears on the attachment point
            // and not in a weird location somewhere unknown.
            if (attachmentPt != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint)
            {
                attachPos = Vector3.Zero;
            }

            // if the attachment point is the same as previous, make sure we get the saved
            // position info.
            if (attachmentPt != 0 && attachmentPt == group.RootPart.Shape.LastAttachPoint)
            {
                attachPos = group.RootPart.AttachedPos;
            }

            // AttachmentPt 0 means the client chose to 'wear' the attachment.
            if (attachmentPt == (uint)AttachmentPoint.Default)
            {
                // Check object for stored attachment point
                attachmentPt = group.AttachmentPoint;
            }

            // if we didn't find an attach point, look for where it was last attached
            if (attachmentPt == 0)
            {
                attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint;
                attachPos = group.RootPart.AttachedPos;
                group.HasGroupChanged = true;
            }

            // if we still didn't find a suitable attachment point.......
            if (attachmentPt == 0)
            {
                // Stick it on left hand with Zero Offset from the attachment point.
                attachmentPt = (uint)AttachmentPoint.LeftHand;
                attachPos = Vector3.Zero;
            }

            group.AttachmentPoint = attachmentPt;
            group.AbsolutePosition = attachPos;

            List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);

            if (attachments.Contains(group))
            {
                if (DebugLevel > 0)
                    m_log.WarnFormat(
                        "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
                        group.Name, group.LocalId, sp.Name, attachmentPt);

                return false;
            }

            // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
            while (attachments.Count >= 5)
            {
                if (attachments[0].FromItemID != UUID.Zero)
                    DetachSingleAttachmentToInv(sp, attachments[0]);
                attachments.RemoveAt(0);
            }

            // If we're not appending, remove the rest as well
            if (attachments.Count != 0 && !append)
            {
                foreach (SceneObjectGroup g in attachments)
                {
                    if (g.FromItemID != UUID.Zero)
                        DetachSingleAttachmentToInv(sp, g);
                }
            }

            lock (sp.AttachmentsSyncLock)
            {
                if (addToInventory && sp.PresenceType != PresenceType.Npc)
                    UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
    
                AttachToAgent(sp, group, attachmentPt, attachPos, silent);

                if (resumeScripts)
                {
                    // Fire after attach, so we don't get messy perms dialogs
                    // 4 == AttachedRez
                    group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
                    group.ResumeScripts();
                }

                // Do this last so that event listeners have access to all the effects of the attachment
                m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
            }

            return true;
        }
Ejemplo n.º 2
0
        private SceneObjectGroup RezSingleObjectToWorld(IClientAPI remoteClient, UUID itemID, 
            SceneObjectGroup group, Vector3 RayEnd, Vector3 RayStart,
            UUID RayTargetID, byte BypassRayCast, byte bRayEndIsIntersection,
            bool RezSelected, bool attachment, Vector3 pos, string name,
            string description, IInventoryItem item, ItemPermissionBlock itemPermissions,
            int? startParam, UUID? newAvatarGroupId, UUID? rezzedByObjectUUID)
        {
            bool ownerChanged = false;  // record this for the CHANGED_OWNER changed event

            if (IsBadUserLoad(group))
            {
                if (remoteClient != null)
                    remoteClient.SendAgentAlertMessage("You are currently not allowed to rez objects in this region.", false);
                return null;   // already reported above
            }
            if (IsBlacklistedLoad(group))
            {
                if (remoteClient != null)
                    remoteClient.SendAgentAlertMessage("Cannot rez blacklisted object '" + group.Name + "'.", false);
                return null;   // already reported above
            }

            //set the group here so that positioning in world will enable/disable the
            //script correctly based on the group the use is currently in

            // Initialize the server weight (LI)
            group.RecalcPrimWeights();

            group.RezzedFromFolderId = item.Folder;
            //group.FromAssetId = item.AssetID; //not needed yet

            if (newAvatarGroupId.HasValue)
            {
                //set the object's land group
                group.SetGroup(newAvatarGroupId.Value, null);
            }

            if (attachment)
            {
                group.SetFromItemID(itemID);
            }
            else
            {
                group.RootPart.SetGroupPositionDirect(pos);

                if (RezSelected)
                {
                    //also tell the client there is a new object being rezzed
                    foreach (SceneObjectPart part in group.GetParts())
                    {
                        part.AddFlag(PrimFlags.CreateSelected);
                    }
                }
            }

            SceneObjectPart rootPart = group.GetChildPart(group.UUID);
            if (rootPart == null) {
                string what = "object ";
                if (attachment)
                    what = " attachment ";
                m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + what + " root part not found.");
                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 = name;
            rootPart.Description = description;

            var partList = group.GetParts();

            foreach (SceneObjectPart part in partList)
            {
                /// This fixes inconsistencies between this part and the root part.
                /// In the past, there was a bug in Link operations that did not force 
                /// these permissions on child prims when linking.
                part.SyncChildPermsWithRoot();
            }

            if (rootPart.OwnerID != item.Owner)
            {
                if (Permissions.PropagatePermissions())
                {
                    if ((itemPermissions.CurrentPermissions & ScenePermBits.SLAM) != 0)
                    {    // enforce slam bit, apply item perms to the group parts
                        foreach (SceneObjectPart part in partList)
                        {
                            part.EveryoneMask = item.EveryOnePermissions;
                            part.NextOwnerMask = item.NextPermissions;
                            part.GroupMask = 0; // DO NOT propagate here
                        }
                    }
                    group.ApplyNextOwnerPermissions();
                }
            }

            ownerChanged |= group.Rationalize(item.Owner, false);

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

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

            rootPart.TrimPermissions();

            if (!attachment)
            {
                if (group.RootPart.IsPrim)
                {
                    group.ClearPartAttachmentData();
                }
            }

            if (this.AddObjectToSceneIfPermitted(group, remoteClient, pos, attachment, rezzedByObjectUUID))
            {
                if (ownerChanged)
                {
                    foreach (SceneObjectPart part in partList)
                        part.TriggerScriptChangedEvent(Changed.OWNER);
                }

                if (!attachment)
                {
                    // Fire on_rez
                    group.CreateScriptInstances(startParam, ScriptStartFlags.PostOnRez, DefaultScriptEngine, (int)ScriptStateSource.PrimData, null);

                    rootPart.ScheduleFullUpdate(PrimUpdateFlags.ForcedFullUpdate);
                }

            } 
            else 
            {
                // The viewer automatically removes no-copy items from inventory on a rez attempt.
                // Since this one did not rez, it's still in inventory so let's "put it back".
                if (remoteClient != null)
                {
                    InventoryItemBase ib = item as InventoryItemBase;

                    if (item != null)
                    {
                        //this is a folder item, not a task item. update the user
                        remoteClient.SendInventoryItemCreateUpdate(ib, 0);
                    }
                }
                return null;
            }

            return rootPart.ParentGroup;
        }
Ejemplo n.º 3
0
        public virtual SceneObjectGroup RezPrim(SceneObjectPart sourcePart, SceneObjectPart newPart, int param, out string reason)
        {
            // Rez object
            Vector3 pos = newPart.AbsolutePosition;
            SceneObjectGroup group = new SceneObjectGroup(newPart);
            bool isTemp = (group.RootPart.GetEffectiveObjectFlags() & PrimFlags.TemporaryOnRez) != 0;

            ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y);
            if (parcel == null)
            {
                reason = "land";
                return null;
            }

            // Pass 0 for landImpact here so that it can be tested separately.
            if (!Permissions.CanRezObject(0, newPart.OwnerID, sourcePart.UUID, pos, isTemp))
            {
                reason = "permission";
                return null;
            }

            if (!CheckLandImpact(parcel, group.LandImpact, out reason))
            {
                return null;
            }

            // Check for grey goo fence
            if (!CheckGreyGoo(sourcePart, group))
            {
                reason = "fence";
                return null;
            }

            // Allowing the rez... update the last rez time and the new group fields
            sourcePart.StampLastRez();
            group.CurrentParcel = parcel;   // initialize _currentParcel (and auto-return)
            group.SetGeneration(group.RootPart.Generation); // now update the rest of the parts
            group.ResetIDs();

            //set the group's group before setting the object's position.
            //this will make sure that the group id is correct during the script
            //engine's group check
            group.SetGroup(sourcePart.ParentGroup.RootPart.GroupID, null);

            AddNewSceneObject(group, !isTemp);

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

            rootPart.TrimPermissions();

            if (group.RootPart.IsPrim)
            {
                group.ClearPartAttachmentData();
            }

            group.CreateScriptInstances(param, ScriptStartFlags.PostOnRez, DefaultScriptEngine, (int)ScriptStateSource.PrimData, null);
            rootPart.ScheduleFullUpdate(PrimUpdateFlags.ForcedFullUpdate);

            reason = "success";
            return rootPart.ParentGroup;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Attach the object to the avatar
        /// </summary>
        /// <param name="remoteClient">The client that is having the attachment done</param>
        /// <param name="localID">The localID (SceneObjectPart) that is being attached (for the attach script event)</param>
        /// <param name="group">The group (SceneObjectGroup) that is being attached</param>
        /// <param name="AttachmentPt">The point to where the attachment will go</param>
        /// <param name="item">If this is not null, it saves a query in this method to the InventoryService
        /// This is the Item that the object is in (if it is in one yet)</param>
        protected void FindAttachmentPoint(IClientAPI remoteClient, uint localID, SceneObjectGroup group,
            int AttachmentPt, InventoryItemBase item)
        {
            //Make sure that we arn't over the limit of attachments
            SceneObjectGroup[] attachments = GetAttachmentsForAvatar(remoteClient.AgentId);
            if (attachments.Length + 1 > m_maxNumberOfAttachments)
            {
                //Too many
                remoteClient.SendAgentAlertMessage(
                    "You are wearing too many attachments. Take one off to attach this object", false);

                return;
            }
            Vector3 attachPos = group.GetAttachmentPos();
            if(!m_allowMultipleAttachments)
                AttachmentPt &= 0x7f; //Disable it!

            //Did the attachment change position or attachment point?
            bool changedPositionPoint = false;

            // If the attachment point isn't the same as the one previously used
            // set it's offset position = 0 so that it appears on the attachment point
            // and not in a weird location somewhere unknown.
            //Simplier terms: the attachment point changed, set it to the default 0,0,0 location
            if ((AttachmentPt & 0x7f) != 0 && (AttachmentPt & 0x7f) != (int)group.GetAttachmentPoint())
            {
                attachPos = Vector3.Zero;
                changedPositionPoint = true;
            }
            else
            {
                // AttachmentPt 0 means the client chose to 'wear' the attachment.
                if ((AttachmentPt & 0x7f) == 0)
                {
                    // Check object for stored attachment point
                    AttachmentPt = (int)group.GetSavedAttachmentPoint();
                    attachPos = group.GetAttachmentPos();
                }

                //Check state afterwards... use the newer GetSavedAttachmentPoint and Pos above first
                if ((AttachmentPt & 0x7f) == 0)
                {
                    // Check object for older stored attachment point
                    AttachmentPt = group.RootPart.Shape.State;
                    //attachPos = group.AbsolutePosition;
                }

                // if we still didn't find a suitable attachment point, force it to the default
                //This happens on the first time an avatar 'wears' an object
                if ((AttachmentPt & 0x7f) == 0)
                {
                    // Stick it on right hand with Zero Offset from the attachment point.
                    AttachmentPt = (int)AttachmentPoint.RightHand;
                    //Default location
                    attachPos = Vector3.Zero;
                    changedPositionPoint = true;
                }
            }

            group.HasGroupChanged = changedPositionPoint;

            //Update where we are put
            group.SetAttachmentPoint((byte)AttachmentPt);
            //Fix the position with the one we found
            group.AbsolutePosition = attachPos;

            // Remove any previous attachments
            ScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId);
            if (presence == null)
                return;
            UUID itemID = UUID.Zero;
            //Check for multiple attachment bits
            //If the numbers are the same, it wants to have the old attachment taken off
            if ((AttachmentPt & 0x7f) == AttachmentPt) 
            {
                foreach (SceneObjectGroup grp in attachments)
                {
                    if (grp.GetAttachmentPoint() == (byte)AttachmentPt)
                    {
                        itemID = grp.GetFromItemID();
                        break;
                    }
                }
                if (itemID != UUID.Zero)
                    DetachSingleAttachmentToInventory(itemID, remoteClient);
            }
            itemID = group.GetFromItemID();

            group.RootPart.AttachedAvatar = presence.UUID;

            //Anakin Lohner bug #3839 
            SceneObjectPart[] parts = group.Parts;
            for (int i = 0; i < parts.Length; i++)
                parts[i].AttachedAvatar = presence.UUID;

            if (group.RootPart.PhysActor != null)
            {
                m_scene.SceneGraph.PhysicsScene.RemovePrim(group.RootPart.PhysActor);
                group.RootPart.PhysActor = null;
            }

            group.AbsolutePosition = attachPos;
            group.RootPart.AttachedPos = attachPos;
            group.RootPart.IsAttachment = true;

            group.RootPart.SetParentLocalId(presence.LocalId);
            group.SetAttachmentPoint(Convert.ToByte(AttachmentPt));

            AvatarAttachments attPlugin = presence.RequestModuleInterface<AvatarAttachments>();
            if (attPlugin != null)
                attPlugin.AddAttachment(group);

            // Killing it here will cause the client to deselect it
            // It then reappears on the avatar, deselected
            // through the full update below
            //
            if (group.IsSelected)
            {
                foreach (SceneObjectPart part in group.ChildrenList)
                {
                    part.CreateSelected = true;
                }
            }
            //Kill the previous entity so that it will be selected
            SendKillEntity(group.RootPart);

            //NOTE: This MUST be here, otherwise we limit full updates during attachments when they are selected and it will block the first update.
            // So until that is changed, this MUST stay. The client will instantly reselect it, so this value doesn't stay borked for long.
            group.IsSelected = false;

            if (itemID == UUID.Zero)
            {
                //Delete the object inworld to inventory

                List<SceneObjectGroup> groups = new List<SceneObjectGroup>(1) { group };

                IInventoryAccessModule inventoryAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
                if (inventoryAccess != null)
                    inventoryAccess.DeleteToInventory(DeRezAction.AcquireToUserInventory, UUID.Zero,
                        groups, remoteClient.AgentId, out itemID);
            }
            else
            {
                //it came from an item, we need to start the scripts

                // Fire after attach, so we don't get messy perms dialogs
                // 4 == AttachedRez
                group.CreateScriptInstances(0, true, 4, UUID.Zero);
                group.ResumeScripts();
            }

            if (UUID.Zero == itemID)
            {
                m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID.");
                remoteClient.SendAgentAlertMessage(
                    "Unable to save attachment. Error inventory item ID.", false);
                return;
            }

            // XXYY!!
            if (item == null)
            {
                item = new InventoryItemBase(itemID, remoteClient.AgentId);
                item = m_scene.InventoryService.GetItem(item);
            }

            //Update the ItemID with the new item
            group.SetFromItemID(item.ID);

            //If we updated the attachment, we need to save the change
            if (presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID))
                AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);

            //Now recreate it so that it is selected
            group.ScheduleGroupUpdate(PrimUpdateFlags.FullUpdate);

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

            m_scene.EventManager.TriggerOnAttach(localID, group.GetFromItemID(), remoteClient.AgentId);
        }