public virtual void InternalCross(IScenePresence agent, Vector3 attemptedPos, bool isFlying, GridRegion crossingRegion) { MainConsole.Instance.DebugFormat("[Entity transfer]: Crossing agent {0} to region {1}", agent.Name, crossingRegion.RegionName); try { agent.SetAgentLeaving(crossingRegion); AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = attemptedPos; if (isFlying) { cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; } AgentCircuitData agentCircuit = BuildCircuitDataForPresence(agent, attemptedPos); agentCircuit.TeleportFlags = (uint)TeleportFlags.ViaRegionID; //This does UpdateAgent and closing of child agents // messages if they need to be called ISyncMessagePosterService syncPoster = agent.Scene.RequestModuleInterface <ISyncMessagePosterService> (); if (syncPoster != null) { syncPoster.PostToServer(SyncMessageHelper.CrossAgent(crossingRegion, attemptedPos, agent.Velocity, agentCircuit, cAgent, agent.Scene.RegionInfo.RegionID)); } } catch (Exception ex) { MainConsole.Instance.Warn("[Entity transfer]: Exception in crossing: " + ex); } }
/// <summary> /// Tell a single agent to disconnect from the region. /// Does not send the DisableSimulator EQM or close child agents /// </summary> /// <param name="presence"></param> /// <param name="forceClose"></param> /// <returns></returns> public bool RemoveAgent(IScenePresence presence, bool forceClose) { presence.SetAgentLeaving(null); 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]: 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 void MakeChildAgent(IScenePresence sp, GridRegion finalDestination, bool isCrossing) { if (sp == null) { return; } sp.SetAgentLeaving(finalDestination); // 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(finalDestination); if (isCrossing) { sp.SuccessfulCrossingTransit(finalDestination); } }
public void MakeChildAgent(IScenePresence sp, GridRegion finalDestination, bool isCrossing) { if (sp == null) { return; } sp.SetAgentLeaving(finalDestination); // Kill the groups here, otherwise they will become ghost attachments // and stay in the sim, they'll get re-added 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(finalDestination); if (isCrossing) { sp.SuccessfulCrossingTransit(finalDestination); } }
public void MakeChildAgent(IScenePresence sp, GridRegion finalDestination, bool isCrossing) { if (sp == null) return; sp.SetAgentLeaving(finalDestination); //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(finalDestination); if (isCrossing) sp.SuccessfulCrossingTransit(finalDestination); }
public virtual void InternalCross(IScenePresence agent, Vector3 attemptedPos, bool isFlying, GridRegion crossingRegion) { MainConsole.Instance.DebugFormat("[EntityTransferModule]: Crossing agent {0} to region {1}", agent.Name, crossingRegion.RegionName); try { agent.SetAgentLeaving(crossingRegion); AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = attemptedPos; if (isFlying) cAgent.ControlFlags |= (uint) AgentManager.ControlFlags.AGENT_CONTROL_FLY; AgentCircuitData agentCircuit = BuildCircuitDataForPresence(agent, attemptedPos); agentCircuit.TeleportFlags = (uint) TeleportFlags.ViaRegionID; //This does UpdateAgent and closing of child agents // messages if they need to be called ISyncMessagePosterService syncPoster = agent.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { syncPoster.PostToServer(SyncMessageHelper.CrossAgent(crossingRegion, attemptedPos, agent.Velocity, agentCircuit, cAgent, agent.Scene.RegionInfo.RegionID)); } } catch (Exception ex) { MainConsole.Instance.Warn("[EntityTransferModule]: Exception in crossing: " + ex); } }
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 InternalCross(IScenePresence agent, Vector3 attemptedPos, bool isFlying, GridRegion crossingRegion) { if(agent.PhysicsActor != null) agent.PhysicsActor.IsPhysical = false; MainConsole.Instance.DebugFormat("[EntityTransferModule]: Crossing agent {0} to region {1}", agent.Name, crossingRegion.RegionName); try { agent.SetAgentLeaving(crossingRegion); AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = attemptedPos; if (isFlying) cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; AgentCircuitData agentCircuit = BuildCircuitDataForPresence(agent, attemptedPos); agentCircuit.teleportFlags = (uint)TeleportFlags.ViaRegionID; IEventQueueService eq = agent.Scene.RequestModuleInterface<IEventQueueService>(); if (eq != null) { //This does UpdateAgent and closing of child agents // messages if they need to be called ISyncMessagePosterService syncPoster = agent.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { syncPoster.Get(SyncMessageHelper.CrossAgent(crossingRegion, attemptedPos, agent.Velocity, agentCircuit, cAgent, agent.Scene.RegionInfo.RegionHandle), agent.UUID, agent.Scene.RegionInfo.RegionHandle, (map) => { if (map == null || !map["success"].AsBoolean()) { //Tell modules that we have failed agent.AgentFailedToLeave(); if (map != null) { if (map.ContainsKey("Note") && !map["Note"].AsBoolean()) return; agent.ControllingClient.SendTeleportFailed(map["Reason"].AsString()); } else agent.ControllingClient.SendTeleportFailed("TP Failed"); if (agent.PhysicsActor != null) agent.PhysicsActor.IsPhysical = true; //Fix the setting that we set earlier // In any case agent.FailedCrossingTransit(crossingRegion); return; } //We're killing the animator and the physics actor, so we don't need to worry about agent.PhysicsActor.IsPhysical agent.MakeChildAgent(crossingRegion); //Revolution- We already were in this region... we don't need updates about the avatars we already know about, right? // OLD: now we have a child agent in this region. Request and send all interesting data about (root) agents in the sim //agent.SendOtherAgentsAvatarDataToMe(); //agent.SendOtherAgentsAppearanceToMe(); //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(agent); // In any case agent.SuccessfulCrossingTransit(crossingRegion); }); } } } catch(Exception ex) { MainConsole.Instance.Warn("[EntityTransferModule]: Exception in crossing: " + ex); } }
public void MakeChildAgent (IScenePresence sp, GridRegion finalDestination, bool markAgentAsLeaving) { if(sp == null) return; if(markAgentAsLeaving) sp.SetAgentLeaving(null); sp.Scene.AuroraEventManager.FireGenericEventHandler("SendingAttachments", new object[] { 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(finalDestination); }
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); }); } } }
/// <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) { presence.SetAgentLeaving(null); 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; }
/// <summary> /// This Closes child agents on neighboring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// </summary> protected IScenePresence CrossAgentToNewRegionAsync(IScenePresence agent, Vector3 pos, GridRegion crossingRegion, bool isFlying, bool positionIsAlreadyFixed) { MainConsole.Instance.DebugFormat("[EntityTransferModule]: Crossing agent {0} to region {1}", agent.Name, crossingRegion.RegionName); IScene m_scene = agent.Scene; try { if (!positionIsAlreadyFixed) { int xOffset = crossingRegion.RegionLocX - m_scene.RegionInfo.RegionLocX; int yOffset = crossingRegion.RegionLocY - m_scene.RegionInfo.RegionLocY; if (xOffset < 0) pos.X += m_scene.RegionInfo.RegionSizeX; else if (xOffset > 0) pos.X -= m_scene.RegionInfo.RegionSizeX; if (yOffset < 0) pos.Y += m_scene.RegionInfo.RegionSizeY; else if (yOffset > 0) pos.Y -= m_scene.RegionInfo.RegionSizeY; //Make sure that they are within bounds (velocity can push it out of bounds) if (pos.X < 0) pos.X = 1; if (pos.Y < 0) pos.Y = 1; if (pos.X > crossingRegion.RegionSizeX) pos.X = crossingRegion.RegionSizeX - 1; if (pos.Y > crossingRegion.RegionSizeY) pos.Y = crossingRegion.RegionSizeY - 1; } AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; if (isFlying) cAgent.ControlFlags |= (uint) AgentManager.ControlFlags.AGENT_CONTROL_FLY; AgentCircuitData agentCircuit = BuildCircuitDataForPresence(agent, pos); agentCircuit.teleportFlags = (uint) TeleportFlags.ViaRegionID; agent.SetAgentLeaving(crossingRegion); IEventQueueService eq = agent.Scene.RequestModuleInterface<IEventQueueService>(); if (eq != null) { //This does UpdateAgent and closing of child agents // messages if they need to be called ISyncMessagePosterService syncPoster = agent.Scene.RequestModuleInterface<ISyncMessagePosterService>(); if (syncPoster != null) { OSDMap map = syncPoster.Get(SyncMessageHelper.CrossAgent(crossingRegion, pos, agent.Velocity, agentCircuit, cAgent, agent.Scene.RegionInfo.RegionHandle), agent.UUID, agent.Scene.RegionInfo.RegionHandle); bool result = false; if (map != null) result = map["Success"].AsBoolean(); if (!result) { //Tell modules that we have failed agent.AgentFailedToLeave(); if (map != null) { if (map.ContainsKey("Note") && !map["Note"].AsBoolean()) return agent; agent.ControllingClient.SendTeleportFailed(map["Reason"].AsString()); } else agent.ControllingClient.SendTeleportFailed("TP Failed"); if (agent.PhysicsActor != null) agent.PhysicsActor.IsPhysical = true; //Fix the setting that we set earlier // In any case agent.FailedCrossingTransit(crossingRegion); return agent; } } } //We're killing the animator and the physics actor, so we don't need to worry about agent.PhysicsActor.IsPhysical agent.MakeChildAgent(crossingRegion); //Revolution- We already were in this region... we don't need updates about the avatars we already know about, right? // OLD: now we have a child agent in this region. Request and send all interesting data about (root) agents in the sim //agent.SendOtherAgentsAvatarDataToMe(); //agent.SendOtherAgentsAppearanceToMe(); //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(agent); } catch(Exception ex) { MainConsole.Instance.Warn("[EntityTransferModule]: Exception in crossing: " + ex); } // In any case agent.SuccessfulCrossingTransit(crossingRegion); return agent; }
public void MakeChildAgent(IScenePresence sp, GridRegion finalDestination, bool isCrossing) { if (sp == null) return; sp.SetAgentLeaving(finalDestination); // 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(finalDestination); if (isCrossing) sp.SuccessfulCrossingTransit(finalDestination); }
public void OnConnectionClose(IClientAPI client) { IScenePresence sp = null; client.Scene.TryGetScenePresence(client.AgentId, out sp); if (client.IsLoggingOut && sp != null & !sp.IsChildAgent) { sp.SetAgentLeaving(null); MainConsole.Instance.InfoFormat("[ActivityDetector]: Detected logout of user {0} in region {1}", client.Name, client.Scene.RegionInfo.RegionName); //Inform the grid service about it if (m_zombieAgents.Contains(client.AgentId)) { m_zombieAgents.Remove(client.AgentId); return; //They are a known zombie, just clear them out and go on with life! } AgentPosition agentpos = new AgentPosition { AgentID = sp.UUID, AtAxis = sp.CameraAtAxis, Center = sp.CameraPosition, Far = sp.DrawDistance, LeftAxis = Vector3.Zero, Position = sp.AbsolutePosition }; if (agentpos.Position.X > sp.Scene.RegionInfo.RegionSizeX) { agentpos.Position.X = sp.Scene.RegionInfo.RegionSizeX; } if (agentpos.Position.Y > sp.Scene.RegionInfo.RegionSizeY) { agentpos.Position.Y = sp.Scene.RegionInfo.RegionSizeY; } if (agentpos.Position.Z > sp.Scene.RegionInfo.RegionSizeZ) { agentpos.Position.Z = sp.Scene.RegionInfo.RegionSizeZ; } if (agentpos.Position.X < 0) { agentpos.Position.X = 0; } if (agentpos.Position.Y < 0) { agentpos.Position.Y = 0; } if (agentpos.Position.Z < 0) { agentpos.Position.Z = 0; } agentpos.RegionHandle = sp.Scene.RegionInfo.RegionHandle; agentpos.Size = sp.PhysicsActor != null ? sp.PhysicsActor.Size : new Vector3(0, 0, 1.8f); agentpos.UpAxis = Vector3.Zero; agentpos.Velocity = sp.Velocity; agentpos.UserGoingOffline = true; //Don't attempt to add us into other regions //Send the child agent data update ISyncMessagePosterService syncPoster = sp.Scene.RequestModuleInterface <ISyncMessagePosterService>(); if (syncPoster != null) { syncPoster.Post(SyncMessageHelper.SendChildAgentUpdate(agentpos, sp.Scene.RegionInfo.RegionHandle), sp.Scene.RegionInfo.RegionHandle); } client.Scene.RequestModuleInterface <ISyncMessagePosterService>().Get( SyncMessageHelper.AgentLoggedOut(client.AgentId, client.Scene.RegionInfo.RegionHandle), client.AgentId, client.Scene.RegionInfo.RegionHandle); } }