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 +- 3 files changed, 267 insertions(+), 230 deletions(-) (limited to 'OpenSim/Region/CoreModules') 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 } } -- cgit v1.1