From 16d68749a457acf079a6737f4ca9a9adb9e53e2f Mon Sep 17 00:00:00 2001 From: Homer Horwitz Date: Fri, 3 Oct 2008 23:00:42 +0000 Subject: Add the missing bits for the new region-search: - Added lookup in the data-layer - MySQL works - SQLite doesn't have a grid-db, so it won't work there - I added MSSQL-code to the best of my knowledge; but I don't know MSSQL :-) - Added the plumbing up to OGS1GridServices. This speaks with the grid-server via XMLRPC. - Modified MapSearchModule to use the new data. It's backward compatible; if used with an old grid-server, it just returns one found region instead of a list. - Refactored a bit. Note: This updates data, grid-server and region code. No new files. --- .../Communications/Local/LocalBackEndServices.cs | 15 +++ .../Region/Communications/OGS1/OGS1GridServices.cs | 119 +++++++++++++-------- .../Modules/World/WorldMap/MapSearchModule.cs | 57 +++++----- .../Scenes/SceneCommunicationService.cs | 6 +- 4 files changed, 129 insertions(+), 68 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Communications/Local/LocalBackEndServices.cs b/OpenSim/Region/Communications/Local/LocalBackEndServices.cs index a861ceb..9034e49 100644 --- a/OpenSim/Region/Communications/Local/LocalBackEndServices.cs +++ b/OpenSim/Region/Communications/Local/LocalBackEndServices.cs @@ -514,5 +514,20 @@ namespace OpenSim.Region.Communications.Local m_log.Debug("[INTERREGION STANDALONE] didn't find land data locally."); return null; } + + public List RequestNamedRegions (string name, int maxNumber) + { + List regions = new List(); + foreach (RegionInfo info in m_regions.Values) + { + if (info.RegionName.StartsWith(name)) + { + regions.Add(info); + if (regions.Count >= maxNumber) break; + } + } + + return regions; + } } } diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs index a2d3823..397062b 100644 --- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs +++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs @@ -352,27 +352,7 @@ namespace OpenSim.Region.Communications.OGS1 return null; } - uint regX = Convert.ToUInt32((string) responseData["region_locx"]); - uint regY = Convert.ToUInt32((string) responseData["region_locy"]); - string internalIpStr = (string) responseData["sim_ip"]; - uint port = Convert.ToUInt32(responseData["sim_port"]); - // string externalUri = (string) responseData["sim_uri"]; - - IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int) port); - // string neighbourExternalUri = externalUri; - regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr); - - regionInfo.RemotingPort = Convert.ToUInt32((string) responseData["remoting_port"]); - regionInfo.RemotingAddress = internalIpStr; - - if (responseData.ContainsKey("http_port")) - { - regionInfo.HttpPort = Convert.ToUInt32((string) responseData["http_port"]); - } - - regionInfo.RegionID = new UUID((string) responseData["region_UUID"]); - regionInfo.RegionName = (string) responseData["region_name"]; - + regionInfo = buildRegionInfo(responseData, String.Empty); if (requestData.ContainsKey("regionHandle")) { m_remoteRegionInfoCache.Add(Convert.ToUInt64((string) requestData["regionHandle"]), regionInfo); @@ -479,30 +459,11 @@ namespace OpenSim.Region.Communications.OGS1 if (responseData.ContainsKey("error")) { - m_log.Error("[OGS1 GRID SERVICES]: Error received from grid server" + responseData["error"]); + m_log.ErrorFormat("[OGS1 GRID SERVICES]: Error received from grid server: ", responseData["error"]); return null; } - uint regX = Convert.ToUInt32((string) responseData["region_locx"]); - uint regY = Convert.ToUInt32((string) responseData["region_locy"]); - string internalIpStr = (string) responseData["sim_ip"]; - uint port = Convert.ToUInt32(responseData["sim_port"]); - // string externalUri = (string) responseData["sim_uri"]; - - IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int) port); - // string neighbourExternalUri = externalUri; - regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr); - - regionInfo.RemotingPort = Convert.ToUInt32((string) responseData["remoting_port"]); - regionInfo.RemotingAddress = internalIpStr; - - if (responseData.ContainsKey("http_port")) - { - regionInfo.HttpPort = Convert.ToUInt32((string) responseData["http_port"]); - } - - regionInfo.RegionID = new UUID((string) responseData["region_UUID"]); - regionInfo.RegionName = (string) responseData["region_name"]; + regionInfo = buildRegionInfo(responseData, ""); if (!m_remoteRegionInfoCache.ContainsKey(regionInfo.RegionHandle)) m_remoteRegionInfoCache.Add(regionInfo.RegionHandle, regionInfo); @@ -1676,7 +1637,8 @@ namespace OpenSim.Region.Communications.OGS1 else { hash = (Hashtable)response.Value; - try { + try + { landData = new LandData(); landData.AABBMax = Vector3.Parse((string)hash["AABBMax"]); landData.AABBMin = Vector3.Parse((string)hash["AABBMin"]); @@ -1745,5 +1707,76 @@ namespace OpenSim.Region.Communications.OGS1 response.Value = hash; return response; } + + public List RequestNamedRegions (string name, int maxNumber) + { + // no asking of the local backend first, here, as we have to ask the gridserver anyway. + Hashtable hash = new Hashtable(); + hash["name"] = name; + hash["maxNumber"] = maxNumber.ToString(); + + IList paramList = new ArrayList(); + paramList.Add(hash); + + Hashtable result = XmlRpcSearchForRegionByName(paramList); + if (result == null) return null; + + uint numberFound = Convert.ToUInt32(result["numFound"]); + List infos = new List(); + for (int i = 0; i < numberFound; ++i) + { + string prefix = "region" + i + "."; + RegionInfo info = buildRegionInfo(result, prefix); + infos.Add(info); + } + return infos; + } + + private RegionInfo buildRegionInfo(Hashtable responseData, string prefix) + { + uint regX = Convert.ToUInt32((string) responseData[prefix + "region_locx"]); + uint regY = Convert.ToUInt32((string) responseData[prefix + "region_locy"]); + string internalIpStr = (string) responseData[prefix + "sim_ip"]; + uint port = Convert.ToUInt32(responseData[prefix + "sim_port"]); + + IPEndPoint neighbourInternalEndPoint = new IPEndPoint(Util.GetHostFromDNS(internalIpStr), (int) port); + + RegionInfo regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr); + regionInfo.RemotingPort = Convert.ToUInt32((string) responseData[prefix + "remoting_port"]); + regionInfo.RemotingAddress = internalIpStr; + + if (responseData.ContainsKey(prefix + "http_port")) + { + regionInfo.HttpPort = Convert.ToUInt32((string) responseData[prefix + "http_port"]); + } + + regionInfo.RegionID = new UUID((string) responseData[prefix + "region_UUID"]); + regionInfo.RegionName = (string) responseData[prefix + "region_name"]; + + regionInfo.RegionSettings.TerrainImageID = new UUID((string) responseData[prefix + "map_UUID"]); + return regionInfo; + } + + private Hashtable XmlRpcSearchForRegionByName(IList parameters) + { + try + { + XmlRpcRequest request = new XmlRpcRequest("search_for_region_by_name", parameters); + XmlRpcResponse resp = request.Send(serversInfo.GridURL, 10000); + Hashtable respData = (Hashtable) resp.Value; + if (respData != null && respData.Contains("faultCode")) + { + m_log.WarnFormat("[OGS1 GRID SERVICES]: Got an error while contacting GridServer: {0}", respData["faultString"]); + return null; + } + + return respData; + } + catch (Exception e) + { + m_log.Error("[OGS1 GRID SERVICES]: MapBlockQuery XMLRPC failure: ", e); + return null; + } + } } } \ No newline at end of file diff --git a/OpenSim/Region/Environment/Modules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/Environment/Modules/World/WorldMap/MapSearchModule.cs index 1a15585..8cc707c 100644 --- a/OpenSim/Region/Environment/Modules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/Environment/Modules/World/WorldMap/MapSearchModule.cs @@ -78,35 +78,44 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap private void OnMapNameRequest(IClientAPI remoteClient, string mapName) { - m_log.DebugFormat("[MAPSEARCH]: looking for region {0}", mapName); - - // TODO currently, this only returns one region per name. LL servers will return all starting with the provided name. - RegionInfo info = m_scene.SceneGridService.RequestClosestRegion(mapName); - // fetch the mapblock of the named sim. We need this anyway (we have the map open, and just jumped to the sim), - // so there shouldn't be any penalty for that. - if (info == null) - { - m_log.Warn("[MAPSEARCHMODULE]: Got Null Region Question!"); - return; + if (mapName.Length < 3) + { + remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); + return; + } + + // try to fetch from GridServer + List regionInfos = m_scene.SceneGridService.RequestNamedRegions(mapName, 20); + if (regionInfos == null) + { + m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?"); + // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region + regionInfos = new List(); + RegionInfo info = m_scene.SceneGridService.RequestClosestRegion(mapName); + if (info != null) regionInfos.Add(info); } - List mapBlocks = m_scene.SceneGridService.RequestNeighbourMapBlocks((int)info.RegionLocX, - (int)info.RegionLocY, - (int)info.RegionLocX, - (int)info.RegionLocY); List blocks = new List(); - MapBlockData data = new MapBlockData(); - data.Agents = 3; // TODO set to number of agents in region - data.Access = 21; // TODO what's this? - data.MapImageId = mapBlocks.Count == 0 ? UUID.Zero : mapBlocks[0].MapImageId; - data.Name = info.RegionName; - data.RegionFlags = 0; // TODO fix this - data.WaterHeight = 0; // not used - data.X = (ushort)info.RegionLocX; - data.Y = (ushort)info.RegionLocY; - blocks.Add(data); + MapBlockData data; + if (regionInfos.Count > 0) + { + foreach (RegionInfo info in regionInfos) + { + data = new MapBlockData(); + data.Agents = 0; + data.Access = 21; // TODO what's this? + data.MapImageId = info.RegionSettings.TerrainImageID; + data.Name = info.RegionName; + data.RegionFlags = 0; // TODO not used? + data.WaterHeight = 0; // not used + data.X = (ushort)info.RegionLocX; + data.Y = (ushort)info.RegionLocY; + blocks.Add(data); + } + } + // final block, closing the search result data = new MapBlockData(); data.Agents = 0; data.Access = 255; diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index c33c777..08793d9 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -806,6 +806,10 @@ namespace OpenSim.Region.Environment.Scenes { return m_commsProvider.GenerateAgentPickerRequestResponse(queryID, query); } - + + public List RequestNamedRegions(string name, int maxNumber) + { + return m_commsProvider.GridService.RequestNamedRegions(name, maxNumber); + } } } -- cgit v1.1