Add serialization/deserialization of region size to RegionInfo, GridRegion, and RegionData.

This does not modify interfaces or handling of variable sized regions. This only
enables the loading and storing of the region size and the reporting of the
region size in grid service responses.
The database tables already have the code to load and store the region size.
master-beforevarregion
Robert Adams 2013-12-28 06:58:15 -08:00
parent 540fa84842
commit 6869633d76
4 changed files with 195 additions and 39 deletions

View File

@ -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";

View File

@ -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<String, String> m_otherSettings = new Dictionary<string, string>();
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<String, String> m_otherSettings = new Dictionary<string, string>();
// 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
/// <summary>
/// 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.
/// </summary>
public uint RegionLocX
{
get { return m_regionLocX.Value; }
set { m_regionLocX = value; }
get { return WorldLocX / Constants.RegionSize; }
set { WorldLocX = value * Constants.RegionSize; }
}
/// <summary>
/// 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.
/// </summary>
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<uint>(RegionSizeX, Constants.RegionSize, Constants.MaximumRegionSize);
RegionSizeY = Util.Clamp<uint>(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<string, object> ToKeyValuePairs()
{
Dictionary<string, object> kvp = new Dictionary<string, object>();
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;
}
}
}

View File

@ -313,8 +313,9 @@ namespace OpenSim.Services.GridService
if (region != null)
{
// Not really? Maybe?
List<RegionData> 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<RegionData> 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;

View File

@ -177,6 +177,7 @@ namespace OpenSim.Services.Interfaces
/// <summary>
/// The location of this region in meters.
/// DANGER DANGER! Note that this name means something different in RegionInfo.
/// </summary>
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; }
/// <summary>
/// The location of this region in meters.
/// DANGER DANGER! Note that this name means something different in RegionInfo.
/// </summary>
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"];