diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 73701560de..b1234fec28 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -128,104 +128,104 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_Clients.Add(remoteClient.AgentId); } - try - { - OnMapNameRequest(remoteClient, mapName, flags); - } - finally - { - lock (m_Clients) - m_Clients.Remove(remoteClient.AgentId); - } + OnMapNameRequest(remoteClient, mapName, flags); } private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { Util.FireAndForget(x => { - List blocks = new List(); - if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) + try { + List blocks = new List(); + if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) + { + // final block, closing the search result + AddFinalBlock(blocks,mapName); + + // flags are agent flags sent from the viewer. + // they have different values depending on different viewers, apparently + remoteClient.SendMapBlock(blocks, flags); + remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); + return; + } + + //m_log.DebugFormat("MAP NAME=({0})", mapName); + + // Hack to get around the fact that ll V3 now drops the port from the + // map name. See https://jira.secondlife.com/browse/VWR-28570 + // + // Caller, use this magic form instead: + // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 + // or url encode if possible. + // the hacks we do with this viewer... + // + bool needOriginalName = false; + string mapNameOrig = mapName; + if (mapName.Contains("|")) + { + mapName = mapName.Replace('|', ':'); + needOriginalName = true; + } + if (mapName.Contains("+")) + { + mapName = mapName.Replace('+', ' '); + needOriginalName = true; + } + if (mapName.Contains("!")) + { + mapName = mapName.Replace('!', '/'); + needOriginalName = true; + } + if (mapName.Contains(".")) + needOriginalName = true; + + // try to fetch from GridServer + List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); + // if (regionInfos.Count == 0) + // remoteClient.SendAlertMessage("Hyperlink could not be established."); + + //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); + + MapBlockData data; + if (regionInfos.Count > 0) + { + foreach (GridRegion info in regionInfos) + { + data = new MapBlockData(); + data.Agents = 0; + data.Access = info.Access; + MapBlockData block = new MapBlockData(); + WorldMap.MapBlockFromGridRegion(block, info, flags); + + if (flags == 2 && regionInfos.Count == 1 && needOriginalName) + block.Name = mapNameOrig; + blocks.Add(block); + } + } + // final block, closing the search result - AddFinalBlock(blocks,mapName); + AddFinalBlock(blocks,mapNameOrig); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); - remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); - return; - } - //m_log.DebugFormat("MAP NAME=({0})", mapName); - - // Hack to get around the fact that ll V3 now drops the port from the - // map name. See https://jira.secondlife.com/browse/VWR-28570 - // - // Caller, use this magic form instead: - // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 - // or url encode if possible. - // the hacks we do with this viewer... - // - bool needOriginalName = false; - string mapNameOrig = mapName; - if (mapName.Contains("|")) - { - mapName = mapName.Replace('|', ':'); - needOriginalName = true; - } - if (mapName.Contains("+")) - { - mapName = mapName.Replace('+', ' '); - needOriginalName = true; - } - if (mapName.Contains("!")) - { - mapName = mapName.Replace('!', '/'); - needOriginalName = true; - } - if (mapName.Contains(".")) - needOriginalName = true; - - // try to fetch from GridServer - List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); - // if (regionInfos.Count == 0) - // remoteClient.SendAlertMessage("Hyperlink could not be established."); - - //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); - - MapBlockData data; - if (regionInfos.Count > 0) - { - foreach (GridRegion info in regionInfos) + // send extra user messages for V3 + // because the UI is very confusing + // while we don't fix the hard-coded urls + if (flags == 2) { - data = new MapBlockData(); - data.Agents = 0; - data.Access = info.Access; - MapBlockData block = new MapBlockData(); - WorldMap.MapBlockFromGridRegion(block, info, flags); - - if (flags == 2 && regionInfos.Count == 1 && needOriginalName) - block.Name = mapNameOrig; - blocks.Add(block); + if (regionInfos.Count == 0) + remoteClient.SendAgentAlertMessage("No regions found with that name.", true); + // else if (regionInfos.Count == 1) + // remoteClient.SendAgentAlertMessage("Region found!", false); } } - - // final block, closing the search result - AddFinalBlock(blocks,mapNameOrig); - - // flags are agent flags sent from the viewer. - // they have different values depending on different viewers, apparently - remoteClient.SendMapBlock(blocks, flags); - - // send extra user messages for V3 - // because the UI is very confusing - // while we don't fix the hard-coded urls - if (flags == 2) + finally { - if (regionInfos.Count == 0) - remoteClient.SendAgentAlertMessage("No regions found with that name.", true); -// else if (regionInfos.Count == 1) -// remoteClient.SendAgentAlertMessage("Region found!", false); + lock (m_Clients) + m_Clients.Remove(remoteClient.AgentId); } }); } diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index a11cae1c4b..66c918f9e3 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -579,7 +579,70 @@ namespace OpenSim.Services.GridService int count = 0; List rinfos = new List(); - if (rdatas != null) + if (count < maxNumber && m_AllowHypergridMapSearch && name.Contains(".")) + { + string regionURI = ""; + string regionName = ""; + if(!m_HypergridLinker.buildHGRegionURI(name, out regionURI, out regionName)) + return null; + + string mapname = regionURI + regionName; + bool haveMatch = false; + + 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(rdata.RegionName == mapname) + { + 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(rdata.RegionName == mapname) + { + haveMatch = true; + if(count == maxNumber) + { + rinfos.RemoveAt(count - 1); + rinfos.Add(RegionData2RegionInfo(rdata)); + break; + } + } + } + if(haveMatch) + return rinfos; + } + + string HGname = regionURI +" "+ regionName; + GridRegion r = m_HypergridLinker.LinkRegion(scopeID, HGname); + if (r != null) + { + if( count == maxNumber) + rinfos.RemoveAt(count - 1); + rinfos.Add(r); + } + } + else if (rdatas != null && (rdatas.Count > 0)) { // m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count); foreach (RegionData rdata in rdatas) @@ -589,13 +652,6 @@ namespace OpenSim.Services.GridService } } - if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0))) - { - GridRegion r = GetHypergridRegionByName(scopeID, name); - if (r != null) - rinfos.Add(r); - } - return rinfos; } @@ -608,7 +664,20 @@ namespace OpenSim.Services.GridService protected GridRegion GetHypergridRegionByName(UUID scopeID, string name) { if (name.Contains(".")) - return m_HypergridLinker.LinkRegion(scopeID, name); + { + string regionURI = ""; + string regionName = ""; + if(!m_HypergridLinker.buildHGRegionURI(name, out regionURI, out regionName)) + return null; + + string mapname = regionURI + regionName; + List rdatas = m_Database.Get(Util.EscapeForLike(mapname), scopeID); + if ((rdatas != null) && (rdatas.Count > 0)) + return RegionData2RegionInfo(rdatas[0]); // get the first + + string HGname = regionURI +" "+ regionName; + return m_HypergridLinker.LinkRegion(scopeID, HGname); + } else return null; } diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index 28693499a2..e00025bfef 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -191,14 +191,14 @@ namespace OpenSim.Services.GridService return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason); } - public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason) + public bool buildHGRegionURI(string inputName, out string serverURI, out string regionName) { - reason = string.Empty; - GridRegion regInfo = null; + serverURI = string.Empty; + regionName = string.Empty; - mapName = mapName.Trim(); + inputName = inputName.Trim(); - if (!mapName.StartsWith("http") && !mapName.StartsWith("https")) + if (!inputName.StartsWith("http") && !inputName.StartsWith("https")) { // Formats: grid.example.com:8002:region name // grid.example.com:region name @@ -207,38 +207,59 @@ namespace OpenSim.Services.GridService string host; uint port = 80; - string regionName = ""; - string[] parts = mapName.Split(new char[] { ':' }); - - if (parts.Length == 0) + string[] parts = inputName.Split(new char[] { ':' }); + int indx; + if(parts.Length == 0) + return false; + if (parts.Length == 1) { - reason = "Wrong format for link-region"; - return null; + indx = inputName.IndexOf('/'); + if (indx < 0) + serverURI = "http://"+ inputName + "/"; + else + { + serverURI = "http://"+ inputName.Substring(0,indx + 1); + if(indx + 2 < inputName.Length) + regionName = inputName.Substring(indx + 1); + } } - - host = parts[0]; - - if (parts.Length >= 2) + else { - // If it's a number then assume it's a port. Otherwise, it's a region name. - if (!UInt32.TryParse(parts[1], out port)) - regionName = parts[1]; - } + host = parts[0]; + + if (parts.Length >= 2) + { + indx = parts[1].IndexOf('/'); + if(indx < 0) + { + // If it's a number then assume it's a port. Otherwise, it's a region name. + if (!UInt32.TryParse(parts[1], out port)) + { + port = 80; + regionName = parts[1]; + } + } + else + { + string portstr = parts[1].Substring(0, indx); + if(indx + 2 < parts[1].Length) + regionName = parts[1].Substring(indx + 1); + if (!UInt32.TryParse(portstr, out port)) + port = 80; + } + } + // always take the last one + if (parts.Length >= 3) + { + regionName = parts[2]; + } - // always take the last one - if (parts.Length >= 3) - { - regionName = parts[2]; - } - - string serverURI = "http://"+ host +":"+ port.ToString() + "/"; -// bool success = TryCreateLink(scopeID, xloc, yloc, regionName, port, host, ownerID, out regInfo, out reason); - if(TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason)) - { - regInfo.RegionName = mapName; - return regInfo; - } + if(port == 80) + serverURI = "http://"+ host + "/"; + else + serverURI = "http://"+ host +":"+ port.ToString() + "/"; + } } else { @@ -246,32 +267,61 @@ namespace OpenSim.Services.GridService // http://grid.example.com "region name" // http://grid.example.com - string serverURI; - string regionName = ""; - - string[] parts = mapName.Split(new char[] { ' ' }); + string[] parts = inputName.Split(new char[] { ' ' }); if (parts.Length == 0) - { - reason = "Wrong format for link-region"; - return null; - } + return false; serverURI = parts[0]; - if (!serverURI.EndsWith("/")) - serverURI = serverURI + "/"; - if (parts.Length >= 2) + int indx = serverURI.LastIndexOf('/'); + if(indx > 10) { - regionName = mapName.Substring(serverURI.Length); - regionName = regionName.Trim(new char[] { '"', ' ' }); + if(indx + 2 < inputName.Length) + regionName = inputName.Substring(indx + 1); + serverURI = inputName.Substring(0, indx + 1); } + else if (parts.Length >= 2) + { + regionName = inputName.Substring(serverURI.Length); + } + } - if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason)) - { - regInfo.RegionName = mapName; - return regInfo; - } + // use better code for sanity check + Uri uri; + try + { + uri = new Uri(serverURI); + } + catch + { + return false; + } + + if(!string.IsNullOrEmpty(regionName)) + regionName = regionName.Trim(new char[] { '"', ' ' }); + serverURI = uri.AbsoluteUri; + return true; + } + + public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason) + { + reason = string.Empty; + GridRegion regInfo = null; + + string serverURI = string.Empty; + string regionName = string.Empty; + + if(!buildHGRegionURI(mapName, out serverURI, out regionName)) + { + reason = "Wrong URI format for link-region"; + return null; + } + + if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason)) + { + regInfo.RegionName = serverURI + regionName; + return regInfo; } return null;