diff --git a/OpenSim/Framework/RegionURI.cs b/OpenSim/Framework/RegionURI.cs new file mode 100644 index 0000000000..3e6d4add99 --- /dev/null +++ b/OpenSim/Framework/RegionURI.cs @@ -0,0 +1,524 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * - Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * - Neither the name of the openmetaverse.org nor the names + * of its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Net; +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public class RegionURI + { + private static byte[] schemaSep = osUTF8.GetASCIIBytes("://"); + private static byte[] altschemaSep = osUTF8.GetASCIIBytes("|!!"); + private static byte[] nameSep = osUTF8.GetASCIIBytes(":/ "); + private static byte[] altnameSep = osUTF8.GetASCIIBytes(":/ +|"); + private static byte[] escapePref = osUTF8.GetASCIIBytes("+%"); + private static byte[] altPortSepPref = osUTF8.GetASCIIBytes(":|"); + + public enum URIFlags : int + { + None = 0, + Valid = 1 << 0, + HasHost = 1 << 1, + HasResolvedHost = 1 << 2, + HasUserName = 1 << 3, + HasUserPass = 1 << 4, + HasRegionName = 1 << 5, + HasCoords = 1 << 6, + + IsLocalGrid = 1 << 7 // this must be set externally + } + + public URIFlags Flags; + public IPAddress IP; + public string originalURI = string.Empty; + public string Schema = "http://"; + public string Host = string.Empty; + public int Port = 80; + public string RegionName = string.Empty; + public string Username = string.Empty; + public string UserPass = string.Empty; + public int X = 127; + public int Y = 127; + public int Z = 2; + + public RegionURI(string _originalURI) + { + originalURI = _originalURI; + Parse(_originalURI); + } + + public RegionURI(string _originalURI, GridInfo gi) + { + originalURI = _originalURI; + Parse(_originalURI); + + if(!HasHost || gi == null) + return; + + if (gi.IsLocalGrid(HostUrl) == 1) + { + Host = string.Empty; + Flags &= ~URIFlags.HasHost; + Flags |= URIFlags.IsLocalGrid; + return; + } + if (!ResolveDNS()) + { + Flags = URIFlags.None; + } + } + + public void Parse(string inputURI) + { + Flags = URIFlags.None; + if (string.IsNullOrWhiteSpace(inputURI)) + return; + + osUTF8Slice input = new osUTF8Slice(inputURI); + input.SelfTrimStart((byte)' '); + input.SelfTrimStart((byte)'+'); + + int firstDot = input.IndexOf((byte)'.'); + if (firstDot == 0) + return; + + osUTF8Slice tmpSlice; + + int indx = input.IndexOf(schemaSep); + if (indx == 0) + return; + if (indx < 0) + indx = input.IndexOf(altschemaSep); + if (indx == 0) + return; + if (indx > 0) + { + if (indx < 2 || input.Length < indx + 4 || (firstDot > 0 && indx > firstDot)) + return; + + bool issecure = false; + tmpSlice = input.SubUTF8(0, indx).Clone(); + tmpSlice.ToASCIILowerSelf(); + + if (tmpSlice.EndsWith((byte)'s')) + { + issecure = true; + tmpSlice.SelfTrimEnd((byte)'s'); + } + + switch (tmpSlice.ToString()) + { + case "hg": + case "hop": + case "http": + case "surl": + if (issecure) + { + Schema = "https://"; + Port = 443; + } + break; + default: + return; + } + + indx += 3; + input.SubUTF8Self(indx); + firstDot -= indx; + } + + int namestart = 0; + if (firstDot > 0) + { + int hostend = -1; + osUTF8Slice hosttmp = input.Clone(); + indx = input.IndexOfAny(altPortSepPref); + if (indx > 0) + { + if (indx < firstDot) + return; + + hostend = indx; + ++indx; + int tmpport = 0; + byte c; + while (indx < input.Length) + { + c = input[indx]; + if (c < (byte)'0' || c > (byte)'9') + break; + tmpport *= 10; + tmpport += c - (byte)'0'; + ++indx; + } + if (indx > hostend + 1) + { + if (tmpport > 64 * 1024) + return; + Port = tmpport; + } + input.SubUTF8Self(indx); + input.SelfTrimStart(altnameSep); + } + else + { + indx = input.IndexOfAny(altnameSep); + if (indx < 0) + { + hostend = input.Length; + namestart = -1; + } + else + { + hostend = indx; + namestart = indx + 1; + } + } + + if (hostend <= 0) + return; + + hosttmp.SubUTF8Self(0, hostend); + indx = hosttmp.IndexOf((byte)'@'); + if (indx >= 0) + { + if (indx > 0) + { + tmpSlice = hosttmp.SubUTF8(0, indx); + int indx2 = tmpSlice.IndexOfAny(escapePref); + if (indx2 >= 0) + { + Username = Uri.UnescapeDataString(tmpSlice.ToString()); + Username = Username.Replace('+', ' '); + } + else + Username = tmpSlice.ToString(); + if (Username.Length > 0) + Flags |= URIFlags.HasUserName; + } + ++indx; + hosttmp.SubUTF8Self(indx); + } + if (hosttmp.Length == 0) + { + Flags = URIFlags.None; + return; + } + + indx = hosttmp.IndexOfAny(escapePref); + if (indx >= 0) + { + string blabla = Uri.UnescapeDataString(hosttmp.ToString()); + blabla = blabla.Replace('+', ' '); + hosttmp = new osUTF8Slice(blabla); + } + hosttmp.ToASCIILowerSelf(); + Host = hosttmp.ToString(); + UriHostNameType type = Uri.CheckHostName(Host); + if (type == UriHostNameType.Unknown || type == UriHostNameType.Basic) + { + Flags = URIFlags.None; + return; + } + + Flags |= URIFlags.HasHost; + } + + if (namestart < 0 || input.Length == 0) + return; + + input.SubUTF8Self(namestart); + input.SelfTrimStart((byte)' '); + input.SelfTrimStart((byte)'+'); + + int firstCoord = input.IndexOf((byte)'/'); + if (firstCoord == 0) + { + Flags = URIFlags.None; + return; + } + if (firstCoord < 0) + firstCoord = input.IndexOf((byte)'('); + + if (firstCoord > 0) + tmpSlice = input.SubUTF8(0, firstCoord); + else + tmpSlice = input; + indx = tmpSlice.IndexOfAny(escapePref); + if (indx >= 0) + { + string blabla = Uri.UnescapeDataString(tmpSlice.ToString()); + blabla = blabla.Replace('+', ' '); + tmpSlice = new osUTF8Slice(blabla); + } + + tmpSlice.SelfTrimEnd((byte)' '); + if (tmpSlice.Length <= 0) + return; + + RegionName = tmpSlice.ToString(); + Flags |= URIFlags.HasRegionName; + + if (firstCoord > 0) + { + if (input[firstCoord] == (byte)'/') + { + ++firstCoord; + int tmp = 0; + tmpSlice = input.SubUTF8(firstCoord); + int indx2 = 0; + while (indx2 < tmpSlice.Length) + { + byte c = tmpSlice[indx2]; + if (c < (byte)'0' || c > (byte)'9') + break; + tmp *= 10; + tmp += c - (byte)'0'; + ++indx2; + } + if (indx2 == 0) + { + Flags = URIFlags.None; + return; + } + X = tmp; + tmpSlice.SubUTF8Self(indx2); + indx = tmpSlice.IndexOf((byte)'/'); + if (indx >= 0) + { + ++indx; + tmpSlice.SubUTF8Self(indx); + indx2 = 0; + tmp = 0; + while (indx2 < tmpSlice.Length) + { + byte c = tmpSlice[indx2]; + if (c < (byte)'0' || c > (byte)'9') + break; + tmp *= 10; + tmp += c - (byte)'0'; + ++indx2; + } + if (indx2 == 0) + { + Flags = URIFlags.None; + return; + } + Y = tmp; + tmpSlice.SubUTF8Self(indx2); + indx = tmpSlice.IndexOf((byte)'/'); + if (indx >= 0) + { + ++indx; + tmpSlice.SubUTF8Self(indx); + indx2 = 0; + tmp = 0; + int sig = 1; + if (tmpSlice[indx2] == (byte)'-') + { + sig = -1; + indx2++; + } + while (indx2 < tmpSlice.Length) + { + byte c = tmpSlice[indx2]; + if (c < (byte)'0' || c > (byte)'9') + break; + tmp *= 10; + tmp += c - (byte)'0'; + ++indx2; + } + if (indx2 == 0) + { + Flags = URIFlags.None; + return; + } + Z = sig * tmp; + } + } + } + else // (,,) case + { + ++firstCoord; + int tmp = 0; + tmpSlice = input.SubUTF8(firstCoord); + int indx2 = tmpSlice.IndexOf((byte)')'); + if (indx2 == 0) + return; + if (indx2 > 0) + tmpSlice.SubUTF8Self(0, indx2); + + indx2 = 0; + tmpSlice.SelfTrimStart((byte)' '); + tmpSlice.SelfTrimStart((byte)'+'); + + while (indx2 < tmpSlice.Length) + { + byte c = tmpSlice[indx2]; + if (c < (byte)'0' || c > (byte)'9') + break; + tmp *= 10; + tmp += c - (byte)'0'; + ++indx2; + } + if (indx2 == 0) + { + Flags = URIFlags.None; + return; + } + X = tmp; + tmpSlice.SubUTF8Self(indx2); + indx = tmpSlice.IndexOf((byte)','); + if (indx >= 0) + { + ++indx; + tmpSlice.SubUTF8Self(indx); + tmpSlice.SelfTrimStart((byte)' '); + tmpSlice.SelfTrimStart((byte)'+'); + indx2 = 0; + tmp = 0; + while (indx2 < tmpSlice.Length) + { + byte c = tmpSlice[indx2]; + if (c < (byte)'0' || c > (byte)'9') + break; + tmp *= 10; + tmp += c - (byte)'0'; + ++indx2; + } + if (indx2 == 0) + { + Flags = URIFlags.None; + return; + } + Y = tmp; + tmpSlice.SubUTF8Self(indx2); + indx = tmpSlice.IndexOf((byte)','); + if (indx >= 0) + { + ++indx; + tmpSlice.SubUTF8Self(indx); + tmpSlice.SelfTrimStart((byte)' '); + tmpSlice.SelfTrimStart((byte)'+'); + indx2 = 0; + tmp = 0; + int sig = 1; + if (tmpSlice[indx2] == (byte)'-') + { + sig = -1; + indx2++; + } + while (indx2 < tmpSlice.Length) + { + byte c = tmpSlice[indx2]; + if (c < (byte)'0' || c > (byte)'9') + break; + tmp *= 10; + tmp += c - (byte)'0'; + ++indx2; + } + if (indx2 == 0) + { + Flags = URIFlags.None; + return; + } + Z = sig * tmp; + } + } + } + } + return; + } + + public bool ResolveDNS() + { + if ((Flags & URIFlags.HasHost) != 0) + { + IPAddress ip = Util.GetHostFromDNS(Host); + if (ip != null) + { + IP = ip; + Flags |= URIFlags.HasResolvedHost; + return true; + } + } + return false; + } + + public bool IsValid + { + get { return (Flags & (URIFlags.HasHost | URIFlags.HasRegionName)) != 0; } + } + + public bool HasHost + { + get { return (Flags & URIFlags.HasHost) != 0; } + } + + public bool HasRegionName + { + get { return (Flags & URIFlags.HasRegionName) != 0; } + } + + public string HostUrl + { + get { return (Flags & URIFlags.HasHost) != 0 ? (Schema + Host + ":" + Port) : ""; } + } + + public string HostUrlEndSlash + { + get { return (Flags & URIFlags.HasHost) != 0 ? (Schema + Host + ":" + Port + "/") : ""; } + } + + public string RegionUrlAndName + { + get + { + string ret = (Flags & URIFlags.HasHost) != 0 ? (Schema + Host + ":" + Port + "/") : ""; + if ((Flags & URIFlags.HasRegionName) != 0) + ret += RegionName; + return ret; + } + } + + // this needs to be set before get + public bool IsLocalGrid + { + get { return (Flags & URIFlags.IsLocalGrid) != 0; } + set + { + if(value) + { + Host = string.Empty; + Flags &= ~URIFlags.HasHost; + Flags |= URIFlags.IsLocalGrid; + } + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionGridServiceConnector.cs index 4290fc1850..a41cf8601c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionGridServiceConnector.cs @@ -342,42 +342,36 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public List GetRegionsByName(UUID scopeID, string name, int maxNumber) { - List rinfo = m_LocalGridService.GetRegionsByName(scopeID, name, maxNumber); + var ruri = new RegionURI(name, m_ThisGridInfo); + return GetRegionsByURI(scopeID, ruri, maxNumber); + } + + public List GetRegionsByURI(UUID scopeID, RegionURI uri, int maxNumber) + { + if(!uri.IsValid) + return null; + + List rinfo = m_LocalGridService.GetRegionsByURI(scopeID, uri, maxNumber); //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetRegionsByName {0} found {1} regions", name, rinfo.Count); - if(m_RemoteGridService == null) + if (m_RemoteGridService == null || !uri.IsLocalGrid) return rinfo; - // HG urls should not get here, strip them - // side effect is that local regions with same name as HG may also be found - // this mb good or bad - string regionName = name; - if(name.Contains(".")) - { - if(!m_ThisGridInfo.HasHGConfig) - return rinfo; // no HG - - string regionURI = ""; - if (!Util.buildHGRegionURI(name, out regionURI, out regionName)) - return rinfo; // invalid - if (m_ThisGridInfo.IsLocalGrid(regionURI) != 1) - return rinfo; // not local grid - } List grinfo = null; - if (string.IsNullOrEmpty(regionName)) + if (!uri.HasRegionName) { List grinfos = m_RemoteGridService.GetDefaultRegions(scopeID); if (grinfos == null || grinfos.Count == 0) - m_log.Warn("[REMOTE GRID CONNECTOR] returned no default regions"); + m_log.Info("[REMOTE GRID CONNECTOR] returned no default regions"); else { - m_log.WarnFormat("[REMOTE GRID CONNECTOR] returned default regions {0}, ...", grinfos[0].RegionName); + m_log.InfoFormat("[REMOTE GRID CONNECTOR] returned default regions {0}, ...", grinfos[0].RegionName); // only return first - grinfo = new List(){grinfos[0]}; + grinfo = new List() { grinfos[0] }; } } else - grinfo = m_RemoteGridService.GetRegionsByName(scopeID, regionName, maxNumber); + grinfo = m_RemoteGridService.GetRegionsByName(scopeID, uri.RegionName, maxNumber); if (grinfo != null) { @@ -385,7 +379,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid foreach (GridRegion r in grinfo) { m_RegionInfoCache.Cache(r); - if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) + if (rinfo.Find(delegate (GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) rinfo.Add(r); } } diff --git a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs index 73bceae6d7..1e8c622be2 100644 --- a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs @@ -419,6 +419,11 @@ namespace OpenSim.Services.Connectors return rinfos; } + public List GetRegionsByURI(UUID scopeID, RegionURI uri, int maxNumber) + { + return null; + } + public List GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) { Dictionary sendData = new Dictionary(); diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index cd2ecc7369..d53ac977be 100755 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -535,107 +535,84 @@ namespace OpenSim.Services.GridService public List GetRegionsByName(UUID scopeID, string name, int maxNumber) { -// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); + // m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); - List rdatas = m_Database.Get("%" + Util.EscapeForLike(name) + "%", scopeID); + var nameURI = new RegionURI(name); + if (!nameURI.IsValid) + return new List(); + + bool localGrid = true; + if (nameURI.HasHost) + { + if (!nameURI.ResolveDNS()) + return new List(); + localGrid = m_HypergridLinker.IsLocalGrid(nameURI.HostUrl); + nameURI.IsLocalGrid = localGrid; + if (!nameURI.IsValid) + return new List(); + } + + return GetRegionsByURI(scopeID, nameURI, maxNumber); + } + + public List GetRegionsByURI(UUID scopeID, RegionURI nameURI, int maxNumber) + { + // m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); + if (!nameURI.IsValid) + return new List(); + + List rdatas = m_Database.Get("%" + Util.EscapeForLike(nameURI.RegionUrlAndName) + "%", scopeID); int count = 0; List rinfos = new List(); - if (m_AllowHypergridMapSearch && name.Contains(".")) + if (m_AllowHypergridMapSearch && nameURI.HasHost) { - string regionURI = ""; - string regionName = ""; - if (!Util.buildHGRegionURI(name, out regionURI, out regionName)) - return null; - - string mapname; - bool localGrid = m_HypergridLinker.IsLocalGrid(regionURI); - if (localGrid) - { - if (String.IsNullOrWhiteSpace(regionName)) - return GetDefaultRegions(scopeID); - mapname = regionName; - } - else - mapname = regionURI + regionName; - + string mapname = nameURI.RegionUrlAndName; bool haveMatch = false; - if (rdatas != null && (rdatas.Count > 0)) { -// m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count); + // m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count); foreach (RegionData rdata in rdatas) { - if (count++ < maxNumber) - rinfos.Add(RegionData2RegionInfo(rdata)); - if(mapname.Equals(rdata.RegionName,StringComparison.InvariantCultureIgnoreCase)) - { - haveMatch = true; - if(count == maxNumber) - { - rinfos.RemoveAt(count - 1); - rinfos.Add(RegionData2RegionInfo(rdata)); - } - } - } - if(haveMatch) - return rinfos; - } - - rdatas = m_Database.Get(Util.EscapeForLike(mapname)+ "%", scopeID); - if (rdatas != null && (rdatas.Count > 0)) - { -// m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count); - foreach (RegionData rdata in rdatas) - { - if (count++ < maxNumber) - rinfos.Add(RegionData2RegionInfo(rdata)); if (mapname.Equals(rdata.RegionName, StringComparison.InvariantCultureIgnoreCase)) { haveMatch = true; - if(count == maxNumber) - { + rinfos.Insert(0, RegionData2RegionInfo(rdata)); + if (count == maxNumber) rinfos.RemoveAt(count - 1); - rinfos.Add(RegionData2RegionInfo(rdata)); - break; - } } + else if (count++ < maxNumber) + rinfos.Add(RegionData2RegionInfo(rdata)); } - if(haveMatch) + if (haveMatch) return rinfos; } - if(!localGrid && !string.IsNullOrWhiteSpace(regionURI)) + + GridRegion r = m_HypergridLinker.LinkRegion(scopeID, nameURI); + if (r != null) { - string HGname = regionURI +" "+ regionName; // include space for compatibility - GridRegion r = m_HypergridLinker.LinkRegion(scopeID, HGname); - if (r != null) - { - if( count == maxNumber) - rinfos.RemoveAt(count - 1); - rinfos.Add(r); - } + if (count == maxNumber) + rinfos.RemoveAt(count - 1); + rinfos.Add(r); } } else if (rdatas != null && (rdatas.Count > 0)) { + string name = nameURI.RegionName; //m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count); foreach (RegionData rdata in rdatas) { - if (count++ < maxNumber) - rinfos.Add(RegionData2RegionInfo(rdata)); if (name.Equals(rdata.RegionName, StringComparison.InvariantCultureIgnoreCase)) { + rinfos.Insert(0, RegionData2RegionInfo(rdata)); if (count == maxNumber) - { rinfos.RemoveAt(count - 1); - rinfos.Add(RegionData2RegionInfo(rdata)); - break; - } } + else if (count++ < maxNumber) + rinfos.Add(RegionData2RegionInfo(rdata)); } } - return rinfos; } diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index 1dce4a655c..bcc14cf57a 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -49,9 +49,7 @@ namespace OpenSim.Services.GridService { public class HypergridLinker : IHypergridLinker { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static uint m_autoMappingX = 0; private static uint m_autoMappingY = 0; @@ -148,6 +146,103 @@ namespace OpenSim.Services.GridService return TryLinkRegionToCoords(scopeID, regionDescriptor, (int)xloc, 0, out reason); } + public GridRegion LinkRegion(UUID scopeID, RegionURI rurl) + { + if(!rurl.IsValid) + return null; + + if (rurl.IsLocalGrid) + { + m_log.InfoFormat("[HYPERGRID LINKER]: Cannot hyperlink to regions on the same grid"); + return null; + } + + int xloc = random.Next(0, short.MaxValue) << 8; + if(TryCreateLinkImpl(scopeID, xloc, 0, rurl, UUID.Zero, out GridRegion regInfo)) + return regInfo; + return null; + } + + private static IPEndPoint dummyIP = new IPEndPoint(0,0); + private bool TryCreateLinkImpl(UUID scopeID, int xloc, int yloc, RegionURI rurl, UUID ownerID, out GridRegion regInfo) + { + m_log.InfoFormat("[HYPERGRID LINKER]: Link to {0} {1}, in <{2},{3}>", + rurl.HostUrl, rurl.RegionName, Util.WorldToRegionLoc((uint)xloc), Util.WorldToRegionLoc((uint)yloc)); + + + // Check for free coordinates + GridRegion region = m_GridService.GetRegionByPosition(scopeID, xloc, yloc); + if (region != null) + { + m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates <{0},{1}> are already occupied by region {2} with uuid {3}", + Util.WorldToRegionLoc((uint)xloc), Util.WorldToRegionLoc((uint)yloc), + region.RegionName, region.RegionID); + regInfo = null; + return false; + } + + regInfo = new GridRegion() + { + HttpPort = (uint)rurl.Port, + ExternalHostName = rurl.Host, + ServerURI = rurl.HostUrl, + RegionName = rurl.RegionName, + + RegionLocX = xloc, + RegionLocY = yloc, + ScopeID = scopeID, + EstateOwner = ownerID, + InternalEndPoint = dummyIP + }; + + // Finally, link it + ulong handle = 0; + UUID regionID = UUID.Zero; + string externalName = string.Empty; + string imageURL = string.Empty; + int sizeX = (int)Constants.RegionSize; + int sizeY = (int)Constants.RegionSize; + if (!m_GatekeeperConnector.LinkRegion(regInfo, out regionID, out handle, out externalName, out imageURL, out string reason, out sizeX, out sizeY)) + return false; + + if (regionID == UUID.Zero) + { + m_log.Warn("[HYPERGRID LINKER]: Unable to link region: " + reason); + return false; + } + + region = m_GridService.GetRegionByUUID(scopeID, regionID); + if (region != null) + { + m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates <{0},{1}>", + Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY)); + regInfo = region; + return true; + } + + regInfo.RegionID = regionID; + regInfo.RegionSizeX = sizeX; + regInfo.RegionSizeY = sizeY; + + if (externalName == string.Empty) + regInfo.RegionName = regInfo.ServerURI; + else + regInfo.RegionName = externalName; + + m_log.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 + regInfo.RegionSecret = handle.ToString(); + + AddHyperlinkRegion(regInfo, handle); + m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} at <{1},{2}> with image {3}", + regInfo.RegionName, Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY), regInfo.TerrainImage); + return true; + } + private static Random random = new Random(); // From the command line link-region (obsolete) and the map diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index bfa97a157c..66e0ed4b71 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -290,7 +290,7 @@ namespace OpenSim.Services.HypergridService m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}, desired region: {2}", m_GridName, gridName, region.RegionID); - if (m_GridName == gridName) + if (m_GridName.Equals(gridName, StringComparison.InvariantCultureIgnoreCase)) { success = m_GatekeeperService.LoginAgent(source, agentCircuit, finalDestination, out reason); } diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index 06313fc9d5..16bce68695 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -98,6 +98,7 @@ namespace OpenSim.Services.Interfaces /// grid-server couldn't be contacted or returned an error, return null. /// List GetRegionsByName(UUID scopeID, string name, int maxNumber); + List GetRegionsByURI(UUID scopeID, RegionURI uri, int maxNumber); List GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax); diff --git a/bin/OpenMetaverse.Rendering.Meshmerizer.dll b/bin/OpenMetaverse.Rendering.Meshmerizer.dll index 9a41123156..6c697d3b66 100755 Binary files a/bin/OpenMetaverse.Rendering.Meshmerizer.dll and b/bin/OpenMetaverse.Rendering.Meshmerizer.dll differ diff --git a/bin/OpenMetaverse.StructuredData.dll b/bin/OpenMetaverse.StructuredData.dll index 364452db42..e7f7a99336 100755 Binary files a/bin/OpenMetaverse.StructuredData.dll and b/bin/OpenMetaverse.StructuredData.dll differ diff --git a/bin/OpenMetaverse.dll b/bin/OpenMetaverse.dll index 1fc2570efb..6476a66eb1 100755 Binary files a/bin/OpenMetaverse.dll and b/bin/OpenMetaverse.dll differ diff --git a/bin/OpenMetaverseTypes.dll b/bin/OpenMetaverseTypes.dll index b8d36b701e..2c403092e3 100755 Binary files a/bin/OpenMetaverseTypes.dll and b/bin/OpenMetaverseTypes.dll differ