From 134f86e8d5c414409631b25b8c6f0ee45fbd8631 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Thu, 3 Nov 2016 21:44:39 +1000 Subject: Initial update to OpenSim 0.8.2.1 source code. --- OpenSim/Services/GridService/GridService.cs | 415 +++++++++++++++++---- OpenSim/Services/GridService/HypergridLinker.cs | 236 ++++++++---- .../GridService/Properties/AssemblyInfo.cs | 4 +- 3 files changed, 515 insertions(+), 140 deletions(-) (limited to 'OpenSim/Services/GridService') diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index ee3b858..0c502a2 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -46,6 +46,7 @@ namespace OpenSim.Services.GridService private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); + private string LogHeader = "[GRID SERVICE]"; private bool m_DeleteOnUnregister = true; private static GridService m_RootInstance = null; @@ -56,6 +57,10 @@ namespace OpenSim.Services.GridService protected bool m_AllowDuplicateNames = false; protected bool m_AllowHypergridMapSearch = false; + protected bool m_SuppressVarregionOverlapCheckOnRegistration = false; + + private static Dictionary m_ExtraFeatures = new Dictionary(); + public GridService(IConfigSource config) : base(config) { @@ -63,6 +68,9 @@ namespace OpenSim.Services.GridService m_config = config; IConfig gridConfig = config.Configs["GridService"]; + + bool suppressConsoleCommands = false; + if (gridConfig != null) { m_DeleteOnUnregister = gridConfig.GetBoolean("DeleteOnUnregister", true); @@ -76,32 +84,33 @@ namespace OpenSim.Services.GridService } m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch); + + m_SuppressVarregionOverlapCheckOnRegistration = gridConfig.GetBoolean("SuppressVarregionOverlapCheckOnRegistration", m_SuppressVarregionOverlapCheckOnRegistration); + + // This service is also used locally by a simulator running in grid mode. This switches prevents + // inappropriate console commands from being registered + suppressConsoleCommands = gridConfig.GetBoolean("SuppressConsoleCommands", suppressConsoleCommands); } - + if (m_RootInstance == null) { m_RootInstance = this; - if (MainConsole.Instance != null) + if (!suppressConsoleCommands && MainConsole.Instance != null) { MainConsole.Instance.Commands.AddCommand("Regions", true, "deregister region id", - "deregister region id ", + "deregister region id +", "Deregister a region manually.", String.Empty, HandleDeregisterRegion); - // A messy way of stopping this command being added if we are in standalone (since the simulator - // has an identically named command - // - // XXX: We're relying on the OpenSimulator version being registered first, which is not well defined. - if (MainConsole.Instance.Commands.Resolve(new string[] { "show", "regions" }).Length == 0) - MainConsole.Instance.Commands.AddCommand("Regions", true, - "show regions", - "show regions", - "Show details on all regions", - String.Empty, - HandleShowRegions); + MainConsole.Instance.Commands.AddCommand("Regions", true, + "show regions", + "show regions", + "Show details on all regions", + String.Empty, + HandleShowRegions); MainConsole.Instance.Commands.AddCommand("Regions", true, "show region name", @@ -117,17 +126,72 @@ namespace OpenSim.Services.GridService "For example, show region at 1000 1000", HandleShowRegionAt); - MainConsole.Instance.Commands.AddCommand("Regions", true, - "set region flags", - "set region flags ", - "Set database flags for region", + MainConsole.Instance.Commands.AddCommand("General", true, + "show grid size", + "show grid size", + "Show the current grid size (excluding hyperlink references)", String.Empty, - HandleSetFlags); + HandleShowGridSize); + + MainConsole.Instance.Commands.AddCommand("Regions", true, + "set region flags", + "set region flags ", + "Set database flags for region", + String.Empty, + HandleSetFlags); } + + if (!suppressConsoleCommands) + SetExtraServiceURLs(config); + m_HypergridLinker = new HypergridLinker(m_config, this, m_Database); } } + private void SetExtraServiceURLs(IConfigSource config) + { + IConfig loginConfig = config.Configs["LoginService"]; + IConfig gridConfig = config.Configs["GridService"]; + + if (loginConfig == null || gridConfig == null) + return; + + string configVal; + + configVal = loginConfig.GetString("SearchURL", string.Empty); + if (!string.IsNullOrEmpty(configVal)) + m_ExtraFeatures["search-server-url"] = configVal; + + configVal = loginConfig.GetString("MapTileURL", string.Empty); + if (!string.IsNullOrEmpty(configVal)) + { + // This URL must end with '/', the viewer doesn't check + configVal = configVal.Trim(); + if (!configVal.EndsWith("/")) + configVal = configVal + "/"; + m_ExtraFeatures["map-server-url"] = configVal; + } + + configVal = loginConfig.GetString("DestinationGuide", string.Empty); + if (!string.IsNullOrEmpty(configVal)) + m_ExtraFeatures["destination-guide-url"] = configVal; + + configVal = Util.GetConfigVarFromSections( + config, "GatekeeperURI", new string[] { "Startup", "Hypergrid" }, String.Empty); + if (!string.IsNullOrEmpty(configVal)) + m_ExtraFeatures["GridURL"] = configVal; + + configVal = Util.GetConfigVarFromSections( + config, "GridName", new string[] { "Const", "Hypergrid" }, String.Empty); + if (string.IsNullOrEmpty(configVal)) + configVal = Util.GetConfigVarFromSections( + config, "gridname", new string[] { "GridInfo" }, String.Empty); + if (!string.IsNullOrEmpty(configVal)) + m_ExtraFeatures["GridName"] = configVal; + + m_ExtraFeatures["ExportSupported"] = gridConfig.GetString("ExportSupported", "true"); + } + #region IGridService public string RegisterRegion(UUID scopeID, GridRegion regionInfos) @@ -137,12 +201,19 @@ namespace OpenSim.Services.GridService if (regionInfos.RegionID == UUID.Zero) return "Invalid RegionID - cannot be zero UUID"; - RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); - if ((region != null) && (region.RegionID != regionInfos.RegionID)) + String reason = "Region overlaps another region"; + RegionData region = FindAnyConflictingRegion(regionInfos, scopeID, out reason); + // If there is a conflicting region, if it has the same ID and same coordinates + // then it is a region re-registering (permissions and ownership checked later). + if ((region != null) + && ( (region.coordX != regionInfos.RegionCoordX) + || (region.coordY != regionInfos.RegionCoordY) + || (region.RegionID != regionInfos.RegionID) ) + ) { - m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.", - regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); - return "Region overlaps another region"; + // If not same ID and same coordinates, this new region has conflicts and can't be registered. + m_log.WarnFormat("{0} Register region conflict in scope {1}. {2}", LogHeader, scopeID, reason); + return reason; } if (region != null) @@ -185,15 +256,15 @@ namespace OpenSim.Services.GridService if (!m_AllowDuplicateNames) { - List dupe = m_Database.Get(regionInfos.RegionName, scopeID); + List dupe = m_Database.Get(Util.EscapeForLike(regionInfos.RegionName), scopeID); if (dupe != null && dupe.Count > 0) { foreach (RegionData d in dupe) { if (d.RegionID != regionInfos.RegionID) { - m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register duplicate name with ID {1}.", - regionInfos.RegionName, regionInfos.RegionID); + m_log.WarnFormat("[GRID SERVICE]: Region tried to register using a duplicate name. New region: {0} ({1}), existing region: {2} ({3}).", + regionInfos.RegionName, regionInfos.RegionID, d.RegionName, d.RegionID); return "Duplicate region name"; } } @@ -265,12 +336,121 @@ namespace OpenSim.Services.GridService m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); } - m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}", - regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY); + m_log.InfoFormat + ("[GRID SERVICE]: Region {0} ({1}, {2}x{3}) registered at {4},{5} with flags {6}", + regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionSizeX, regionInfos.RegionSizeY, + regionInfos.RegionCoordX, regionInfos.RegionCoordY, + (OpenSim.Framework.RegionFlags)flags); return String.Empty; } + /// + /// Search the region map for regions conflicting with this region. + /// The region to be added is passed and we look for any existing regions that are + /// in the requested location, that are large varregions that overlap this region, or + /// are previously defined regions that would lie under this new region. + /// + /// Information on region requested to be added to the world map + /// Grid id for region + /// The reason the returned region conflicts with passed region + /// + private RegionData FindAnyConflictingRegion(GridRegion regionInfos, UUID scopeID, out string reason) + { + reason = "Reregistration"; + // First see if there is an existing region right where this region is trying to go + // (We keep this result so it can be returned if suppressing errors) + RegionData noErrorRegion = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); + RegionData region = noErrorRegion; + if (region != null + && region.RegionID == regionInfos.RegionID + && region.sizeX == regionInfos.RegionSizeX + && region.sizeY == regionInfos.RegionSizeY) + { + // If this seems to be exactly the same region, return this as it could be + // a re-registration (permissions checked by calling routine). + m_log.DebugFormat("{0} FindAnyConflictingRegion: re-register of {1}", + LogHeader, RegionString(regionInfos)); + return region; + } + + // No region exactly there or we're resizing an existing region. + // Fetch regions that could be varregions overlapping requested location. + int xmin = regionInfos.RegionLocX - (int)Constants.MaximumRegionSize + 10; + int xmax = regionInfos.RegionLocX; + int ymin = regionInfos.RegionLocY - (int)Constants.MaximumRegionSize + 10; + int ymax = regionInfos.RegionLocY; + List rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID); + foreach (RegionData rdata in rdatas) + { + // m_log.DebugFormat("{0} FindAnyConflictingRegion: find existing. Checking {1}", LogHeader, RegionString(rdata) ); + if ( (rdata.posX + rdata.sizeX > regionInfos.RegionLocX) + && (rdata.posY + rdata.sizeY > regionInfos.RegionLocY) ) + { + region = rdata; + m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of {1} by existing varregion {2}", + LogHeader, RegionString(regionInfos), RegionString(region)); + reason = String.Format("Region location is overlapped by existing varregion {0}", + RegionString(region)); + + if (m_SuppressVarregionOverlapCheckOnRegistration) + region = noErrorRegion; + return region; + } + } + + // There isn't a region that overlaps this potential region. + // See if this potential region overlaps an existing region. + // First, a shortcut of not looking for overlap if new region is legacy region sized + // and connot overlap anything. + if (regionInfos.RegionSizeX != Constants.RegionSize + || regionInfos.RegionSizeY != Constants.RegionSize) + { + // trim range looked for so we don't pick up neighbor regions just off the edges + xmin = regionInfos.RegionLocX; + xmax = regionInfos.RegionLocX + regionInfos.RegionSizeX - 10; + ymin = regionInfos.RegionLocY; + ymax = regionInfos.RegionLocY + regionInfos.RegionSizeY - 10; + rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID); + + // If the region is being resized, the found region could be ourself. + foreach (RegionData rdata in rdatas) + { + // m_log.DebugFormat("{0} FindAnyConflictingRegion: see if overlap. Checking {1}", LogHeader, RegionString(rdata) ); + if (region == null || region.RegionID != regionInfos.RegionID) + { + region = rdata; + m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of varregion {1} overlaps existing region {2}", + LogHeader, RegionString(regionInfos), RegionString(region)); + reason = String.Format("Region {0} would overlap existing region {1}", + RegionString(regionInfos), RegionString(region)); + + if (m_SuppressVarregionOverlapCheckOnRegistration) + region = noErrorRegion; + return region; + } + } + } + + // If we get here, region is either null (nothing found here) or + // is the non-conflicting region found at the location being requested. + return region; + } + + // String describing name and region location of passed region + private String RegionString(RegionData reg) + { + return String.Format("{0}/{1} at <{2},{3}>", + reg.RegionName, reg.RegionID, reg.coordX, reg.coordY); + } + + // String describing name and region location of passed region + private String RegionString(GridRegion reg) + { + return String.Format("{0}/{1} at <{2},{3}>", + reg.RegionName, reg.RegionID, reg.RegionCoordX, reg.RegionCoordY); + } + public bool DeregisterRegion(UUID regionID) { RegionData region = m_Database.Get(regionID, UUID.Zero); @@ -312,8 +492,10 @@ namespace OpenSim.Services.GridService if (region != null) { // Not really? Maybe? - List rdatas = m_Database.Get(region.posX - (int)Constants.RegionSize - 1, region.posY - (int)Constants.RegionSize - 1, - region.posX + (int)Constants.RegionSize + 1, region.posY + (int)Constants.RegionSize + 1, scopeID); + // The adjacent regions are presumed to be the same size as the current region + List rdatas = m_Database.Get( + region.posX - region.sizeX - 1, region.posY - region.sizeY - 1, + region.posX + region.sizeX + 1, region.posY + region.sizeY + 1, scopeID); foreach (RegionData rdata in rdatas) { @@ -325,7 +507,11 @@ namespace OpenSim.Services.GridService } } -// m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighbours", region.RegionName, rinfos.Count); + // string rNames = ""; + // foreach (GridRegion gr in rinfos) + // rNames += gr.RegionName + ","; + // m_log.DebugFormat("{0} region {1} has {2} neighbours ({3})", + // LogHeader, region.RegionName, rinfos.Count, rNames); } else { @@ -346,20 +532,36 @@ namespace OpenSim.Services.GridService return null; } + // Get a region given its base coordinates. + // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST + // be the base coordinate of the region. + // The snapping is technically unnecessary but is harmless because regions are always + // multiples of the legacy region size (256). public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) { - int snapX = (int)(x / Constants.RegionSize) * (int)Constants.RegionSize; - int snapY = (int)(y / Constants.RegionSize) * (int)Constants.RegionSize; + uint regionX = Util.WorldToRegionLoc((uint)x); + uint regionY = Util.WorldToRegionLoc((uint)y); + int snapX = (int)Util.RegionToWorldLoc(regionX); + int snapY = (int)Util.RegionToWorldLoc(regionY); + RegionData rdata = m_Database.Get(snapX, snapY, scopeID); if (rdata != null) + { + m_log.DebugFormat("{0} GetRegionByPosition. Found region {1} in database. Pos=<{2},{3}>", + LogHeader, rdata.RegionName, regionX, regionY); return RegionData2RegionInfo(rdata); - - return null; + } + else + { + m_log.DebugFormat("{0} GetRegionByPosition. Did not find region in database. Pos=<{1},{2}>", + LogHeader, regionX, regionY); + return null; + } } public GridRegion GetRegionByName(UUID scopeID, string name) { - List rdatas = m_Database.Get(name, scopeID); + List rdatas = m_Database.Get(Util.EscapeForLike(name), scopeID); if ((rdatas != null) && (rdatas.Count > 0)) return RegionData2RegionInfo(rdatas[0]); // get the first @@ -377,7 +579,7 @@ namespace OpenSim.Services.GridService { // m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); - List rdatas = m_Database.Get(name + "%", scopeID); + List rdatas = m_Database.Get(Util.EscapeForLike(name) + "%", scopeID); int count = 0; List rinfos = new List(); @@ -440,6 +642,8 @@ namespace OpenSim.Services.GridService RegionData rdata = new RegionData(); rdata.posX = (int)rinfo.RegionLocX; rdata.posY = (int)rinfo.RegionLocY; + rdata.sizeX = rinfo.RegionSizeX; + rdata.sizeY = rinfo.RegionSizeY; rdata.RegionID = rinfo.RegionID; rdata.RegionName = rinfo.RegionName; rdata.Data = rinfo.ToKeyValuePairs(); @@ -453,6 +657,8 @@ namespace OpenSim.Services.GridService GridRegion rinfo = new GridRegion(rdata.Data); rinfo.RegionLocX = rdata.posX; rinfo.RegionLocY = rdata.posY; + rinfo.RegionSizeX = rdata.sizeX; + rinfo.RegionSizeY = rdata.sizeY; rinfo.RegionID = rdata.RegionID; rinfo.RegionName = rdata.RegionName; rinfo.ScopeID = rdata.ScopeID; @@ -478,6 +684,33 @@ namespace OpenSim.Services.GridService return ret; } + public List GetDefaultHypergridRegions(UUID scopeID) + { + List ret = new List(); + + List regions = m_Database.GetDefaultHypergridRegions(scopeID); + + foreach (RegionData r in regions) + { + if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0) + ret.Add(RegionData2RegionInfo(r)); + } + + int hgDefaultRegionsFoundOnline = regions.Count; + + // For now, hypergrid default regions will always be given precedence but we will also return simple default + // regions in case no specific hypergrid regions are specified. + ret.AddRange(GetDefaultRegions(scopeID)); + + int normalDefaultRegionsFoundOnline = ret.Count - hgDefaultRegionsFoundOnline; + + m_log.DebugFormat( + "[GRID SERVICE]: GetDefaultHypergridRegions returning {0} hypergrid default and {1} normal default regions", + hgDefaultRegionsFoundOnline, normalDefaultRegionsFoundOnline); + + return ret; + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { List ret = new List(); @@ -526,40 +759,41 @@ namespace OpenSim.Services.GridService private void HandleDeregisterRegion(string module, string[] cmd) { - if (cmd.Length != 4) + if (cmd.Length < 4) { - MainConsole.Instance.Output("Syntax: degregister region id "); + MainConsole.Instance.Output("Usage: degregister region id +"); return; } - string rawRegionUuid = cmd[3]; - UUID regionUuid; - - if (!UUID.TryParse(rawRegionUuid, out regionUuid)) + for (int i = 3; i < cmd.Length; i++) { - MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid); - return; - } + string rawRegionUuid = cmd[i]; + UUID regionUuid; - GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid); + if (!UUID.TryParse(rawRegionUuid, out regionUuid)) + { + MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid); + return; + } - if (region == null) - { - MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid); - return; - } + GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid); - if (DeregisterRegion(regionUuid)) - { - MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid); - } - else - { - // I don't think this can ever occur if we know that the region exists. - MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid); - } + if (region == null) + { + MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid); + return; + } - return; + if (DeregisterRegion(regionUuid)) + { + MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid); + } + else + { + // I don't think this can ever occur if we know that the region exists. + MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid); + } + } } private void HandleShowRegions(string module, string[] cmd) @@ -575,6 +809,27 @@ namespace OpenSim.Services.GridService OutputRegionsToConsoleSummary(regions); } + private void HandleShowGridSize(string module, string[] cmd) + { + List regions = m_Database.Get(int.MinValue, int.MinValue, int.MaxValue, int.MaxValue, UUID.Zero); + + double size = 0; + + foreach (RegionData region in regions) + { + int flags = Convert.ToInt32(region.Data["flags"]); + + if ((flags & (int)Framework.RegionFlags.Hyperlink) == 0) + size += region.sizeX * region.sizeY; + } + + MainConsole.Instance.Output("This is a very rough approximation."); + MainConsole.Instance.Output("Although it will not count regions that are actually links to others over the Hypergrid, "); + MainConsole.Instance.Output("it will count regions that are inactive but were not deregistered from the grid service"); + MainConsole.Instance.Output("(e.g. simulator crashed rather than shutting down cleanly).\n"); + + MainConsole.Instance.OutputFormat("Grid size: {0} km squared.", size / 1000000); + } private void HandleShowRegion(string module, string[] cmd) { @@ -586,7 +841,7 @@ namespace OpenSim.Services.GridService string regionName = cmd[3]; - List regions = m_Database.Get(regionName, UUID.Zero); + List regions = m_Database.Get(Util.EscapeForLike(regionName), UUID.Zero); if (regions == null || regions.Count < 1) { MainConsole.Instance.Output("No region with name {0} found", regionName); @@ -604,20 +859,20 @@ namespace OpenSim.Services.GridService return; } - int x, y; - if (!int.TryParse(cmd[3], out x)) + uint x, y; + if (!uint.TryParse(cmd[3], out x)) { MainConsole.Instance.Output("x-coord must be an integer"); return; } - if (!int.TryParse(cmd[4], out y)) + if (!uint.TryParse(cmd[4], out y)) { MainConsole.Instance.Output("y-coord must be an integer"); return; } - RegionData region = m_Database.Get(x * (int)Constants.RegionSize, y * (int)Constants.RegionSize, UUID.Zero); + RegionData region = m_Database.Get((int)Util.RegionToWorldLoc(x), (int)Util.RegionToWorldLoc(y), UUID.Zero); if (region == null) { MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y); @@ -634,7 +889,8 @@ namespace OpenSim.Services.GridService ConsoleDisplayList dispList = new ConsoleDisplayList(); dispList.AddRow("Region Name", r.RegionName); dispList.AddRow("Region ID", r.RegionID); - dispList.AddRow("Location", string.Format("{0},{1}", r.coordX, r.coordY)); + dispList.AddRow("Position", string.Format("{0},{1}", r.coordX, r.coordY)); + dispList.AddRow("Size", string.Format("{0}x{1}", r.sizeX, r.sizeY)); dispList.AddRow("URI", r.Data["serverURI"]); dispList.AddRow("Owner ID", r.Data["owner_uuid"]); dispList.AddRow("Flags", flags); @@ -651,10 +907,10 @@ namespace OpenSim.Services.GridService private void OutputRegionsToConsoleSummary(List regions) { ConsoleDisplayTable dispTable = new ConsoleDisplayTable(); - dispTable.AddColumn("Name", 16); + dispTable.AddColumn("Name", 44); dispTable.AddColumn("ID", 36); dispTable.AddColumn("Position", 11); - dispTable.AddColumn("Owner ID", 36); + dispTable.AddColumn("Size", 11); dispTable.AddColumn("Flags", 60); foreach (RegionData r in regions) @@ -664,7 +920,7 @@ namespace OpenSim.Services.GridService r.RegionName, r.RegionID.ToString(), string.Format("{0},{1}", r.coordX, r.coordY), - r.Data["owner_uuid"].ToString(), + string.Format("{0}x{1}", r.sizeX, r.sizeY), flags.ToString()); } @@ -716,7 +972,7 @@ namespace OpenSim.Services.GridService return; } - List regions = m_Database.Get(cmd[3], UUID.Zero); + List regions = m_Database.Get(Util.EscapeForLike(cmd[3]), UUID.Zero); if (regions == null || regions.Count < 1) { MainConsole.Instance.Output("Region not found"); @@ -734,5 +990,18 @@ namespace OpenSim.Services.GridService m_Database.Store(r); } } + + /// + /// Gets the grid extra service URls we wish for the region to send in OpenSimExtras to dynamically refresh + /// parameters in the viewer used to access services like map, search and destination guides. + /// see "SimulatorFeaturesModule" + /// + /// + /// The grid extra service URls. + /// + public Dictionary GetExtraFeatures() + { + return m_ExtraFeatures; + } } } diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index 7abed20..9d016fc 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -47,7 +47,7 @@ using OpenMetaverse; namespace OpenSim.Services.GridService { - public class HypergridLinker + public class HypergridLinker : IHypergridLinker { private static readonly ILog m_log = LogManager.GetLogger( @@ -63,14 +63,11 @@ namespace OpenSim.Services.GridService protected GatekeeperServiceConnector m_GatekeeperConnector; protected UUID m_ScopeID = UUID.Zero; +// protected bool m_Check4096 = true; protected string m_MapTileDirectory = string.Empty; protected string m_ThisGatekeeper = string.Empty; protected Uri m_ThisGatekeeperURI = null; - // Hyperlink regions are hyperlinks on the map - public readonly Dictionary m_HyperlinkRegions = new Dictionary(); - protected Dictionary m_HyperlinkHandles = new Dictionary(); - protected GridRegion m_DefaultRegion; protected GridRegion DefaultRegion { @@ -78,7 +75,7 @@ namespace OpenSim.Services.GridService { if (m_DefaultRegion == null) { - List defs = m_GridService.GetDefaultRegions(m_ScopeID); + List defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID); if (defs != null && defs.Count > 0) m_DefaultRegion = defs[0]; else @@ -123,9 +120,14 @@ namespace OpenSim.Services.GridService if (scope != string.Empty) UUID.TryParse(scope, out m_ScopeID); +// m_Check4096 = gridConfig.GetBoolean("Check4096", true); + m_MapTileDirectory = gridConfig.GetString("MapTileDirectory", "maptiles"); - m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", string.Empty); + m_ThisGatekeeper = Util.GetConfigVarFromSections(config, "GatekeeperURI", + new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty); + // Legacy. Remove soon! + m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", m_ThisGatekeeper); try { m_ThisGatekeeperURI = new Uri(m_ThisGatekeeper); @@ -154,18 +156,18 @@ namespace OpenSim.Services.GridService if (MainConsole.Instance != null) { - MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region", + MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-region", "link-region []", "Link a HyperGrid Region. Examples for : http://grid.net:8002/ or http://example.org/path/foo.php", RunCommand); - MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region", + MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-region", "link-region []", "Link a hypergrid region (deprecated)", RunCommand); - MainConsole.Instance.Commands.AddCommand("hypergrid", false, "unlink-region", + MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "unlink-region", "unlink-region ", "Unlink a hypergrid region", RunCommand); - MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-mapping", "link-mapping [ ]", + MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-mapping", "link-mapping [ ]", "Set local coordinate to map HG regions to", RunCommand); - MainConsole.Instance.Commands.AddCommand("hypergrid", false, "show hyperlinks", "show hyperlinks", + MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "show hyperlinks", "show hyperlinks", "List the HG regions", HandleShow); } } @@ -177,14 +179,14 @@ namespace OpenSim.Services.GridService public GridRegion LinkRegion(UUID scopeID, string regionDescriptor) { string reason = string.Empty; - int xloc = random.Next(0, Int16.MaxValue) * (int)Constants.RegionSize; - return TryLinkRegionToCoords(scopeID, regionDescriptor, xloc, 0, out reason); + uint xloc = Util.RegionToWorldLoc((uint)random.Next(0, Int16.MaxValue)); + return TryLinkRegionToCoords(scopeID, regionDescriptor, (int)xloc, 0, out reason); } private static Random random = new Random(); // From the command line link-region (obsolete) and the map - public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason) + private GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason) { return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason); } @@ -194,24 +196,36 @@ namespace OpenSim.Services.GridService reason = string.Empty; GridRegion regInfo = null; + mapName = mapName.Trim(); + if (!mapName.StartsWith("http")) { - string host = "127.0.0.1"; - string portstr; + // Formats: grid.example.com:8002:region name + // grid.example.com:region name + // grid.example.com:8002 + // grid.example.com + + string host; + uint port = 80; string regionName = ""; - uint port = 0; + string[] parts = mapName.Split(new char[] { ':' }); - if (parts.Length >= 1) + + if (parts.Length == 0) { - host = parts[0]; + reason = "Wrong format for link-region"; + return null; } + + host = parts[0]; + if (parts.Length >= 2) { - portstr = parts[1]; - //m_log.Debug("-- port = " + portstr); - if (!UInt32.TryParse(portstr, out port)) + // 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]; } + // always take the last one if (parts.Length >= 3) { @@ -228,14 +242,30 @@ namespace OpenSim.Services.GridService } else { - string[] parts = mapName.Split(new char[] {' '}); - string regionName = String.Empty; - if (parts.Length > 1) + // Formats: http://grid.example.com region name + // http://grid.example.com "region name" + // http://grid.example.com + + string serverURI; + string regionName = ""; + + string[] parts = mapName.Split(new char[] { ' ' }); + + if (parts.Length == 0) { - regionName = mapName.Substring(parts[0].Length + 1); - regionName = regionName.Trim(new char[] {'"'}); + reason = "Wrong format for link-region"; + return null; } - if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, parts[0], ownerID, out regInfo, out reason)) + + serverURI = parts[0]; + + if (parts.Length >= 2) + { + regionName = mapName.Substring(serverURI.Length); + regionName = regionName.Trim(new char[] { '"', ' ' }); + } + + if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason)) { regInfo.RegionName = mapName; return regInfo; @@ -244,31 +274,39 @@ namespace OpenSim.Services.GridService return null; } - - public bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason) + + private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason) { return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason); } - - 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) + + private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason) { - m_log.DebugFormat("[HYPERGRID LINKER]: Link to {0} {1}, in {2}-{3}", + lock (this) + { + return TryCreateLinkImpl(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, serverURI, ownerID, out regInfo, out reason); + } + } + + private bool TryCreateLinkImpl(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason) + { + m_log.InfoFormat("[HYPERGRID LINKER]: Link to {0} {1}, in <{2},{3}>", ((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI), - remoteRegionName, xloc / Constants.RegionSize, yloc / Constants.RegionSize); + remoteRegionName, Util.WorldToRegionLoc((uint)xloc), Util.WorldToRegionLoc((uint)yloc)); reason = string.Empty; Uri uri = null; regInfo = new GridRegion(); - if ( externalPort > 0) + if (externalPort > 0) regInfo.HttpPort = externalPort; else - regInfo.HttpPort = 0; - if ( externalHostName != null) + regInfo.HttpPort = 80; + if (externalHostName != null) regInfo.ExternalHostName = externalHostName; else regInfo.ExternalHostName = "0.0.0.0"; - if ( serverURI != null) + if (serverURI != null) { regInfo.ServerURI = serverURI; try @@ -280,7 +318,7 @@ namespace OpenSim.Services.GridService catch {} } - if ( remoteRegionName != string.Empty ) + if (remoteRegionName != string.Empty) regInfo.RegionName = remoteRegionName; regInfo.RegionLocX = xloc; @@ -293,6 +331,7 @@ namespace OpenSim.Services.GridService { if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port) { + m_log.InfoFormat("[HYPERGRID LINKER]: Cannot hyperlink to regions on the same grid"); reason = "Cannot hyperlink to regions on the same grid"; return false; } @@ -304,8 +343,8 @@ namespace OpenSim.Services.GridService GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY); if (region != null) { - m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates {0}-{1} are already occupied by region {2} with uuid {3}", - regInfo.RegionLocX / Constants.RegionSize, regInfo.RegionLocY / Constants.RegionSize, + m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates <{0},{1}> are already occupied by region {2} with uuid {3}", + Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY), region.RegionName, region.RegionID); reason = "Coordinates are already in use"; return false; @@ -340,12 +379,25 @@ namespace OpenSim.Services.GridService region = m_GridService.GetRegionByUUID(scopeID, regionID); if (region != null) { - m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates {0} {1}", - region.RegionLocX / Constants.RegionSize, region.RegionLocY / Constants.RegionSize); + 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; } + // We are now performing this check for each individual teleport in the EntityTransferModule instead. This + // allows us to give better feedback when teleports fail because of the distance reason (which can't be + // done here) and it also hypergrid teleports that are within range (possibly because the source grid + // itself has regions that are very far apart). +// uint x, y; +// if (m_Check4096 && !Check4096(handle, out x, out y)) +// { +// //RemoveHyperlinkRegion(regInfo.RegionID); +// reason = "Region is too far (" + x + ", " + y + ")"; +// m_log.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")"); +// //return false; +// } + regInfo.RegionID = regionID; if (externalName == string.Empty) @@ -362,7 +414,8 @@ namespace OpenSim.Services.GridService regInfo.RegionSecret = handle.ToString(); AddHyperlinkRegion(regInfo, handle); - m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} with image {1}", regInfo.RegionName, regInfo.TerrainImage); + 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; } @@ -371,7 +424,7 @@ namespace OpenSim.Services.GridService m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName); GridRegion regInfo = null; - List regions = m_Database.Get(mapName, m_ScopeID); + List regions = m_Database.Get(Util.EscapeForLike(mapName), m_ScopeID); if (regions != null && regions.Count > 0) { OpenSim.Framework.RegionFlags rflags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]); @@ -395,6 +448,52 @@ namespace OpenSim.Services.GridService } } +// Not currently used +// /// +// /// Cope with this viewer limitation. +// /// +// /// +// /// +// public bool Check4096(ulong realHandle, out uint x, out uint y) +// { +// uint ux = 0, uy = 0; +// Utils.LongToUInts(realHandle, out ux, out uy); +// x = Util.WorldToRegionLoc(ux); +// y = Util.WorldToRegionLoc(uy); +// +// const uint limit = Util.RegionToWorldLoc(4096 - 1); +// uint xmin = ux - limit; +// uint xmax = ux + limit; +// uint ymin = uy - limit; +// uint ymax = uy + limit; +// // World map boundary checks +// if (xmin < 0 || xmin > ux) +// xmin = 0; +// if (xmax > int.MaxValue || xmax < ux) +// xmax = int.MaxValue; +// if (ymin < 0 || ymin > uy) +// ymin = 0; +// if (ymax > int.MaxValue || ymax < uy) +// ymax = int.MaxValue; +// +// // Check for any regions that are within the possible teleport range to the linked region +// List regions = m_GridService.GetRegionRange(m_ScopeID, (int)xmin, (int)xmax, (int)ymin, (int)ymax); +// if (regions.Count == 0) +// { +// return false; +// } +// else +// { +// // Check for regions which are not linked regions +// List hyperlinks = m_GridService.GetHyperlinks(m_ScopeID); +// IEnumerable availableRegions = regions.Except(hyperlinks); +// if (availableRegions.Count() == 0) +// return false; +// } +// +// return true; +// } + private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle) { RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo); @@ -437,9 +536,14 @@ namespace OpenSim.Services.GridService MainConsole.Instance.Output(new string('-', 72)); foreach (RegionData r in regions) { - MainConsole.Instance.Output(String.Format("{0}\n{2,-32} {1}\n", - r.RegionName, r.RegionID, String.Format("{0},{1} ({2},{3})", r.posX, r.posY, - r.posX / Constants.RegionSize, r.posY / Constants.RegionSize))); + MainConsole.Instance.Output( + String.Format("{0}\n{2,-32} {1}\n", + r.RegionName, r.RegionID, + String.Format("{0},{1} ({2},{3})", r.posX, r.posY, + Util.WorldToRegionLoc((uint)r.posX), Util.WorldToRegionLoc((uint)r.posY) + ) + ) + ); } return; } @@ -464,8 +568,8 @@ namespace OpenSim.Services.GridService int xloc, yloc; string serverURI; string remoteName = null; - xloc = Convert.ToInt32(cmdparams[0]) * (int)Constants.RegionSize; - yloc = Convert.ToInt32(cmdparams[1]) * (int)Constants.RegionSize; + xloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[0])); + yloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[1])); serverURI = cmdparams[2]; if (cmdparams.Length > 3) remoteName = string.Join(" ", cmdparams, 3, cmdparams.Length - 3); @@ -536,13 +640,13 @@ namespace OpenSim.Services.GridService { // old format GridRegion regInfo; - int xloc, yloc; + uint xloc, yloc; uint externalPort; string externalHostName; try { - xloc = Convert.ToInt32(cmdparams[0]); - yloc = Convert.ToInt32(cmdparams[1]); + xloc = Convert.ToUInt32(cmdparams[0]); + yloc = Convert.ToUInt32(cmdparams[1]); externalPort = Convert.ToUInt32(cmdparams[3]); externalHostName = cmdparams[2]; //internalPort = Convert.ToUInt32(cmdparams[4]); @@ -556,10 +660,11 @@ namespace OpenSim.Services.GridService } // Convert cell coordinates given by the user to meters - xloc = xloc * (int)Constants.RegionSize; - yloc = yloc * (int)Constants.RegionSize; + xloc = Util.RegionToWorldLoc(xloc); + yloc = Util.RegionToWorldLoc(yloc); string reason = string.Empty; - if (TryCreateLink(UUID.Zero, xloc, yloc, string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason)) + if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc, + string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason)) { // What is this? The GridRegion instance will be discarded anyway, // which effectively ignores any local name given with the command. @@ -639,13 +744,13 @@ namespace OpenSim.Services.GridService private void ReadLinkFromConfig(IConfig config) { GridRegion regInfo; - int xloc, yloc; + uint xloc, yloc; uint externalPort; string externalHostName; uint realXLoc, realYLoc; - xloc = Convert.ToInt32(config.GetString("xloc", "0")); - yloc = Convert.ToInt32(config.GetString("yloc", "0")); + xloc = Convert.ToUInt32(config.GetString("xloc", "0")); + yloc = Convert.ToUInt32(config.GetString("yloc", "0")); externalPort = Convert.ToUInt32(config.GetString("externalPort", "0")); externalHostName = config.GetString("externalHostName", ""); realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0")); @@ -653,18 +758,19 @@ namespace OpenSim.Services.GridService if (m_enableAutoMapping) { - xloc = (int)((xloc % 100) + m_autoMappingX); - yloc = (int)((yloc % 100) + m_autoMappingY); + xloc = (xloc % 100) + m_autoMappingX; + yloc = (yloc % 100) + m_autoMappingY; } if (((realXLoc == 0) && (realYLoc == 0)) || (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) && ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896)))) { - xloc = xloc * (int)Constants.RegionSize; - yloc = yloc * (int)Constants.RegionSize; + xloc = Util.RegionToWorldLoc(xloc); + yloc = Util.RegionToWorldLoc(yloc); string reason = string.Empty; - if (TryCreateLink(UUID.Zero, xloc, yloc, string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason)) + if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc, + string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason)) { regInfo.RegionName = config.GetString("localName", ""); } diff --git a/OpenSim/Services/GridService/Properties/AssemblyInfo.cs b/OpenSim/Services/GridService/Properties/AssemblyInfo.cs index 5c0c8f4..0841e5a 100644 --- a/OpenSim/Services/GridService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/GridService/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("0.8.3.*")] + -- cgit v1.1