コード例 #1
0
ファイル: Scene.cs プロジェクト: emperorstarfinder/Opensim2
        /// <summary>
        /// Synchronously delete the given object from the scene.
        /// </summary>
        /// <param name="group">Object Id</param>
        /// <param name="silent">Suppress broadcasting changes to other clients.</param>
        /// <param name="removeScripts">If true, then scripts are removed.  If false, then they are only stopped.</para>
        public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
        {
            // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);

            if (removeScripts)
                group.RemoveScriptInstances(true);
            else
                group.StopScriptInstances();

            List<ScenePresence> avatars = group.GetSittingAvatars();
            foreach (ScenePresence av in avatars)
            {
                if(av.ParentUUID == UUID.Zero)
                    av.StandUp();
            }

            SceneObjectPart[] partList = group.Parts;

            foreach (SceneObjectPart part in partList)
            {
                if (part.KeyframeMotion != null)
                {
                    part.KeyframeMotion.Delete();
                    part.KeyframeMotion = null;
                }

                if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
                {
                    PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
                }
                else if (part.PhysActor != null)
                {
                    part.RemoveFromPhysics();
                }
            }

            if (UnlinkSceneObject(group, false))
            {
                EventManager.TriggerObjectBeingRemovedFromScene(group);
                EventManager.TriggerParcelPrimCountTainted();
            }

            group.DeleteGroupFromScene(silent);

            // use this to mean also full delete
            if (removeScripts)
                group.Clear();
            partList = null;
            // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);          
        }
コード例 #2
0
        public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
        {
            if (so.AttachedAvatar != sp.UUID)
            {
                m_log.WarnFormat(
                    "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}",
                    so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName);

                return;
            }

            // If this didn't come from inventory, it also shouldn't go there
            // on detach. It's likely a temp attachment.
            if (so.FromItemID == UUID.Zero)
            {
                // Retirn value is ignored
                PrepareScriptInstanceForSave(so, true);

                lock (sp.AttachmentsSyncLock)
                {
                    bool changed = sp.Appearance.DetachAttachment(so.FromItemID);
                    if (changed && m_scene.AvatarFactory != null)
                        m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);

                    sp.RemoveAttachment(so);
                }

                m_scene.DeleteSceneObject(so, false, false);
                so.RemoveScriptInstances(true);
                so.Clear();

                return;
            }

            if (DebugLevel > 0)
                m_log.DebugFormat(
                    "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", 
                    so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name);

            // Scripts MUST be snapshotted before the object is
            // removed from the scene because doing otherwise will
            // clobber the run flag
            // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
            // scripts performing attachment operations at the same time.  Getting object states stops the scripts.
            string scriptedState = PrepareScriptInstanceForSave(so, true);

            lock (sp.AttachmentsSyncLock)
            {
                // Save avatar attachment information
//                m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);

                bool changed = sp.Appearance.DetachAttachment(so.FromItemID);
                if (changed && m_scene.AvatarFactory != null)
                    m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);

                sp.RemoveAttachment(so);
                UpdateDetachedObject(sp, so, scriptedState);
            }
        }
