From f276ba57bf5bd732fbc6a255213c9bb7f5f5f148 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 17 Jan 2010 11:33:47 -0800 Subject: HG agent transfers are starting to work. Gatekeeper handlers are missing. --- .../EntityTransfer/EntityTransferModule.cs | 469 +++++++++++---------- .../Resources/CoreModulePlugin.addin.xml | 1 + .../ServiceConnectorsOut/Grid/HGGridConnector.cs | 27 +- .../Hypergrid/GatekeeperServerConnector.cs | 2 +- .../Server/Handlers/Simulation/AgentHandlers.cs | 12 +- .../Hypergrid/HypergridServiceConnector.cs | 7 +- .../Services/HypergridService/GatekeeperService.cs | 34 +- .../Services/HypergridService/HypergridService.cs | 8 +- OpenSim/Services/Interfaces/IHypergridService.cs | 2 +- OpenSim/Services/LLLoginService/LLLoginService.cs | 49 ++- bin/config-include/StandaloneHypergrid.ini | 9 +- 11 files changed, 362 insertions(+), 258 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 827dafe..d0171fe 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer get { return null; } } - public string Name + public virtual string Name { get { return "BasicEntityTransferModule"; } } @@ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_agentsInTransit = new List(); m_Enabled = true; - m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} nabled.", Name); + m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} enabled.", Name); } } } @@ -135,296 +135,312 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Reset animations; the viewer does that in teleports. sp.Animator.ResetAnimations(); - if (regionHandle == sp.Scene.RegionInfo.RegionHandle) + try { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", - position, sp.Scene.RegionInfo.RegionName); - - // Teleport within the same region - if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) - { - Vector3 emergencyPos = new Vector3(128, 128, 128); - - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - position, sp.Name, sp.UUID, emergencyPos); - position = emergencyPos; - } - - // TODO: Get proper AVG Height - float localAVHeight = 1.56f; - float posZLimit = 22; - - // TODO: Check other Scene HeightField - if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) + if (regionHandle == sp.Scene.RegionInfo.RegionHandle) { - posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; - } - - float newPosZ = posZLimit + localAVHeight; - if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) - { - position.Z = newPosZ; - } + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", + position, sp.Scene.RegionInfo.RegionName); - // Only send this if the event queue is null - if (eq == null) - sp.ControllingClient.SendTeleportLocationStart(); + // Teleport within the same region + if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) + { + Vector3 emergencyPos = new Vector3(128, 128, 128); - sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); - sp.Teleport(position); - } - else - { - uint x = 0, y = 0; - Utils.LongToUInts(regionHandle, out x, out y); - GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + position, sp.Name, sp.UUID, emergencyPos); + position = emergencyPos; + } - if (reg != null) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", - position, reg.RegionName); + // TODO: Get proper AVG Height + float localAVHeight = 1.56f; + float posZLimit = 22; - uint newRegionX = (uint)(reg.RegionHandle >> 40); - uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); - uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); - uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); + // TODO: Check other Scene HeightField + if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) + { + posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; + } - ulong destinationHandle = GetRegionHandle(reg); - GridRegion finalDestination = GetFinalDestination(reg); + float newPosZ = posZLimit + localAVHeight; + if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + { + position.Z = newPosZ; + } + // Only send this if the event queue is null if (eq == null) sp.ControllingClient.SendTeleportLocationStart(); - // Let's do DNS resolution only once in this process, please! - // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, - // it's actually doing a lot of work. - IPEndPoint endPoint = reg.ExternalEndPoint; - if (endPoint.Address == null) - { - // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. - destRegionUp = false; - } + sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); + sp.Teleport(position); + } + else + { + uint x = 0, y = 0; + Utils.LongToUInts(regionHandle, out x, out y); + GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); - if (destRegionUp) + if (reg != null) { - // Fixing a bug where teleporting while sitting results in the avatar ending up removed from - // both regions - if (sp.ParentID != (uint)0) - sp.StandUp(); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", + position, reg.RegionName); + + uint newRegionX = (uint)(reg.RegionHandle >> 40); + uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); + uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); + uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); - if (!sp.ValidateAttachments()) + GridRegion finalDestination = GetFinalDestination(reg); + if (finalDestination == null) { - sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport agent."); + sp.ControllingClient.SendTeleportFailed("Problem at destination"); return; } + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", finalDestination.RegionLocX, finalDestination.RegionLocY, finalDestination.RegionID); + ulong destinationHandle = finalDestination.RegionHandle; - // the avatar.Close below will clear the child region list. We need this below for (possibly) - // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - //List childRegions = new List(avatar.GetKnownRegionList()); - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport - // failure at this point (unlike a border crossing failure). So perhaps this can never fail - // once we reach here... - //avatar.Scene.RemoveCapsHandler(avatar.UUID); - - string capsPath = String.Empty; - AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); - agentCircuit.BaseFolder = UUID.Zero; - agentCircuit.InventoryFolder = UUID.Zero; - agentCircuit.startpos = position; - agentCircuit.child = true; - agentCircuit.Appearance = sp.Appearance; - - if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) + if (eq == null) + sp.ControllingClient.SendTeleportLocationStart(); + + // Let's do DNS resolution only once in this process, please! + // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, + // it's actually doing a lot of work. + IPEndPoint endPoint = finalDestination.ExternalEndPoint; + if (endPoint.Address == null) { - // brand new agent, let's create a new caps seed - agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. + destRegionUp = false; } - string reason = String.Empty; - - // Let's create an agent there if one doesn't exist yet. - if (!m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason)) + if (destRegionUp) { - sp.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", - reason)); - return; - } + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); - // OK, it got this agent. Let's close some child agents - sp.CloseChildAgents(newRegionX, newRegionY); + if (!sp.ValidateAttachments()) + { + sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); + return; + } - if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) - { - #region IP Translation for NAT - IClientIPEndpoint ipepClient; - if (sp.ClientView.TryGet(out ipepClient)) + // the avatar.Close below will clear the child region list. We need this below for (possibly) + // closing the child agents, so save it here (we need a copy as it is Clear()-ed). + //List childRegions = new List(avatar.GetKnownRegionList()); + // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport + // failure at this point (unlike a border crossing failure). So perhaps this can never fail + // once we reach here... + //avatar.Scene.RemoveCapsHandler(avatar.UUID); + + string capsPath = String.Empty; + AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); + agentCircuit.BaseFolder = UUID.Zero; + agentCircuit.InventoryFolder = UUID.Zero; + agentCircuit.startpos = position; + agentCircuit.child = true; + agentCircuit.Appearance = sp.Appearance; + + if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) { - capsPath - = "http://" - + NetworkUtil.GetHostFor(ipepClient.EndPoint, reg.ExternalHostName) - + ":" - + reg.HttpPort - + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + // brand new agent, let's create a new caps seed + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); } - else + + string reason = String.Empty; + + // Let's create an agent there if one doesn't exist yet. + if (!m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason)) { - capsPath - = "http://" - + reg.ExternalHostName - + ":" - + reg.HttpPort - + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + sp.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", + reason)); + return; } - #endregion - if (eq != null) + // OK, it got this agent. Let's close some child agents + sp.CloseChildAgents(newRegionX, newRegionY); + + if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) { #region IP Translation for NAT - // Uses ipepClient above + IClientIPEndpoint ipepClient; if (sp.ClientView.TryGet(out ipepClient)) { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + capsPath + = "http://" + + NetworkUtil.GetHostFor(ipepClient.EndPoint, finalDestination.ExternalHostName) + + ":" + + finalDestination.HttpPort + + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } + else + { + capsPath + = "http://" + + finalDestination.ExternalHostName + + ":" + + finalDestination.HttpPort + + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } #endregion - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + if (eq != null) + { + #region IP Translation for NAT + // Uses ipepClient above + if (sp.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + + eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); - // ES makes the client send a UseCircuitCode message to the destination, - // which triggers a bunch of things there. - // So let's wait - Thread.Sleep(2000); + // ES makes the client send a UseCircuitCode message to the destination, + // which triggers a bunch of things there. + // So let's wait + Thread.Sleep(2000); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + } + else + { + sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); + } } else { - sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); + agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); + capsPath = "http://" + finalDestination.ExternalHostName + ":" + finalDestination.HttpPort + + "/CAPS/" + agentCircuit.CapsPath + "0000/"; } - } - else - { - agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); - capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort - + "/CAPS/" + agentCircuit.CapsPath + "0000/"; - } - - // Expect avatar crossing is a heavy-duty function at the destination. - // That is where MakeRoot is called, which fetches appearance and inventory. - // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. - //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, - // position, false); - - //{ - // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); - // // We should close that agent we just created over at destination... - // List lst = new List(); - // lst.Add(reg.RegionHandle); - // SendCloseChildAgentAsync(avatar.UUID, lst); - // return; - //} - SetInTransit(sp.UUID); + // Expect avatar crossing is a heavy-duty function at the destination. + // That is where MakeRoot is called, which fetches appearance and inventory. + // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. + //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, + // position, false); + + //{ + // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); + // // We should close that agent we just created over at destination... + // List lst = new List(); + // lst.Add(reg.RegionHandle); + // SendCloseChildAgentAsync(avatar.UUID, lst); + // return; + //} + + SetInTransit(sp.UUID); + + // Let's send a full update of the agent. This is a synchronous call. + AgentData agent = new AgentData(); + sp.CopyTo(agent); + agent.Position = position; + agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + + "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; + + // Straight to the region. Safe. + m_aScene.SimulationService.UpdateAgent(reg, agent); - // Let's send a full update of the agent. This is a synchronous call. - AgentData agent = new AgentData(); - sp.CopyTo(agent); - agent.Position = position; - agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + - "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); - m_aScene.SimulationService.UpdateAgent(reg, agent); - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); + if (eq != null) + { + eq.TeleportFinishEvent(destinationHandle, 13, endPoint, + 0, teleportFlags, capsPath, sp.UUID); + } + else + { + sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, + teleportFlags, capsPath); + } + // 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. + if (!WaitForCallback(sp.UUID)) + { + // Client never contacted destination. Let's restore everything back + sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); - if (eq != null) - { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); - } - else - { - sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, - teleportFlags, capsPath); - } + ResetFromTransit(sp.UUID); - // 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. - if (!WaitForCallback(sp.UUID)) - { - // Client never contacted destination. Let's restore everything back - sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); + // Yikes! We should just have a ref to scene here. + //sp.Scene.InformClientOfNeighbours(sp); + EnableChildAgents(sp); - ResetFromTransit(sp.UUID); + // Finally, kill the agent we just created at the destination. + m_aScene.SimulationService.CloseAgent(reg, sp.UUID); - // Yikes! We should just have a ref to scene here. - //sp.Scene.InformClientOfNeighbours(sp); - EnableChildAgents(sp); + return; + } - // Finally, kill the agent we just created at the destination. - m_aScene.SimulationService.CloseAgent(reg, sp.UUID); + KillEntity(sp.Scene, sp.LocalId); - return; - } + sp.MakeChildAgent(); - KillEntity(sp.Scene, sp.LocalId); + // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it + CrossAttachmentsIntoNewRegion(reg, sp, true); - sp.MakeChildAgent(); + // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - CrossAttachmentsIntoNewRegion(reg, sp, true); + if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + { + Thread.Sleep(5000); + sp.Close(); + sp.Scene.IncomingCloseAgent(sp.UUID); + } + else + // now we have a child agent in this region. + sp.Reset(); - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) - { - Thread.Sleep(5000); - sp.Close(); - sp.Scene.IncomingCloseAgent(sp.UUID); + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (sp.Scene.NeedSceneCacheClear(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", + sp.UUID); + } } else - // now we have a child agent in this region. - sp.Reset(); - - - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! - if (sp.Scene.NeedSceneCacheClear(sp.UUID)) { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", - sp.UUID); + sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); } } else { - sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + // TP to a place that doesn't exist (anymore) + // Inform the viewer about that + sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); + + // and set the map-tile to '(Offline)' + uint regX, regY; + Utils.LongToUInts(regionHandle, out regX, out regY); + + MapBlockData block = new MapBlockData(); + block.X = (ushort)(regX / Constants.RegionSize); + block.Y = (ushort)(regY / Constants.RegionSize); + block.Access = 254; // == not there + + List blocks = new List(); + blocks.Add(block); + sp.ControllingClient.SendMapBlock(blocks, 0); } } - else - { - // TP to a place that doesn't exist (anymore) - // Inform the viewer about that - sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); - - // and set the map-tile to '(Offline)' - uint regX, regY; - Utils.LongToUInts(regionHandle, out regX, out regY); - - MapBlockData block = new MapBlockData(); - block.X = (ushort)(regX / Constants.RegionSize); - block.Y = (ushort)(regY / Constants.RegionSize); - block.Access = 254; // == not there - - List blocks = new List(); - blocks.Add(block); - sp.ControllingClient.SendMapBlock(blocks, 0); - } + } + catch (Exception e) + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0}\n{1}", e.Message, e.StackTrace); + sp.ControllingClient.SendTeleportFailed("Internal error"); } } @@ -433,11 +449,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer scene.SendKillObject(localID); } - protected virtual ulong GetRegionHandle(GridRegion region) - { - return region.RegionHandle; - } - protected virtual GridRegion GetFinalDestination(GridRegion region) { return region; diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index 68cf060..08a90a2 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -9,6 +9,7 @@ + diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs index 773286c..07f3cdc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs @@ -48,7 +48,7 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { - public class HGGridConnector : ISharedRegionModule, IGridService + public class HGGridConnector : ISharedRegionModule, IGridService, IHypergridService { private static readonly ILog m_log = LogManager.GetLogger( @@ -148,6 +148,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid m_LocalScenes[scene.RegionInfo.RegionHandle] = scene; scene.RegisterModuleInterface(this); + scene.RegisterModuleInterface(this); ((ISharedRegionModule)m_GridServiceConnector).AddRegion(scene); @@ -158,6 +159,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (m_Enabled) { m_LocalScenes.Remove(scene.RegionInfo.RegionHandle); + scene.UnregisterModuleInterface(this); + scene.UnregisterModuleInterface(this); ((ISharedRegionModule)m_GridServiceConnector).RemoveRegion(scene); } } @@ -278,5 +281,27 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid #endregion + #region IHypergridService + + public bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string imageURL, out string reason) + { + return m_HypergridService.LinkRegion(regionDescriptor, out regionID, out regionHandle, out imageURL, out reason); + } + + public GridRegion GetHyperlinkRegion(GridRegion gateway, UUID regionID) + { + if (m_LocalScenes.ContainsKey(gateway.RegionHandle)) + return gateway; + + return m_HypergridService.GetHyperlinkRegion(gateway, regionID); + } + + public GridRegion GetRegionByUUID(UUID regionID) { return null; } + public GridRegion GetRegionByPosition(int x, int y) { return null; } + public GridRegion GetRegionByName(string name) { return null; } + public List GetRegionsByName(string name) { return null; } + public List GetRegionRange(int xmin, int xmax, int ymin, int ymax) { return null; } + + #endregion } } diff --git a/OpenSim/Server/Handlers/Hypergrid/GatekeeperServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/GatekeeperServerConnector.cs index 762ea79..f72b36c 100644 --- a/OpenSim/Server/Handlers/Hypergrid/GatekeeperServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/GatekeeperServerConnector.cs @@ -109,7 +109,7 @@ namespace OpenSim.Server.Handlers.Hypergrid Hashtable requestData = (Hashtable)request.Params[0]; //string host = (string)requestData["host"]; //string portstr = (string)requestData["port"]; - string regionID_str = (string)requestData["regionID"]; + string regionID_str = (string)requestData["region_uuid"]; UUID regionID = UUID.Zero; UUID.TryParse(regionID_str, out regionID); diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 45e88ce..0c098d9 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -59,13 +59,13 @@ namespace OpenSim.Server.Handlers.Simulation public Hashtable Handler(Hashtable request) { - //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); + m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); - //m_log.Debug("---------------------------"); - //m_log.Debug(" >> uri=" + request["uri"]); - //m_log.Debug(" >> content-type=" + request["content-type"]); - //m_log.Debug(" >> http-method=" + request["http-method"]); - //m_log.Debug("---------------------------\n"); + m_log.Debug("---------------------------"); + m_log.Debug(" >> uri=" + request["uri"]); + m_log.Debug(" >> content-type=" + request["content-type"]); + m_log.Debug(" >> http-method=" + request["http-method"]); + m_log.Debug("---------------------------\n"); Hashtable responsedata = new Hashtable(); responsedata["content_type"] = "text/html"; diff --git a/OpenSim/Services/Connectors/Hypergrid/HypergridServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HypergridServiceConnector.cs index 0bb1c0e..953c7bd 100644 --- a/OpenSim/Services/Connectors/Hypergrid/HypergridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/HypergridServiceConnector.cs @@ -50,6 +50,8 @@ namespace OpenSim.Services.Connectors.Hypergrid private IAssetService m_AssetService; + public HypergridServiceConnector() : this(null) { } + public HypergridServiceConnector(IAssetService assService) { m_AssetService = assService; @@ -197,21 +199,24 @@ namespace OpenSim.Services.Connectors.Hypergrid GridRegion region = new GridRegion(); UUID.TryParse((string)hash["uuid"], out region.RegionID); - //m_log.Debug(">> HERE, uuid: " + uuid); + //m_log.Debug(">> HERE, uuid: " + region.RegionID); int n = 0; if (hash["x"] != null) { Int32.TryParse((string)hash["x"], out n); region.RegionLocX = n; + //m_log.Debug(">> HERE, x: " + region.RegionLocX); } if (hash["y"] != null) { Int32.TryParse((string)hash["y"], out n); region.RegionLocY = n; + //m_log.Debug(">> HERE, y: " + region.RegionLocY); } if (hash["region_name"] != null) { region.RegionName = (string)hash["region_name"]; + //m_log.Debug(">> HERE, name: " + region.RegionName); } if (hash["hostname"] != null) region.ExternalHostName = (string)hash["hostname"]; diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index ec7ef1d..a5bd881 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -112,6 +112,10 @@ namespace OpenSim.Services.HypergridService m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", regionName); if (!m_AllowTeleportsToAnyRegion) { + List defs = m_GridService.GetDefaultRegions(m_ScopeID); + if (defs != null && defs.Count > 0) + m_DefaultGatewayRegion = defs[0]; + try { regionID = m_DefaultGatewayRegion.RegionID; @@ -150,6 +154,8 @@ namespace OpenSim.Services.HypergridService public GridRegion GetHyperlinkRegion(UUID regionID) { + m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to get hyperlink region {0}", regionID); + if (!m_AllowTeleportsToAnyRegion) // Don't even check the given regionID return m_DefaultGatewayRegion; @@ -160,23 +166,43 @@ namespace OpenSim.Services.HypergridService public bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination) { + string authURL = string.Empty; + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + authURL = aCircuit.ServiceURLs["HomeURI"].ToString(); + + m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to login foreign agent {0} {1} @ {2} ({3}) at destination {4}", + aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName); + if (!Authenticate(aCircuit)) + { + m_log.InfoFormat("[GATEKEEPER SERVICE]: Unable to verify identity of agent {0} {1}. Refusing service.", aCircuit.firstname, aCircuit.lastname); return false; + } // Check to see if we have a local user with that UUID UserAccount account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID); if (account != null) + { // No, sorry; go away + m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agent {0} {1} has UUID of local user {3}. Refusing service.", + aCircuit.firstname, aCircuit.lastname, aCircuit.AgentID); return false; + } // May want to authorize // Login the presence if (!m_PresenceService.LoginAgent(aCircuit.AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID)) + { + m_log.InfoFormat("[GATEKEEPER SERVICE]: Presence login failed for foreign agent {0} {1}. Refusing service.", + aCircuit.firstname, aCircuit.lastname); return false; + } // Finally launch the agent at the destination string reason = string.Empty; + aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname; + aCircuit.lastname = "@" + aCircuit.ServiceURLs["HomeURI"].ToString(); return m_SimulationService.CreateAgent(destination, aCircuit, 0, out reason); } @@ -188,9 +214,15 @@ namespace OpenSim.Services.HypergridService protected bool Authenticate(AgentCircuitData aCircuit) { - string authURL = string.Empty; // GetAuthURL(aCircuit); + string authURL = string.Empty; + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + authURL = aCircuit.ServiceURLs["HomeURI"].ToString(); + if (authURL == string.Empty) + { + m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide an authentication server URL"); return false; + } Object[] args = new Object[] { authURL }; IAuthenticationService authService = ServerUtils.LoadPlugin(m_AuthDll, args); diff --git a/OpenSim/Services/HypergridService/HypergridService.cs b/OpenSim/Services/HypergridService/HypergridService.cs index 747b98a..734931d 100644 --- a/OpenSim/Services/HypergridService/HypergridService.cs +++ b/OpenSim/Services/HypergridService/HypergridService.cs @@ -347,10 +347,12 @@ namespace OpenSim.Services.HypergridService #region Get Hyperlinks - public GridRegion GetHyperlinkRegion(UUID regionID) + public GridRegion GetHyperlinkRegion(GridRegion gatekeeper, UUID regionID) { - //GridRegion region = m_HypergridConnector. - return null; + if (m_HyperlinkRegions.ContainsKey(regionID)) + return m_HypergridConnector.GetHyperlinkRegion(gatekeeper, regionID); + else + return gatekeeper; } #endregion diff --git a/OpenSim/Services/Interfaces/IHypergridService.cs b/OpenSim/Services/Interfaces/IHypergridService.cs index b49657a..f2a1983 100644 --- a/OpenSim/Services/Interfaces/IHypergridService.cs +++ b/OpenSim/Services/Interfaces/IHypergridService.cs @@ -36,7 +36,7 @@ namespace OpenSim.Services.Interfaces public interface IHypergridService { bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string imageURL, out string reason); - GridRegion GetHyperlinkRegion(UUID regionID); + GridRegion GetHyperlinkRegion(GridRegion gateway, UUID regionID); GridRegion GetRegionByUUID(UUID regionID); GridRegion GetRegionByPosition(int x, int y); diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 6f92388..d4f89d9 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -37,24 +37,26 @@ namespace OpenSim.Services.LLLoginService private bool m_RequireInventory; private int m_MinLoginLevel; + IConfig m_LoginServerConfig; + public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService) { - IConfig serverConfig = config.Configs["LoginService"]; - if (serverConfig == null) + m_LoginServerConfig = config.Configs["LoginService"]; + if (m_LoginServerConfig == null) throw new Exception(String.Format("No section LoginService in config file")); - string accountService = serverConfig.GetString("UserAccountService", String.Empty); - string authService = serverConfig.GetString("AuthenticationService", String.Empty); - string invService = serverConfig.GetString("InventoryService", String.Empty); - string gridService = serverConfig.GetString("GridService", String.Empty); - string presenceService = serverConfig.GetString("PresenceService", String.Empty); - string libService = serverConfig.GetString("LibraryService", String.Empty); - string avatarService = serverConfig.GetString("AvatarService", String.Empty); - string simulationService = serverConfig.GetString("SimulationService", String.Empty); + string accountService = m_LoginServerConfig.GetString("UserAccountService", String.Empty); + string authService = m_LoginServerConfig.GetString("AuthenticationService", String.Empty); + string invService = m_LoginServerConfig.GetString("InventoryService", String.Empty); + string gridService = m_LoginServerConfig.GetString("GridService", String.Empty); + string presenceService = m_LoginServerConfig.GetString("PresenceService", String.Empty); + string libService = m_LoginServerConfig.GetString("LibraryService", String.Empty); + string avatarService = m_LoginServerConfig.GetString("AvatarService", String.Empty); + string simulationService = m_LoginServerConfig.GetString("SimulationService", String.Empty); - m_DefaultRegionName = serverConfig.GetString("DefaultRegion", String.Empty); - m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!"); - m_RequireInventory = serverConfig.GetBoolean("RequireInventory", true); + m_DefaultRegionName = m_LoginServerConfig.GetString("DefaultRegion", String.Empty); + m_WelcomeMessage = m_LoginServerConfig.GetString("WelcomeMessage", "Welcome to OpenSim!"); + m_RequireInventory = m_LoginServerConfig.GetBoolean("RequireInventory", true); // These are required; the others aren't if (accountService == string.Empty || authService == string.Empty) @@ -438,7 +440,7 @@ namespace OpenSim.Services.LLLoginService aCircuit.SecureSessionID = secureSession; aCircuit.SessionID = session; aCircuit.startpos = position; - aCircuit.ServiceURLs = account.ServiceURLs; + SetServiceURLs(aCircuit, account); if (simConnector.CreateAgent(region, aCircuit, 0, out reason)) return aCircuit; @@ -447,6 +449,25 @@ namespace OpenSim.Services.LLLoginService } + private void SetServiceURLs(AgentCircuitData aCircuit, UserAccount account) + { + aCircuit.ServiceURLs = new Dictionary(); + if (account.ServiceURLs == null) + return; + + foreach (KeyValuePair kvp in account.ServiceURLs) + { + if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty)) + { + aCircuit.ServiceURLs[kvp.Key] = m_LoginServerConfig.GetString(kvp.Key, string.Empty); + } + else + { + aCircuit.ServiceURLs[kvp.Key] = kvp.Value; + } + } + } + #region Console Commands private void RegisterCommands() { diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 79a8775..3d05d51 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -20,7 +20,7 @@ UserAccountServices = "LocalUserAccountServicesConnector" SimulationServices = "RemoteSimulationConnectorModule" AvatarServices = "LocalAvatarServicesConnector" - EntityTransferModule = "BasicEntityTransferModule" + EntityTransferModule = "HGEntityTransferModule" InventoryServiceInConnector = true AssetServiceInConnector = true HGAuthServiceInConnector = true @@ -28,6 +28,8 @@ NeighbourServiceInConnector = true LibraryModule = true LLLoginServiceInConnector = true + ;; err, temporary + SimulationServiceInConnector = true [AssetService] ; For the AssetServiceInConnector @@ -103,3 +105,8 @@ DefaultRegion = "OpenSim Test" WelcomeMessage = "Welcome, Avatar!" + HomeURI = "http://127.0.0.1:9000" + GatewayURI = "http://127.0.0.1:9000" + InventoryServerURI = "http://127.0.0.1:9000" + AssetServerURI = "http://127.0.0.1:9000" + -- cgit v1.1