예제 #1
0
        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);
                    }
                }
            });
        }
예제 #2
0
        /// <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);
            }
        }
예제 #3
0
 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"));
     }
 }
예제 #4
0
        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"));
            }
        }
예제 #5
0
        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));
        }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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();
        }
예제 #8
0
        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. ");
                        }
                    }
                }
            }
        }
예제 #9
0
        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));
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }