Add code to GridService to check for overlapping of varregions
when registering a new region. Adds parameter "[GridService]SuppressVarRegionOverlapCheckOnRegistration=false" that can be turned on to suppress the error check if a simulator's database has old regions that overlap.bullet-2.82
parent
738c60459c
commit
aa8b44c001
|
@ -52,12 +52,12 @@ namespace OpenSim.Data
|
||||||
public int sizeY;
|
public int sizeY;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the x-coordinate of this region.
|
/// Return the x-coordinate of this region in region units.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
|
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the y-coordinate of this region.
|
/// Return the y-coordinate of this region in region units.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
|
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace OpenSim.Services.GridService
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(
|
LogManager.GetLogger(
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
// private string LogHeader = "[GRID SERVICE]";
|
private string LogHeader = "[GRID SERVICE]";
|
||||||
|
|
||||||
private bool m_DeleteOnUnregister = true;
|
private bool m_DeleteOnUnregister = true;
|
||||||
private static GridService m_RootInstance = null;
|
private static GridService m_RootInstance = null;
|
||||||
|
@ -57,6 +57,8 @@ namespace OpenSim.Services.GridService
|
||||||
protected bool m_AllowDuplicateNames = false;
|
protected bool m_AllowDuplicateNames = false;
|
||||||
protected bool m_AllowHypergridMapSearch = false;
|
protected bool m_AllowHypergridMapSearch = false;
|
||||||
|
|
||||||
|
protected bool m_SuppressVarregionOverlapCheckOnRegistration = false;
|
||||||
|
|
||||||
public GridService(IConfigSource config)
|
public GridService(IConfigSource config)
|
||||||
: base(config)
|
: base(config)
|
||||||
{
|
{
|
||||||
|
@ -81,6 +83,8 @@ namespace OpenSim.Services.GridService
|
||||||
m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames);
|
m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames);
|
||||||
m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch);
|
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
|
// This service is also used locally by a simulator running in grid mode. This switches prevents
|
||||||
// inappropriate console commands from being registered
|
// inappropriate console commands from being registered
|
||||||
suppressConsoleCommands = gridConfig.GetBoolean("SuppressConsoleCommands", suppressConsoleCommands);
|
suppressConsoleCommands = gridConfig.GetBoolean("SuppressConsoleCommands", suppressConsoleCommands);
|
||||||
|
@ -148,12 +152,19 @@ namespace OpenSim.Services.GridService
|
||||||
if (regionInfos.RegionID == UUID.Zero)
|
if (regionInfos.RegionID == UUID.Zero)
|
||||||
return "Invalid RegionID - cannot be zero UUID";
|
return "Invalid RegionID - cannot be zero UUID";
|
||||||
|
|
||||||
RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
|
String reason = "Region overlaps another region";
|
||||||
if ((region != null) && (region.RegionID != regionInfos.RegionID))
|
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}.",
|
// If not same ID and same coordinates, this new region has conflicts and can't be registered.
|
||||||
regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
|
m_log.WarnFormat("{0} Register region conflict in scope {1}. {2}", LogHeader, scopeID, reason);
|
||||||
return "Region overlaps another region";
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region != null)
|
if (region != null)
|
||||||
|
@ -283,6 +294,112 @@ namespace OpenSim.Services.GridService
|
||||||
return String.Empty;
|
return String.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="regionInfos">Information on region requested to be added to the world map</param>
|
||||||
|
/// <param name="scopeID">Grid id for region</param>
|
||||||
|
/// <param name="reason">The reason the returned region conflicts with passed region</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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<RegionData> 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)
|
public bool DeregisterRegion(UUID regionID)
|
||||||
{
|
{
|
||||||
RegionData region = m_Database.Get(regionID, UUID.Zero);
|
RegionData region = m_Database.Get(regionID, UUID.Zero);
|
||||||
|
|
|
@ -186,12 +186,12 @@ namespace OpenSim.Services.Interfaces
|
||||||
protected IPEndPoint m_internalEndPoint;
|
protected IPEndPoint m_internalEndPoint;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The co-ordinate of this region.
|
/// The co-ordinate of this region in region units.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int RegionCoordX { get { return (int)Util.WorldToRegionLoc((uint)RegionLocX); } }
|
public int RegionCoordX { get { return (int)Util.WorldToRegionLoc((uint)RegionLocX); } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The co-ordinate of this region
|
/// The co-ordinate of this region in region units
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int RegionCoordY { get { return (int)Util.WorldToRegionLoc((uint)RegionLocY); } }
|
public int RegionCoordY { get { return (int)Util.WorldToRegionLoc((uint)RegionLocY); } }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue