diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs index a2eb5ee18e..3468ceac85 100644 --- a/OpenSim/Framework/Constants.cs +++ b/OpenSim/Framework/Constants.cs @@ -30,8 +30,14 @@ namespace OpenSim.Framework { public class Constants { + // 'RegionSize' is the legacy region size. + // DO NOT USE THIS FOR ANY NEW CODE. Use Scene.RegionInfo.RegionSize[XYZ] as a region might not + // be the legacy region size. public const uint RegionSize = 256; public const uint RegionHeight = 4096; + // This could be a parameters but, really, a region of greater than this is pretty unmanageable + public const uint MaximumRegionSize = 8192; + public const byte TerrainPatchSize = 16; public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f"; diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 24b9c89344..857c151506 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -99,6 +99,7 @@ namespace OpenSim.Framework public class RegionInfo { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string LogHeader = "[REGION INFO]"; public bool commFailTF = false; public ConfigurationMember configMember; @@ -137,16 +138,20 @@ namespace OpenSim.Framework public bool m_allow_alternate_ports; protected string m_externalHostName; protected IPEndPoint m_internalEndPoint; - protected uint? m_regionLocX; - protected uint? m_regionLocY; protected uint m_remotingPort; public UUID RegionID = UUID.Zero; public string RemotingAddress; public UUID ScopeID = UUID.Zero; private UUID m_maptileStaticUUID = UUID.Zero; - private Dictionary m_otherSettings = new Dictionary(); + public uint WorldLocX = 0; + public uint WorldLocY = 0; + public uint WorldLocZ = 0; + public uint RegionSizeX = Constants.RegionSize; + public uint RegionSizeY = Constants.RegionSize; + public uint RegionSizeZ = Constants.RegionHeight; + private Dictionary m_otherSettings = new Dictionary(); // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. @@ -229,11 +234,10 @@ namespace OpenSim.Framework m_serverURI = string.Empty; } - public RegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) + public RegionInfo(uint legacyRegionLocX, uint legacyRegionLocY, IPEndPoint internalEndPoint, string externalUri) { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - + RegionLocX = legacyRegionLocX; + RegionLocY = legacyRegionLocY; m_internalEndPoint = internalEndPoint; m_externalHostName = externalUri; m_serverURI = string.Empty; @@ -447,25 +451,42 @@ namespace OpenSim.Framework /// /// The x co-ordinate of this region in map tiles (e.g. 1000). + /// Coordinate is scaled as world coordinates divided by the legacy region size + /// and is thus is the number of legacy regions. /// public uint RegionLocX { - get { return m_regionLocX.Value; } - set { m_regionLocX = value; } + get { return WorldLocX / Constants.RegionSize; } + set { WorldLocX = value * Constants.RegionSize; } } /// /// The y co-ordinate of this region in map tiles (e.g. 1000). + /// Coordinate is scaled as world coordinates divided by the legacy region size + /// and is thus is the number of legacy regions. /// public uint RegionLocY { - get { return m_regionLocY.Value; } - set { m_regionLocY = value; } + get { return WorldLocY / Constants.RegionSize; } + set { WorldLocY = value * Constants.RegionSize; } } + public void SetDefaultRegionSize() + { + WorldLocX = 0; + WorldLocY = 0; + WorldLocZ = 0; + RegionSizeX = Constants.RegionSize; + RegionSizeY = Constants.RegionSize; + RegionSizeZ = Constants.RegionHeight; + } + + // A unique region handle is created from the region's world coordinates. + // This cannot be changed because some code expects to receive the region handle and then + // compute the region coordinates from it. public ulong RegionHandle { - get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); } + get { return Util.UIntsToLong(WorldLocX, WorldLocY); } } public void SetEndPoint(string ipaddr, int port) @@ -572,8 +593,25 @@ namespace OpenSim.Framework string[] locationElements = location.Split(new char[] {','}); - m_regionLocX = Convert.ToUInt32(locationElements[0]); - m_regionLocY = Convert.ToUInt32(locationElements[1]); + RegionLocX = Convert.ToUInt32(locationElements[0]); + RegionLocY = Convert.ToUInt32(locationElements[1]); + + // Region size + // Default to legacy region size if not specified. + allKeys.Remove("SizeX"); + string configSizeX = config.GetString("SizeX", Constants.RegionSize.ToString()); + config.Set("SizeX", configSizeX); + RegionSizeX = Convert.ToUInt32(configSizeX); + allKeys.Remove("SizeY"); + string configSizeY = config.GetString("SizeY", Constants.RegionSize.ToString()); + config.Set("SizeY", configSizeX); + RegionSizeY = Convert.ToUInt32(configSizeY); + allKeys.Remove("SizeZ"); + string configSizeZ = config.GetString("SizeZ", Constants.RegionHeight.ToString()); + config.Set("SizeZ", configSizeX); + RegionSizeZ = Convert.ToUInt32(configSizeZ); + + DoRegionSizeSanityChecks(); // InternalAddress // @@ -693,6 +731,57 @@ namespace OpenSim.Framework } } + // Make sure user specified region sizes are sane. + // Must be multiples of legacy region size (256). + private void DoRegionSizeSanityChecks() + { + if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize) + { + // Doing non-legacy region sizes. + // Enforce region size to be multiples of the legacy region size (256) + uint partial = RegionSizeX % Constants.RegionSize; + if (partial != 0) + { + RegionSizeX -= partial; + if (RegionSizeX == 0) + RegionSizeX = Constants.RegionSize; + m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeX={3} instead of specified {4}", + LogHeader, Constants.RegionSize, m_regionName, RegionSizeX, RegionSizeX + partial); + } + partial = RegionSizeY % Constants.RegionSize; + if (partial != 0) + { + RegionSizeY -= partial; + if (RegionSizeY == 0) + RegionSizeY = Constants.RegionSize; + m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeY={3} instead of specified {4}", + LogHeader, Constants.RegionSize, m_regionName, RegionSizeY, RegionSizeY + partial); + } + + // Because of things in the viewer, regions MUST be square. + // Remove this check when viewers have been updated. + if (RegionSizeX != RegionSizeY) + { + uint minSize = Math.Min(RegionSizeX, RegionSizeY); + RegionSizeX = minSize; + RegionSizeY = minSize; + m_log.ErrorFormat("{0} Regions must be square until viewers are updated. Forcing region {1} size to <{2},{3}>", + LogHeader, m_regionName, RegionSizeX, RegionSizeY); + } + + // There is a practical limit to region size. + if (RegionSizeX > Constants.MaximumRegionSize || RegionSizeY > Constants.MaximumRegionSize) + { + RegionSizeX = Util.Clamp(RegionSizeX, Constants.RegionSize, Constants.MaximumRegionSize); + RegionSizeY = Util.Clamp(RegionSizeY, Constants.RegionSize, Constants.MaximumRegionSize); + m_log.ErrorFormat("{0} Region dimensions must be less than {1}. Clamping {2}'s size to <{3},{4}>", + LogHeader, Constants.MaximumRegionSize, m_regionName, RegionSizeX, RegionSizeY); + } + + m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY); + } + } + private void WriteNiniConfig(IConfigSource source) { IConfig config = source.Configs[RegionName]; @@ -704,9 +793,16 @@ namespace OpenSim.Framework config.Set("RegionUUID", RegionID.ToString()); - string location = String.Format("{0},{1}", m_regionLocX, m_regionLocY); + string location = String.Format("{0},{1}", RegionLocX, RegionLocY); config.Set("Location", location); + if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize) + { + config.Set("SizeX", RegionSizeX); + config.Set("SizeY", RegionSizeY); + config.Set("SizeZ", RegionSizeZ); + } + config.Set("InternalAddress", m_internalEndPoint.Address.ToString()); config.Set("InternalPort", m_internalEndPoint.Port); @@ -789,10 +885,18 @@ namespace OpenSim.Framework RegionID.ToString(), true); configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Region Name", RegionName, true); + configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Grid Location (X Axis)", m_regionLocX.ToString(), true); + "Grid Location (X Axis)", RegionLocX.ToString(), true); configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Grid Location (Y Axis)", m_regionLocY.ToString(), true); + "Grid Location (Y Axis)", RegionLocY.ToString(), true); + configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in X dimension", RegionSizeX.ToString(), true); + configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in Y dimension", RegionSizeY.ToString(), true); + configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in Z dimension", RegionSizeZ.ToString(), true); + //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); configMember.addConfigurationOption("internal_ip_address", ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, @@ -855,10 +959,18 @@ namespace OpenSim.Framework UUID.Random().ToString(), true); configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Region Name", "OpenSim Test", false); + configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "Grid Location (X Axis)", "1000", false); configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "Grid Location (Y Axis)", "1000", false); + configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in X dimension", Constants.RegionSize.ToString(), false); + configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in Y dimension", Constants.RegionSize.ToString(), false); + configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Size of region in Z dimension", Constants.RegionHeight.ToString(), false); + //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); configMember.addConfigurationOption("internal_ip_address", ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, @@ -916,10 +1028,19 @@ namespace OpenSim.Framework RegionName = (string) configuration_result; break; case "sim_location_x": - m_regionLocX = (uint) configuration_result; + RegionLocX = (uint) configuration_result; break; case "sim_location_y": - m_regionLocY = (uint) configuration_result; + RegionLocY = (uint) configuration_result; + break; + case "sim_size_x": + RegionSizeX = (uint) configuration_result; + break; + case "sim_size_y": + RegionSizeY = (uint) configuration_result; + break; + case "sim_size_z": + RegionSizeZ = (uint) configuration_result; break; case "internal_ip_address": IPAddress address = (IPAddress) configuration_result; @@ -1000,8 +1121,13 @@ namespace OpenSim.Framework args["external_host_name"] = OSD.FromString(ExternalHostName); args["http_port"] = OSD.FromString(HttpPort.ToString()); args["server_uri"] = OSD.FromString(ServerURI); + args["region_xloc"] = OSD.FromString(RegionLocX.ToString()); args["region_yloc"] = OSD.FromString(RegionLocY.ToString()); + args["region_size_x"] = OSD.FromString(RegionSizeX.ToString()); + args["region_size_y"] = OSD.FromString(RegionSizeY.ToString()); + args["region_size_z"] = OSD.FromString(RegionSizeZ.ToString()); + args["internal_ep_address"] = OSD.FromString(InternalEndPoint.Address.ToString()); args["internal_ep_port"] = OSD.FromString(InternalEndPoint.Port.ToString()); if ((RemotingAddress != null) && !RemotingAddress.Equals("")) @@ -1040,6 +1166,13 @@ namespace OpenSim.Framework UInt32.TryParse(args["region_yloc"].AsString(), out locy); RegionLocY = locy; } + if (args.ContainsKey("region_size_x")) + RegionSizeX = (uint)args["region_size_x"].AsInteger(); + if (args.ContainsKey("region_size_y")) + RegionSizeY = (uint)args["region_size_y"].AsInteger(); + if (args.ContainsKey("region_size_z")) + RegionSizeZ = (uint)args["region_size_z"].AsInteger(); + IPAddress ip_addr = null; if (args["internal_ep_address"] != null) { @@ -1076,23 +1209,5 @@ namespace OpenSim.Framework regionInfo.ServerURI = serverURI; return regionInfo; } - - public Dictionary ToKeyValuePairs() - { - Dictionary kvp = new Dictionary(); - kvp["uuid"] = RegionID.ToString(); - kvp["locX"] = RegionLocX.ToString(); - kvp["locY"] = RegionLocY.ToString(); - kvp["external_ip_address"] = ExternalEndPoint.Address.ToString(); - kvp["external_port"] = ExternalEndPoint.Port.ToString(); - kvp["external_host_name"] = ExternalHostName; - kvp["http_port"] = HttpPort.ToString(); - kvp["internal_ip_address"] = InternalEndPoint.Address.ToString(); - kvp["internal_port"] = InternalEndPoint.Port.ToString(); - kvp["alternate_ports"] = m_allow_alternate_ports.ToString(); - kvp["server_uri"] = ServerURI; - - return kvp; - } } } diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index e72b7f98e9..137ce04ead 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -313,8 +313,9 @@ 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); + 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) { @@ -347,6 +348,11 @@ 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; @@ -441,6 +447,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(); @@ -454,6 +462,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; diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index 88ac5b3653..651bd976a5 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -177,6 +177,7 @@ namespace OpenSim.Services.Interfaces /// /// The location of this region in meters. + /// DANGER DANGER! Note that this name means something different in RegionInfo. /// public int RegionLocX { @@ -185,8 +186,12 @@ namespace OpenSim.Services.Interfaces } protected int m_regionLocX; + public int RegionSizeX { get; set; } + public int RegionSizeY { get; set; } + /// /// The location of this region in meters. + /// DANGER DANGER! Note that this name means something different in RegionInfo. /// public int RegionLocY { @@ -218,10 +223,13 @@ namespace OpenSim.Services.Interfaces m_serverURI = string.Empty; } + /* public GridRegion(int regionLocX, int regionLocY, IPEndPoint internalEndPoint, string externalUri) { m_regionLocX = regionLocX; m_regionLocY = regionLocY; + RegionSizeX = (int)Constants.RegionSize; + RegionSizeY = (int)Constants.RegionSize; m_internalEndPoint = internalEndPoint; m_externalHostName = externalUri; @@ -231,16 +239,21 @@ namespace OpenSim.Services.Interfaces { m_regionLocX = regionLocX; m_regionLocY = regionLocY; + RegionSizeX = (int)Constants.RegionSize; + RegionSizeY = (int)Constants.RegionSize; m_externalHostName = externalUri; m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)port); } + */ public GridRegion(uint xcell, uint ycell) { m_regionLocX = (int)(xcell * Constants.RegionSize); m_regionLocY = (int)(ycell * Constants.RegionSize); + RegionSizeX = (int)Constants.RegionSize; + RegionSizeY = (int)Constants.RegionSize; } public GridRegion(RegionInfo ConvertFrom) @@ -248,6 +261,8 @@ namespace OpenSim.Services.Interfaces m_regionName = ConvertFrom.RegionName; m_regionLocX = (int)(ConvertFrom.RegionLocX * Constants.RegionSize); m_regionLocY = (int)(ConvertFrom.RegionLocY * Constants.RegionSize); + RegionSizeX = (int)ConvertFrom.RegionSizeX; + RegionSizeY = (int)ConvertFrom.RegionSizeY; m_internalEndPoint = ConvertFrom.InternalEndPoint; m_externalHostName = ConvertFrom.ExternalHostName; m_httpPort = ConvertFrom.HttpPort; @@ -266,6 +281,8 @@ namespace OpenSim.Services.Interfaces m_regionName = ConvertFrom.RegionName; m_regionLocX = ConvertFrom.RegionLocX; m_regionLocY = ConvertFrom.RegionLocY; + RegionSizeX = ConvertFrom.RegionSizeX; + RegionSizeY = ConvertFrom.RegionSizeY; m_internalEndPoint = ConvertFrom.InternalEndPoint; m_externalHostName = ConvertFrom.ExternalHostName; m_httpPort = ConvertFrom.HttpPort; @@ -373,6 +390,8 @@ namespace OpenSim.Services.Interfaces kvp["uuid"] = RegionID.ToString(); kvp["locX"] = RegionLocX.ToString(); kvp["locY"] = RegionLocY.ToString(); + kvp["sizeX"] = RegionSizeX.ToString(); + kvp["sizeY"] = RegionSizeY.ToString(); kvp["regionName"] = RegionName; kvp["serverIP"] = ExternalHostName; //ExternalEndPoint.Address.ToString(); kvp["serverHttpPort"] = HttpPort.ToString(); @@ -399,6 +418,12 @@ namespace OpenSim.Services.Interfaces if (kvp.ContainsKey("locY")) RegionLocY = Convert.ToInt32((string)kvp["locY"]); + if (kvp.ContainsKey("sizeX")) + RegionSizeX = Convert.ToInt32((string)kvp["sizeX"]); + + if (kvp.ContainsKey("sizeY")) + RegionSizeY = Convert.ToInt32((string)kvp["sizeY"]); + if (kvp.ContainsKey("regionName")) RegionName = (string)kvp["regionName"];