public bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason)
{
MainConsole.Instance.DebugFormat("[HYPERGRID LINKER]: Link to {0} {1}, in {2}-{3}",
((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI),
remoteRegionName, xloc / Constants.RegionSize, yloc / Constants.RegionSize);
reason = string.Empty;
Uri uri = null;
regInfo = new GridRegion();
if (externalPort > 0)
{
regInfo.HttpPort = externalPort;
}
else
{
regInfo.HttpPort = 0;
}
if (externalHostName != null)
{
regInfo.ExternalHostName = externalHostName;
}
else
{
regInfo.ExternalHostName = "0.0.0.0";
}
if (serverURI != null)
{
regInfo.ServerURI = serverURI;
try
{
uri = new Uri(serverURI);
regInfo.ExternalHostName = uri.Host;
regInfo.HttpPort = (uint)uri.Port;
}
catch
{
}
}
if (!string.IsNullOrEmpty(remoteRegionName))
{
regInfo.RegionName = remoteRegionName;
}
regInfo.RegionLocX = xloc;
regInfo.RegionLocY = yloc;
regInfo.ScopeID = scopeID;
regInfo.EstateOwner = ownerID;
// Make sure we're not hyperlinking to regions on this grid!
if (m_ThisGatekeeperURI != null)
{
if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port)
{
reason = "Cannot hyperlink to regions on the same grid";
return(false);
}
}
else
{
MainConsole.Instance.WarnFormat("[HYPERGRID LINKER]: Please set this grid's Gatekeeper's address in [GridService]!");
}
// Check for free coordinates
GridRegion region = m_GridService.GetRegionByPosition(null, regInfo.RegionLocX, regInfo.RegionLocY);
if (region != null)
{
MainConsole.Instance.WarnFormat("[HYPERGRID LINKER]: Coordinates {0}-{1} are already occupied by region {2} with uuid {3}",
regInfo.RegionLocX / Constants.RegionSize, regInfo.RegionLocY / Constants.RegionSize,
region.RegionName, region.RegionID);
reason = "Coordinates are already in use";
return(false);
}
try
{
regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0);
}
catch (Exception e)
{
MainConsole.Instance.Warn("[HYPERGRID LINKER]: Wrong format for link-region: " + e.Message);
reason = "Internal error";
return(false);
}
// Finally, link it
ulong handle = 0;
UUID regionID = UUID.Zero;
string externalName = string.Empty;
string imageURL = string.Empty;
if (!m_GatekeeperConnector.LinkRegion(regInfo, out regionID, out handle, out externalName, out imageURL, out reason))
{
return(false);
}
if (regionID == UUID.Zero)
{
MainConsole.Instance.Warn("[HYPERGRID LINKER]: Unable to link region");
reason = "Remote region could not be found";
return(false);
}
region = m_GridService.GetRegionByUUID(null, regionID);
if (region != null)
{
MainConsole.Instance.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates {0} {1}",
region.RegionLocX / Constants.RegionSize, region.RegionLocY / Constants.RegionSize);
regInfo = region;
return(true);
}
uint x, y;
if (m_Check4096 && !Check4096(handle, out x, out y))
{
RemoveHyperlinkRegion(regInfo.RegionID);
reason = "Region is too far (" + x + ", " + y + ")";
MainConsole.Instance.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")");
return(false);
}
regInfo.RegionID = regionID;
if (externalName == string.Empty)
{
regInfo.RegionName = regInfo.ServerURI;
}
else
{
regInfo.RegionName = externalName;
}
MainConsole.Instance.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString());
// Get the map image
regInfo.TerrainImage = GetMapImage(regionID, imageURL);
// Store the origin's coordinates somewhere
//TODO:
//regInfo.RegionSecret = handle.ToString ();
AddHyperlinkRegion(regInfo, handle);
MainConsole.Instance.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} with image {1}", regInfo.RegionName, regInfo.TerrainImage);
return(true);
}