public void llUnSit(string id) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } UUID key = new UUID(); if (UUID.TryParse(id, out key)) { IScenePresence av = World.GetScenePresence(key); if (av != null) { if (m_host.ParentEntity.SitTargetAvatar.Contains(key)) { // if the avatar is sitting on this object, then // we can unsit them. We don't want random scripts unsitting random people // Lets avoid the popcorn avatar scenario. av.StandUp(); } else { // If the object owner also owns the parcel // or // if the land is group owned and the object is group owned by the same group // or // if the object is owned by a person with estate access. IParcelManagementModule parcelManagement = World.RequestModuleInterface <IParcelManagementModule>(); if (parcelManagement != null) { ILandObject parcel = parcelManagement.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); if (parcel != null) { if (m_host.OwnerID == parcel.LandData.OwnerID || (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) { av.StandUp(); } } } } } } }
/// <summary> /// Synchronously delete the given object from the scene. /// </summary> /// <param name="group">Object Id</param> /// <param name="DeleteScripts">Remove the scripts from the ScriptEngine as well</param> /// <param name="removeFromDatabase">Remove from the database?</param> protected bool DeleteSceneObject(ISceneEntity group, bool DeleteScripts, bool removeFromDatabase) { //MainConsole.Instance.DebugFormat("[Backup]: Deleting scene object {0} {1}", group.Name, group.UUID); lock (group.SitTargetAvatar) { if (group.SitTargetAvatar.Count != 0) { UUID[] ids = new UUID[group.SitTargetAvatar.Count]; group.SitTargetAvatar.CopyTo(ids); foreach (UUID avID in ids) { //Don't screw up avatar's that are sitting on us! IScenePresence SP = m_scene.GetScenePresence(avID); if (SP != null) { SP.StandUp(); } } } } // Serialise calls to RemoveScriptInstances to avoid // deadlocking on m_parts inside SceneObjectGroup if (DeleteScripts) { group.RemoveScriptInstances(true); } foreach (ISceneChildEntity part in group.ChildrenEntities()) { IScriptControllerModule m = m_scene.RequestModuleInterface <IScriptControllerModule>(); if (m != null) { m.RemoveAllScriptControllers(part); } } if (group.RootChild.PhysActor != null) { //Remove us from the physics sim m_scene.PhysicsScene.DeletePrim(group.RootChild.PhysActor); //We MUST leave this to the PhysicsScene or it will hate us forever! //group.RootChild.PhysActor = null; } if (!group.IsAttachment) { m_scene.SimulationDataService.Tainted(); } if (m_scene.SceneGraph.DeleteEntity(group)) { // We need to keep track of this state in case this group is still queued for backup. group.IsDeleted = true; m_scene.EventManager.TriggerObjectBeingRemovedFromScene(group); return(true); } //MainConsole.Instance.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); return(false); }
/// <summary> /// Tell a single agent to disconnect from the region. /// Does not send the DisableSimulator EQM or close child agents /// </summary> /// <param name="?"></param> /// <param name="presence"></param> /// <param name="forceClose"></param> /// <returns></returns> public bool RemoveAgent(IScenePresence presence, bool forceClose) { AddAsyncEvent(delegate { presence.ControllingClient.Close(forceClose); foreach (IClientNetworkServer cns in m_clientServers) { cns.RemoveClient(presence.ControllingClient); } if (presence.ParentID != UUID.Zero) { presence.StandUp(); } EventManager.TriggerOnClosingClient(presence.ControllingClient); EventManager.TriggerOnRemovePresence(presence); ForEachClient( delegate(IClientAPI client) { if (client.AgentId != presence.UUID) { //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway try { client.SendKillObject(presence.Scene.RegionInfo.RegionHandle, new IEntity[] { presence }); } catch (NullReferenceException) { } } }); // Remove the avatar from the scene m_sceneGraph.RemoveScenePresence(presence); m_clientManager.Remove(presence.UUID); try { presence.Close(); } catch (Exception e) { MainConsole.Instance.Error( "[SCENE] Scene.cs:RemoveClient:Presence.Close exception: " + e); } //Remove any interfaces it might have stored presence.RemoveAllInterfaces(); AuthenticateHandler.RemoveCircuit(presence.UUID); //MainConsole.Instance.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //MainConsole.Instance.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); }); return(true); }
public void botStandUp(string bot) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "botStandUp", m_host, "bot", m_itemID)) { return; } IScenePresence sp = World.GetScenePresence(UUID.Parse(bot)); if (sp == null) { return; } sp.StandUp(); }
public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest"); if (finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } MainConsole.Instance.DebugFormat("[Entity transfer]: Request Teleport to {0}:{1}/{2}", finalDestination.ServerURI, finalDestination.RegionName, position); sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving"); sp.SetAgentLeaving(finalDestination); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (sp.ParentID != UUID.Zero) { sp.StandUp(); } AgentCircuitData agentCircuit = BuildCircuitDataForPresence(sp, position); AgentData agent = new AgentData(); sp.CopyTo(agent); // Fix the position agent.Position = position; ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface <ISyncMessagePosterService> (); if (syncPoster != null) { // This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish // messages if they need to be called and deals with the callback syncPoster.PostToServer(SyncMessageHelper.TeleportAgent((int)sp.DrawDistance, agentCircuit, agent, teleportFlags, finalDestination, sp.Scene.RegionInfo.RegionID)); } }
/// <summary> /// Tell a single agent to disconnect from the region. /// Does not send the DisableSimulator EQM or close child agents /// </summary> /// <param name="?"></param> /// <returns></returns> public bool RemoveAgent(IScenePresence presence) { presence.ControllingClient.Close(); if (presence.ParentID != UUID.Zero) { presence.StandUp(); } EventManager.TriggerClientClosed(presence.UUID, this); EventManager.TriggerOnClosingClient(presence.ControllingClient); EventManager.TriggerOnRemovePresence(presence); ForEachClient( delegate(IClientAPI client) { //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway try { client.SendKillObject(presence.Scene.RegionInfo.RegionHandle, new IEntity[] { presence }); } catch (NullReferenceException) { } }); try { presence.Close(); } catch (Exception e) { m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); } //Remove any interfaces it might have stored presence.RemoveAllInterfaces(); // Remove the avatar from the scene m_sceneGraph.RemoveScenePresence(presence); m_clientManager.Remove(presence.UUID); AuthenticateHandler.RemoveCircuit(presence.ControllingClient.CircuitCode); //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); return(true); }
/// <summary> /// Tell a single agent to disconnect from the region. /// Does not send the DisableSimulator EQM or close child agents /// </summary> /// <param name="?"></param> /// <param name="presence"></param> /// <param name="forceClose"></param> /// <returns></returns> public bool RemoveAgent(IScenePresence presence, bool forceClose) { AddAsyncEvent(delegate { presence.ControllingClient.Close(forceClose); foreach (IClientNetworkServer cns in m_clientServers) cns.RemoveClient(presence.ControllingClient); if (presence.ParentID != UUID.Zero) presence.StandUp(); EventManager.TriggerOnClosingClient(presence.ControllingClient); EventManager.TriggerOnRemovePresence(presence); ForEachClient( delegate(IClientAPI client) { if (client.AgentId != presence.UUID) { //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway try { client.SendKillObject(presence.Scene.RegionInfo.RegionHandle, new IEntity[] {presence}); } catch (NullReferenceException) { } } }); // Remove the avatar from the scene m_sceneGraph.RemoveScenePresence(presence); m_clientManager.Remove(presence.UUID); try { presence.Close(); } catch (Exception e) { MainConsole.Instance.Error( "[SCENE] Scene.cs:RemoveClient:Presence.Close exception: " + e); } //Remove any interfaces it might have stored presence.RemoveAllInterfaces(); AuthenticateHandler.RemoveCircuit(presence.UUID); //MainConsole.Instance.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //MainConsole.Instance.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); }); return true; }
public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest"); if (finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } MainConsole.Instance.DebugFormat( "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}/{2}", finalDestination.ServerURI, finalDestination.RegionName, position); sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving"); sp.SetAgentLeaving(finalDestination); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (sp.ParentID != UUID.Zero) sp.StandUp(); AgentCircuitData agentCircuit = BuildCircuitDataForPresence(sp, position); AgentData agent = new AgentData(); sp.CopyTo(agent); //Fix the position agent.Position = position; ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { //This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish // messages if they need to be called and deals with the callback syncPoster.PostToServer(SyncMessageHelper.TeleportAgent((int) sp.DrawDistance, agentCircuit, agent, teleportFlags, finalDestination, sp.Scene.RegionInfo.RegionID)); } }
public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest"); if (finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } MainConsole.Instance.DebugFormat( "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}/{2}", finalDestination.ServerURI, finalDestination.RegionName, position); sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving"); sp.SetAgentLeaving(finalDestination); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (sp.ParentID != UUID.Zero) sp.StandUp(); AgentCircuitData agentCircuit = BuildCircuitDataForPresence(sp, position); AgentData agent = new AgentData(); sp.CopyTo(agent); //Fix the position agent.Position = position; IEventQueueService eq = sp.Scene.RequestModuleInterface<IEventQueueService>(); if (eq != null) { ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { //This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish // messages if they need to be called and deals with the callback syncPoster.Get(SyncMessageHelper.TeleportAgent((int)sp.DrawDistance, agentCircuit, agent, teleportFlags, finalDestination, sp.Scene.RegionInfo.RegionHandle), sp.UUID, sp.Scene.RegionInfo.RegionHandle, (map) => { if (map == null || !map["success"].AsBoolean()) { // Fix the agent status sp.IsChildAgent = false; //Tell modules about it sp.AgentFailedToLeave(); sp.ControllingClient.SendTeleportFailed(map != null ? map["Reason"].AsString() : "Teleport Failed"); return; } //Get the new destintation, it may have changed if (map.ContainsKey("Destination")) { finalDestination = new GridRegion(); finalDestination.FromOSD((OSDMap)map["Destination"]); } MakeChildAgent(sp, finalDestination, false); }); } } }
public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest"); if (finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}/{2}", finalDestination.ServerURI, finalDestination.RegionName, position); sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving"); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (sp.ParentID != UUID.Zero) sp.StandUp(); //Make sure that all attachments are ready for the teleport IAttachmentsModule attModule = sp.Scene.RequestModuleInterface<IAttachmentsModule>(); if (attModule != null) attModule.ValidateAttachments(sp.UUID); AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; //The agent will be a root agent agentCircuit.child = false; //Make sure the appearnace is right IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule> (); if(appearance != null) agentCircuit.Appearance = appearance.Appearance; AgentData agent = new AgentData(); sp.CopyTo(agent); //Fix the position agent.Position = position; IEventQueueService eq = sp.Scene.RequestModuleInterface<IEventQueueService>(); if (eq != null) { ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { AgentCircuitData oldCircuit = sp.Scene.AuthenticateHandler.AgentCircuitsByUUID[sp.UUID]; agentCircuit.ServiceURLs = oldCircuit.ServiceURLs; agentCircuit.firstname = oldCircuit.firstname; agentCircuit.lastname = oldCircuit.lastname; agentCircuit.ServiceSessionID = oldCircuit.ServiceSessionID; //This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish // messages if they need to be called and deals with the callback OSDMap map = syncPoster.Get(SyncMessageHelper.TeleportAgent((int)sp.DrawDistance, agentCircuit, agent, teleportFlags, finalDestination, sp.Scene.RegionInfo.RegionHandle), sp.UUID, sp.Scene.RegionInfo.RegionHandle); bool result = false; if(map != null) result = map["Success"].AsBoolean(); if (!result) { // Fix the agent status sp.IsChildAgent = false; //Fix user's attachments attModule.RezAttachments (sp); if (map != null) sp.ControllingClient.SendTeleportFailed (map["Reason"].AsString ()); else sp.ControllingClient.SendTeleportFailed ("Teleport Failed"); return; } else { //Get the new destintation, it may have changed if(map.ContainsKey("Destination")) { finalDestination = new GridRegion(); finalDestination.FromOSD((OSDMap)map["Destination"]); } } } } MakeChildAgent(sp, finalDestination); }
/// <summary> /// Tell a single agent to disconnect from the region. /// Does not send the DisableSimulator EQM or close child agents /// </summary> /// <param name="?"></param> /// <returns></returns> public bool RemoveAgent (IScenePresence presence) { presence.ControllingClient.Close (); if (presence.ParentID != UUID.Zero) { presence.StandUp (); } EventManager.TriggerClientClosed (presence.UUID, this); EventManager.TriggerOnClosingClient (presence.ControllingClient); EventManager.TriggerOnRemovePresence (presence); ForEachClient ( delegate (IClientAPI client) { //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway try { client.SendKillObject (presence.Scene.RegionInfo.RegionHandle, new IEntity[] { presence }); } catch (NullReferenceException) { } }); try { presence.Close (); } catch (Exception e) { m_log.Error ("[SCENE] Scene.cs:RemoveClient:Presence.Close exception: " + e.ToString ()); } //Remove any interfaces it might have stored presence.RemoveAllInterfaces (); // Remove the avatar from the scene m_sceneGraph.RemoveScenePresence (presence); m_clientManager.Remove (presence.UUID); AuthenticateHandler.RemoveCircuit (presence.ControllingClient.CircuitCode); //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); return true; }
/// <summary> /// Synchronously delete the given object from the scene. /// </summary> /// <param name="group">Object Id</param> /// <param name="DeleteScripts">Remove the scripts from the ScriptEngine as well</param> /// <param name="removeFromDatabase">Remove from the database?</param> protected bool DeleteSceneObject(SceneObjectGroup group, bool DeleteScripts, bool removeFromDatabase) { //m_log.DebugFormat("[Backup]: Deleting scene object {0} {1}", group.Name, group.UUID); lock (group.RootPart.SitTargetAvatar) { if (group.RootPart.SitTargetAvatar.Count != 0) { UUID[] ids = new UUID[group.RootPart.SitTargetAvatar.Count]; group.RootPart.SitTargetAvatar.CopyTo(ids); foreach (UUID avID in ids) { IScenePresence SP = m_scene.GetScenePresence(avID); if (SP != null) { SP.StandUp(); } } } } // Serialise calls to RemoveScriptInstances to avoid // deadlocking on m_parts inside SceneObjectGroup if (DeleteScripts) { group.RemoveScriptInstances(true); } foreach (SceneObjectPart part in group.ChildrenList) { if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) { m_scene.PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? } else if (part.PhysActor != null) { m_scene.PhysicsScene.RemovePrim(part.PhysActor); part.PhysActor = null; } } if (m_scene.SceneGraph.DeleteEntity(group)) { if (removeFromDatabase) { DeleteFromStorage(group.UUID); } // We need to keep track of this state in case this group is still queued for backup. group.IsDeleted = true; //Clear the update schedule HERE so that IsDeleted will not have to fire as well lock (group.ChildrenListLock) { foreach (SceneObjectPart part in group.ChildrenList) { //Make sure it isn't going to be updated again part.ClearUpdateSchedule(); } } m_scene.EventManager.TriggerObjectBeingRemovedFromScene(group); return(true); } //m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); return(false); }
public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest"); if (finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}/{2}", finalDestination.ServerURI, finalDestination.RegionName, position); sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving"); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (sp.ParentID != UUID.Zero) sp.StandUp(); //Make sure that all attachments are ready for the teleport IAttachmentsModule attModule = sp.Scene.RequestModuleInterface<IAttachmentsModule>(); if (attModule != null) attModule.ValidateAttachments(sp.UUID); AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; //The agent will be a root agent agentCircuit.child = false; //Make sure the appearnace is right IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule> (); agentCircuit.Appearance = appearance.Appearance; AgentData agent = new AgentData(); sp.CopyTo(agent); //Fix the position agent.Position = position; IEventQueueService eq = sp.Scene.RequestModuleInterface<IEventQueueService>(); if (eq != null) { ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { //This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish // messages if they need to be called and deals with the callback OSDMap map = syncPoster.Get(SyncMessageHelper.TeleportAgent((int)sp.DrawDistance, agentCircuit, agent, teleportFlags, finalDestination, sp.Scene.RegionInfo.RegionHandle), sp.UUID, sp.Scene.RegionInfo.RegionHandle); bool result = false; if(map != null) result = map["Success"].AsBoolean(); if (!result) { // Fix the agent status sp.IsChildAgent = false; if(map != null) sp.ControllingClient.SendTeleportFailed(map["Reason"].AsString()); else sp.ControllingClient.SendTeleportFailed ("Teleport Failed"); return; } } } sp.Scene.AuroraEventManager.FireGenericEventHandler ("SendingAttachments", new object[2] { finalDestination, sp }); //Kill the groups here, otherwise they will become ghost attachments // and stay in the sim, they'll get readded below into the new sim KillAttachments(sp); // Well, this is it. The agent is over there. KillEntity(sp.Scene, sp); //Make it a child agent for now... the grid will kill us later if we need to close sp.MakeChildAgent(); }
public virtual void DoTeleport(IScenePresence sp, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { sp.ControllingClient.SendTeleportProgress(teleportFlags, "sending_dest"); if (finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}/{2}", finalDestination.ServerURI, finalDestination.RegionName, position); sp.ControllingClient.SendTeleportProgress(teleportFlags, "arriving"); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (sp.ParentID != UUID.Zero) { sp.StandUp(); } //Make sure that all attachments are ready for the teleport IAttachmentsModule attModule = sp.Scene.RequestModuleInterface <IAttachmentsModule>(); if (attModule != null) { attModule.ValidateAttachments(sp.UUID); } AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; //The agent will be a root agent agentCircuit.child = false; //Make sure the appearnace is right IAvatarAppearanceModule appearance = sp.RequestModuleInterface <IAvatarAppearanceModule> (); agentCircuit.Appearance = appearance.Appearance; AgentData agent = new AgentData(); sp.CopyTo(agent); //Fix the position agent.Position = position; IEventQueueService eq = sp.Scene.RequestModuleInterface <IEventQueueService>(); if (eq != null) { ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface <ISyncMessagePosterService>(); if (syncPoster != null) { //This does CreateAgent and sends the EnableSimulator/EstablishAgentCommunication/TeleportFinish // messages if they need to be called and deals with the callback OSDMap map = syncPoster.Get(SyncMessageHelper.TeleportAgent((int)sp.DrawDistance, agentCircuit, agent, teleportFlags, finalDestination, sp.Scene.RegionInfo.RegionHandle), sp.Scene.RegionInfo.RegionHandle); bool result = map["Success"].AsBoolean(); if (!result) { // Fix the agent status sp.IsChildAgent = false; sp.ControllingClient.SendTeleportFailed(map["Reason"].AsString()); return; } } } //Kill the groups here, otherwise they will become ghost attachments // and stay in the sim, they'll get readded below into the new sim KillAttachments(sp); // Well, this is it. The agent is over there. KillEntity(sp.Scene, sp); //Make it a child agent for now... the grid will kill us later if we need to close sp.MakeChildAgent(); }