コード例 #3
0
        public SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val)
        {
            Scene sogScene = sog.m_scene;
            IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface<IEntityTransferModule>();

            Vector3 newpos = Vector3.Zero;
            OpenSim.Services.Interfaces.GridRegion destination = null;

            if (sog.RootPart.DIE_AT_EDGE)
            {               
                try
                {
                    sogScene.DeleteSceneObject(sog, false);
                }
                catch (Exception)
                {
                    m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
                }
                return sog;
            }

            if (sog.RootPart.RETURN_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    List<uint> localIDs = new List<uint>();
                    localIDs.Add(sog.RootPart.LocalId);
                    sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition,
                        "Returned at region cross");
                    sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero);                   
                }
                catch (Exception)
                {
                    m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
                }
                return sog;
            }

            if (sog.m_rootPart.KeyframeMotion != null)
                sog.m_rootPart.KeyframeMotion.StartCrossingCheck();

            if (entityTransfer == null)
                return sog;

            destination = entityTransfer.GetObjectDestination(sog, val, out newpos);
            if (destination == null)
                return sog;

            if (sog.m_sittingAvatars.Count == 0)
            {
                entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, true);
                return sog;
            }

            string reason = String.Empty;
            EntityTransferContext ctx = new EntityTransferContext();

            foreach (ScenePresence av in sog.m_sittingAvatars)
            {
                // We need to cross these agents. First, let's find
                // out if any of them can't cross for some reason.
                // We have to deny the crossing entirely if any
                // of them are banned. Alternatively, we could
                // unsit banned agents....

                // We set the avatar position as being the object
                // position to get the region to send to
                if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason))
                {
                    return sog;
                }
                m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
            }

            // We unparent the SP quietly so that it won't
            // be made to stand up

            List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();

            foreach (ScenePresence av in sog.m_sittingAvatars)
            {
                byte cflags = 1;

                avtocrossInfo avinfo = new avtocrossInfo();
                SceneObjectPart parentPart = sogScene.GetSceneObjectPart(av.ParentID);
                if (parentPart != null)
                {
                    av.ParentUUID = parentPart.UUID;
                    if(parentPart.SitTargetAvatar == av.UUID)
                        cflags = 7; // low 3 bits set
                    else
                        cflags = 3;
                }

                // 1 is crossing
                // 2 is sitting
                // 4 is sitting at sittarget
                av.crossingFlags = cflags;

                avinfo.av = av;
                avinfo.ParentID = av.ParentID;
                avsToCross.Add(avinfo);

                av.PrevSitOffset = av.OffsetPosition;
                av.ParentID = 0;
            }

            if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, false))
            {
                foreach (avtocrossInfo avinfo in avsToCross)
                {
                    ScenePresence av = avinfo.av;
                    if (!av.IsInTransit) // just in case...
                    {
                        m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);

                        av.IsInTransit = true;

//                        CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
//                        d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
                        entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, ctx);
                        if (av.IsChildAgent)
                        {
                            // avatar crossed do some extra cleanup
                            if (av.ParentUUID != UUID.Zero)
                            {
                                av.ClearControls();
                                av.ParentPart = null;
                            }
                        }
                        else
                        {
                            // avatar cross failed we need do dedicated standUp
                            // part of it was done at CrossAgentToNewRegionAsync
                            // so for now just remove the sog controls
                            // this may need extra care 
                            av.UnRegisterSeatControls(sog.UUID);
                        }

                        av.ParentUUID = UUID.Zero;
                        // In any case
                        av.IsInTransit = false;
                        av.crossingFlags = 0;
                        m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname);
                    }
                    else
                        m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val);
                }
                avsToCross.Clear();
                sog.RemoveScriptInstances(true);
                sog.Clear();
                return sog;
            }
            else // cross failed, put avas back ??
            {
                foreach (avtocrossInfo avinfo in avsToCross)
                {
                    ScenePresence av = avinfo.av;
                    av.ParentUUID = UUID.Zero;
                    av.ParentID = avinfo.ParentID;
                    av.crossingFlags = 0;
                }
            }
            avsToCross.Clear();

            return sog;
        }
コード例 #4
0
        private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so, string scriptedState)
        {
            // Don't save attachments for HG visitors, it
            // messes up their inventory. When a HG visitor logs
            // out on a foreign grid, their attachments will be
            // reloaded in the state they were in when they left
            // the home grid. This is best anyway as the visited
            // grid may use an incompatible script engine.
            bool saveChanged
                    = sp.PresenceType != PresenceType.Npc
                    && (m_scene.UserManagementModule == null
                    || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));

            // Remove the object from the scene so no more updates
            // are sent. Doing this before the below changes will ensure
            // updates can't cause "HUD artefacts"
           
            m_scene.DeleteSceneObject(so, false, false);

            // Prepare sog for storage
            so.AttachedAvatar = UUID.Zero;
            so.RootPart.SetParentLocalId(0);
            so.IsAttachment = false;

            if (saveChanged)
            {
                // We cannot use AbsolutePosition here because that would
                // attempt to cross the prim as it is detached
                so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });

                UpdateKnownItem(sp, so, scriptedState);
            }

            // Now, remove the scripts
            so.RemoveScriptInstances(true);
            so.Clear();
        }