private void CloseNeighborAgents(GridRegion oldRegion, GridRegion destination, UUID AgentID) { Util.FireAndForget(delegate(object o) { //Sleep for 5 seconds to give the agents a chance to cross and get everything right Thread.Sleep(5000); //Now do a sanity check on the avatar IClientCapsService clientCaps = m_registry.RequestModuleInterface <ICapsService>().GetClientCapsService(AgentID); if (clientCaps == null) { return; } IRegionClientCapsService rootRegionCaps = clientCaps.GetRootCapsService(); if (rootRegionCaps == null) { return; } IRegionClientCapsService ourRegionCaps = clientCaps.GetCapsService(destination.RegionHandle); if (ourRegionCaps == null) { return; } //If they handles arn't the same, the agent moved, and we can't be sure that we should close these agents if (rootRegionCaps.RegionHandle != ourRegionCaps.RegionHandle) { return; } INeighborService service = m_registry.RequestModuleInterface <INeighborService>(); if (service != null) { List <GridRegion> NeighborsOfOldRegion = service.GetNeighbors(oldRegion); List <GridRegion> NeighborsOfDestinationRegion = service.GetNeighbors(destination); List <GridRegion> byebyeRegions = new List <GridRegion>(NeighborsOfOldRegion); byebyeRegions.Add(oldRegion); //Add the old region, because it might need closed too byebyeRegions.RemoveAll(delegate(GridRegion r) { if (r.RegionID == destination.RegionID) { return(true); } else if (NeighborsOfDestinationRegion.Contains(r)) { return(true); } return(false); }); if (byebyeRegions.Count > 0) { m_log.Info("[AgentProcessing]: Closing " + byebyeRegions.Count + " child agents around " + oldRegion.RegionName); SendCloseChildAgent(AgentID, byebyeRegions); } } }); }
/// <summary> /// Now that we are fully done, add the child agents from other regions /// </summary> /// <param name="data"></param> private void InformNeighborsAboutUs(IScene scene) { //Tell the neighbor service about it INeighborService service = scene.RequestModuleInterface <INeighborService>(); if (service != null) { service.InformRegionsNeighborsThatRegionIsUp(scene.RegionInfo); } }
public NeighborHandler(INeighborService service, IAuthenticationService authentication, IConfigSource config) : base("POST", "/region") { m_NeighborService = service; m_AuthenticationService = authentication; IConfig neighborsConfig = config.Configs["NeighborService"]; if (neighborsConfig != null) { m_threatLevel = (NeighborThreatLevel)Enum.Parse(typeof(NeighborThreatLevel), neighborsConfig.GetString("ThreatLevel", "Low")); } }
public void Start(IConfigSource config, IRegistryCore registry) { IConfig handlerConfig = config.Configs["Handlers"]; if (handlerConfig.GetString("NeighborInHandler", "") != Name) return; IHttpServer server = registry.RequestModuleInterface<ISimulationBase>().GetHttpServer((uint)handlerConfig.GetInt("NeighborInHandlerPort")); m_NeighborService = registry.RequestModuleInterface<INeighborService>(); m_AuthenticationService = registry.RequestModuleInterface<IAuthenticationService>(); if (m_NeighborService == null) { m_log.Error("[NEIGHBOR IN CONNECTOR]: neighbor service was not provided"); return; } server.AddStreamHandler(new NeighborHandler(m_NeighborService.InnerService, m_AuthenticationService, config)); }
public bool EnableChildAgentsForRegion(GridRegion requestingRegion) { int count = 0; bool informed = true; INeighborService neighborService = m_registry.RequestModuleInterface <INeighborService>(); if (neighborService != null) { List <GridRegion> neighbors = neighborService.GetNeighbors(requestingRegion, 0); foreach (GridRegion neighbor in neighbors) { //m_log.WarnFormat("--> Going to send child agent to {0}, new agent {1}", neighbour.RegionName, newAgent); IRegionCapsService regionCaps = m_registry.RequestModuleInterface <ICapsService>().GetCapsForRegion(neighbor.RegionHandle); if (regionCaps == null) //If there isn't a region caps, there isn't an agent in this sim { continue; } List <UUID> usersInformed = new List <UUID>(); foreach (IRegionClientCapsService regionClientCaps in regionCaps.GetClients()) { if (usersInformed.Contains(regionClientCaps.AgentID)) //Only inform agents once { continue; } AgentCircuitData regionCircuitData = regionClientCaps.CircuitData.Copy(); regionCircuitData.child = true; //Fix child agent status string reason; //Tell the region about it if (!InformClientOfNeighbor(regionClientCaps.AgentID, requestingRegion.RegionHandle, regionCircuitData, requestingRegion, (uint)TeleportFlags.Default, null, out reason)) { informed = false; } else { usersInformed.Add(regionClientCaps.AgentID); } } count++; } } return(informed); }
/// <summary> /// This is the method that shuts down the scene. /// </summary> public void Close() { m_log.InfoFormat("[Scene]: Closing down the single simulator: {0}", RegionInfo.RegionName); // Kick all ROOT agents with the message, 'The simulator is going down' ForEachScenePresence(delegate(IScenePresence avatar) { if (!avatar.IsChildAgent) { avatar.ControllingClient.Kick("The simulator is going down."); } }); IEntityTransferModule transferModule = RequestModuleInterface <IEntityTransferModule> (); if (transferModule != null) { foreach (IScenePresence avatar in GetScenePresences()) { transferModule.IncomingCloseAgent(this, avatar.UUID); } } ShouldRunHeartbeat = false; //Stop the heartbeat //Now close the tracker monitor.Stop(); if (m_sceneGraph.PhysicsScene != null) { m_sceneGraph.PhysicsScene.Dispose(); } //Tell the neighbors that this region is now down INeighborService service = RequestModuleInterface <INeighborService>(); if (service != null) { service.InformNeighborsThatRegionIsDown(RegionInfo); } // Stop updating the scene objects and agents. shuttingdown = true; m_sceneGraph.Close(); }
protected void SendChildAgentUpdateAsync(AgentPosition agentpos, IRegionClientCapsService regionCaps) { //We need to send this update out to all the child agents this region has INeighborService service = m_registry.RequestModuleInterface <INeighborService>(); if (service != null) { ISimulationService SimulationService = m_registry.RequestModuleInterface <ISimulationService>(); if (SimulationService != null) { //Set the last location in the database IAgentInfoService agentInfoService = m_registry.RequestModuleInterface <IAgentInfoService>(); if (agentInfoService != null) { //Find the lookAt vector Vector3 lookAt = new Vector3(agentpos.AtAxis.X, agentpos.AtAxis.Y, 0); if (lookAt != Vector3.Zero) { lookAt = Util.GetNormalizedVector(lookAt); } //Update the database agentInfoService.SetLastPosition(regionCaps.AgentID.ToString(), regionCaps.Region.RegionID, agentpos.Position, lookAt); } //Also update the service itself regionCaps.LastPosition = agentpos.Position; //Tell all neighbor regions about the new position as well List <GridRegion> ourNeighbors = service.GetNeighbors(regionCaps.Region); foreach (GridRegion region in ourNeighbors) { //Update all the neighbors that we have if (!SimulationService.UpdateAgent(region, agentpos)) { m_log.Info("[AgentProcessing]: Failed to inform " + region.RegionName + " about updating agent. "); } } } } }
public void Start(IConfigSource config, IRegistryCore registry) { IConfig handlerConfig = config.Configs["Handlers"]; if (handlerConfig.GetString("NeighborInHandler", "") != Name) { return; } IHttpServer server = registry.RequestModuleInterface <ISimulationBase>().GetHttpServer((uint)handlerConfig.GetInt("NeighborInHandlerPort")); m_NeighborService = registry.RequestModuleInterface <INeighborService>(); m_AuthenticationService = registry.RequestModuleInterface <IAuthenticationService>(); if (m_NeighborService == null) { m_log.Error("[NEIGHBOR IN CONNECTOR]: neighbor service was not provided"); return; } server.AddStreamHandler(new NeighborHandler(m_NeighborService.InnerService, m_AuthenticationService, config)); }
public bool EnableChildAgents(UUID AgentID, ulong requestingRegion, int DrawDistance, AgentCircuitData circuit) { int count = 0; bool informed = true; INeighborService neighborService = m_registry.RequestModuleInterface <INeighborService>(); if (neighborService != null) { int x, y; Util.UlongToInts(requestingRegion, out x, out y); GridRegion ourRegion = m_registry.RequestModuleInterface <IGridService>().GetRegionByPosition(UUID.Zero, x, y); if (ourRegion == null) { m_log.Info("[AgentProcessing]: Failed to inform neighbors about new agent, could not find our region."); return(false); } List <GridRegion> neighbors = neighborService.GetNeighbors(ourRegion, DrawDistance); foreach (GridRegion neighbor in neighbors) { //m_log.WarnFormat("--> Going to send child agent to {0}, new agent {1}", neighbour.RegionName, newAgent); if (neighbor.RegionHandle != requestingRegion) { string reason; AgentCircuitData regionCircuitData = circuit.Copy(); regionCircuitData.child = true; //Fix child agent status if (!InformClientOfNeighbor(AgentID, requestingRegion, regionCircuitData, neighbor, (uint)TeleportFlags.Default, null, out reason)) { informed = false; } } count++; } } return(informed); }
public bool CrossAgent(GridRegion crossingRegion, Vector3 pos, Vector3 velocity, AgentCircuitData circuit, AgentData cAgent, UUID AgentID, ulong requestingRegion, out string reason) { try { IClientCapsService clientCaps = m_registry.RequestModuleInterface <ICapsService>().GetClientCapsService(AgentID); IRegionClientCapsService requestingRegionCaps = clientCaps.GetCapsService(requestingRegion); ISimulationService SimulationService = m_registry.RequestModuleInterface <ISimulationService>(); if (SimulationService != null) { //Note: we have to pull the new grid region info as the one from the region cannot be trusted IGridService GridService = m_registry.RequestModuleInterface <IGridService>(); if (GridService != null) { //Set the user in transit so that we block duplicate tps and reset any cancelations if (!SetUserInTransit(AgentID)) { reason = "Already in a teleport"; return(false); } bool result = false; crossingRegion = GridService.GetRegionByUUID(UUID.Zero, crossingRegion.RegionID); if (!SimulationService.UpdateAgent(crossingRegion, cAgent)) { m_log.Warn("[AgentProcessing]: Failed to cross agent " + AgentID + " because region did not accept it. Resetting."); reason = "Failed to update an agent"; } else { IEventQueueService EQService = m_registry.RequestModuleInterface <IEventQueueService>(); //Add this for the viewer, but not for the sim, seems to make the viewer happier int XOffset = crossingRegion.RegionLocX - requestingRegionCaps.RegionX; pos.X += XOffset; int YOffset = crossingRegion.RegionLocY - requestingRegionCaps.RegionY; pos.Y += YOffset; IRegionClientCapsService otherRegion = clientCaps.GetCapsService(crossingRegion.RegionHandle); //Tell the client about the transfer EQService.CrossRegion(crossingRegion.RegionHandle, pos, velocity, crossingRegion.ExternalEndPoint, otherRegion.CapsUrl, AgentID, circuit.SessionID, crossingRegion.RegionSizeX, crossingRegion.RegionSizeY, requestingRegion); result = WaitForCallback(AgentID); if (!result) { m_log.Warn("[AgentProcessing]: Callback never came in crossing agent " + circuit.AgentID + ". Resetting."); reason = "Crossing timed out"; } else { // Next, let's close the child agent connections that are too far away. INeighborService service = m_registry.RequestModuleInterface <INeighborService>(); if (service != null) { //Fix the root agent status otherRegion.RootAgent = true; requestingRegionCaps.RootAgent = false; CloseNeighborAgents(requestingRegionCaps.Region, crossingRegion, AgentID); } reason = ""; } } //All done ResetFromTransit(AgentID); return(result); } else { reason = "Could not find the GridService"; } } else { reason = "Could not find the SimulationService"; } } catch (Exception ex) { m_log.WarnFormat("[AgentProcessing]: Failed to cross an agent into a new region. {0}", ex.ToString()); } ResetFromTransit(AgentID); reason = "Exception occured"; return(false); }
public bool TeleportAgent(GridRegion destination, uint TeleportFlags, int DrawDistance, AgentCircuitData circuit, AgentData agentData, UUID AgentID, ulong requestingRegion, out string reason) { IClientCapsService clientCaps = m_registry.RequestModuleInterface <ICapsService>().GetClientCapsService(AgentID); IRegionClientCapsService regionCaps = clientCaps.GetCapsService(requestingRegion); if (regionCaps == null || !regionCaps.RootAgent) { reason = ""; return(false); } bool result = false; try { bool callWasCanceled = false; ISimulationService SimulationService = m_registry.RequestModuleInterface <ISimulationService>(); if (SimulationService != null) { //Set the user in transit so that we block duplicate tps and reset any cancelations if (!SetUserInTransit(AgentID)) { reason = "Already in a teleport"; return(false); } //Note: we have to pull the new grid region info as the one from the region cannot be trusted IGridService GridService = m_registry.RequestModuleInterface <IGridService>(); if (GridService != null) { destination = GridService.GetRegionByUUID(UUID.Zero, destination.RegionID); //Inform the client of the neighbor if needed circuit.child = false; //Force child status to the correct type if (!InformClientOfNeighbor(AgentID, requestingRegion, circuit, destination, TeleportFlags, agentData, out reason)) { ResetFromTransit(AgentID); return(false); } } else { reason = "Could not find the grid service"; ResetFromTransit(AgentID); return(false); } IEventQueueService EQService = m_registry.RequestModuleInterface <IEventQueueService>(); IRegionClientCapsService otherRegion = clientCaps.GetCapsService(destination.RegionHandle); EQService.TeleportFinishEvent(destination.RegionHandle, destination.Access, destination.ExternalEndPoint, otherRegion.CapsUrl, 4, AgentID, TeleportFlags, destination.RegionSizeX, destination.RegionSizeY, requestingRegion); // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation // that the client contacted the destination before we send the attachments and close things here. result = WaitForCallback(AgentID, out callWasCanceled); if (!result) { //It says it failed, lets call the sim and check IAgentData data = null; result = SimulationService.RetrieveAgent(destination, AgentID, out data); } if (!result) { if (!callWasCanceled) { m_log.Warn("[AgentProcessing]: Callback never came for teleporting agent " + AgentID + ". Resetting."); } INeighborService service = m_registry.RequestModuleInterface <INeighborService>(); if (service != null) { //Close the agent at the place we just created if it isn't a neighbor if (service.IsOutsideView(regionCaps.RegionX, destination.RegionLocX, regionCaps.Region.RegionSizeX, destination.RegionSizeX, regionCaps.RegionY, destination.RegionLocY, regionCaps.Region.RegionSizeY, destination.RegionSizeY)) { SimulationService.CloseAgent(destination, AgentID); } } clientCaps.RemoveCAPS(destination.RegionHandle); if (!callWasCanceled) { reason = "The teleport timed out"; } else { reason = "Cancelled"; } } else { //Fix the root agent status otherRegion.RootAgent = true; regionCaps.RootAgent = false; // Next, let's close the child agent connections that are too far away. CloseNeighborAgents(regionCaps.Region, destination, AgentID); reason = ""; } } else { reason = "No SimulationService found!"; } } catch (Exception ex) { m_log.WarnFormat("[AgentProcessing]: Exception occured during agent teleport, {0}", ex.ToString()); reason = "Exception occured."; } //All done ResetFromTransit(AgentID); return(result); }