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); }