public override bool InformClientOfNeighbor(UUID AgentID, ulong requestingRegion, AgentCircuitData circuitData, ref GridRegion neighbor, uint TeleportFlags, AgentData agentData, out string reason, out bool useCallbacks) { useCallbacks = true; if (neighbor == null) { reason = "Could not find neighbor to inform"; return false; } MainConsole.Instance.Info ("[AgentProcessing]: Starting to inform client about neighbor " + neighbor.RegionName); //Notes on this method // 1) the SimulationService.CreateAgent MUST have a fixed CapsUrl for the region, so we have to create (if needed) // a new Caps handler for it. // 2) Then we can call the methods (EnableSimulator and EstatablishAgentComm) to tell the client the new Urls // 3) This allows us to make the Caps on the grid server without telling any other regions about what the // Urls are. ISimulationService SimulationService = m_registry.RequestModuleInterface<ISimulationService> (); if (SimulationService != null) { ICapsService capsService = m_registry.RequestModuleInterface<ICapsService> (); IClientCapsService clientCaps = capsService.GetClientCapsService (AgentID); GridRegion originalDest = neighbor; if ((neighbor.Flags & (int)Aurora.Framework.RegionFlags.Hyperlink) == (int)Aurora.Framework.RegionFlags.Hyperlink) { neighbor = GetFinalDestination (neighbor); if (neighbor == null || neighbor.RegionHandle == 0) { reason = "Could not find neighbor to inform"; return false; } //Remove any offenders clientCaps.RemoveCAPS (originalDest.RegionHandle); clientCaps.RemoveCAPS (neighbor.RegionHandle); } IRegionClientCapsService oldRegionService = clientCaps.GetCapsService (neighbor.RegionHandle); //If its disabled, it should be removed, so kill it! if (oldRegionService != null && oldRegionService.Disabled) { clientCaps.RemoveCAPS (neighbor.RegionHandle); oldRegionService = null; } bool newAgent = oldRegionService == null; IRegionClientCapsService otherRegionService = clientCaps.GetOrCreateCapsService (neighbor.RegionHandle, CapsUtil.GetCapsSeedPath (CapsUtil.GetRandomCapsObjectPath ()), circuitData, 0); if (!newAgent) { //Note: if the agent is already there, send an agent update then bool result = true; if (agentData != null) { agentData.IsCrossing = false; result = SimulationService.UpdateAgent (neighbor, agentData); } if (result) oldRegionService.Disabled = false; reason = ""; return result; } ICommunicationService commsService = m_registry.RequestModuleInterface<ICommunicationService> (); if (commsService != null) commsService.GetUrlsForUser (neighbor, circuitData.AgentID);//Make sure that we make userURLs if we need to circuitData.CapsPath = CapsUtil.GetCapsPathFromCapsSeed (otherRegionService.CapsUrl); if (clientCaps.AccountInfo != null) { circuitData.firstname = clientCaps.AccountInfo.FirstName; circuitData.lastname = clientCaps.AccountInfo.LastName; } bool regionAccepted = false; int requestedUDPPort = 0; if ((originalDest.Flags & (int)Aurora.Framework.RegionFlags.Hyperlink) == (int)Aurora.Framework.RegionFlags.Hyperlink) { if (circuitData.ServiceURLs == null || circuitData.ServiceURLs.Count == 0) { if (clientCaps.AccountInfo != null) { circuitData.ServiceURLs = new Dictionary<string, object> (); circuitData.ServiceURLs[GetHandlers.Helpers_HomeURI] = GetHandlers.GATEKEEPER_URL; circuitData.ServiceURLs[GetHandlers.Helpers_GatekeeperURI] = GetHandlers.GATEKEEPER_URL; circuitData.ServiceURLs[GetHandlers.Helpers_InventoryServerURI] = GetHandlers.GATEKEEPER_URL; circuitData.ServiceURLs[GetHandlers.Helpers_AssetServerURI] = GetHandlers.GATEKEEPER_URL; circuitData.ServiceURLs[GetHandlers.Helpers_ProfileServerURI] = GetHandlers.GATEKEEPER_URL; circuitData.ServiceURLs[GetHandlers.Helpers_FriendsServerURI] = GetHandlers.GATEKEEPER_URL; circuitData.ServiceURLs[GetHandlers.Helpers_IMServerURI] = GetHandlers.IM_URL; clientCaps.AccountInfo.ServiceURLs = circuitData.ServiceURLs; //Store the new urls m_registry.RequestModuleInterface<IUserAccountService> ().StoreUserAccount (clientCaps.AccountInfo); } } string userAgentDriver = circuitData.ServiceURLs[GetHandlers.Helpers_HomeURI].ToString (); IUserAgentService connector = new UserAgentServiceConnector (userAgentDriver); regionAccepted = connector.LoginAgentToGrid (circuitData, originalDest, neighbor, out reason); } else { if(circuitData.child) circuitData.reallyischild = true; regionAccepted = SimulationService.CreateAgent (neighbor, ref circuitData, TeleportFlags, agentData, out requestedUDPPort, out reason); } if (regionAccepted) { IPAddress ipAddress = neighbor.ExternalEndPoint.Address; string otherRegionsCapsURL; //If the region accepted us, we should get a CAPS url back as the reason, if not, its not updated or not an Aurora region, so don't touch it. if (reason != "") { OSDMap responseMap = (OSDMap)OSDParser.DeserializeJson (reason); OSDMap SimSeedCaps = (OSDMap)responseMap["CapsUrls"]; if(responseMap.ContainsKey("OurIPForClient")) { string ip = responseMap["OurIPForClient"].AsString(); ipAddress = IPAddress.Parse(ip); } otherRegionService.AddCAPS (SimSeedCaps); otherRegionsCapsURL = otherRegionService.CapsUrl; } else { //We are assuming an OpenSim region now! #region OpenSim teleport compatibility! useCallbacks = false; otherRegionsCapsURL = neighbor.ServerURI + CapsUtil.GetCapsSeedPath (circuitData.CapsPath); otherRegionService.CapsUrl = otherRegionsCapsURL; #endregion } if (requestedUDPPort == 0) requestedUDPPort = neighbor.ExternalEndPoint.Port; if(ipAddress == null) ipAddress = neighbor.ExternalEndPoint.Address; circuitData.RegionUDPPort = requestedUDPPort; otherRegionService = clientCaps.GetCapsService(neighbor.RegionHandle); otherRegionService.LoopbackRegionIP = ipAddress; otherRegionService.CircuitData.RegionUDPPort = requestedUDPPort; IEventQueueService EQService = m_registry.RequestModuleInterface<IEventQueueService> (); EQService.EnableSimulator (neighbor.RegionHandle, ipAddress.GetAddressBytes(), requestedUDPPort, AgentID, neighbor.RegionSizeX, neighbor.RegionSizeY, requestingRegion); // EnableSimulator makes the client send a UseCircuitCode message to the destination, // which triggers a bunch of things there. // So let's wait Thread.Sleep (300); EQService.EstablishAgentCommunication (AgentID, neighbor.RegionHandle, ipAddress.GetAddressBytes(), requestedUDPPort, otherRegionsCapsURL, neighbor.RegionSizeX, neighbor.RegionSizeY, requestingRegion); if (!useCallbacks) Thread.Sleep (3000); //Give it a bit of time, only for OpenSim... MainConsole.Instance.Info ("[AgentProcessing]: Completed inform client about neighbor " + neighbor.RegionName); } else { clientCaps.RemoveCAPS (neighbor.RegionHandle); MainConsole.Instance.Error ("[AgentProcessing]: Failed to inform client about neighbor " + neighbor.RegionName + ", reason: " + reason); return false; } return true; } reason = "SimulationService does not exist"; MainConsole.Instance.Error ("[AgentProcessing]: Failed to inform client about neighbor " + neighbor.RegionName + ", reason: " + reason + "!"); return false; }