diff options
-rw-r--r-- | OpenSim/Data/IRegionData.cs | 4 | ||||
-rw-r--r-- | OpenSim/Services/GridService/GridService.cs | 129 | ||||
-rw-r--r-- | OpenSim/Services/Interfaces/IGridService.cs | 4 |
3 files changed, 127 insertions, 10 deletions
diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs index 50433ba..ca9b327 100644 --- a/OpenSim/Data/IRegionData.cs +++ b/OpenSim/Data/IRegionData.cs | |||
@@ -52,12 +52,12 @@ namespace OpenSim.Data | |||
52 | public int sizeY; | 52 | public int sizeY; |
53 | 53 | ||
54 | /// <summary> | 54 | /// <summary> |
55 | /// Return the x-coordinate of this region. | 55 | /// Return the x-coordinate of this region in region units. |
56 | /// </summary> | 56 | /// </summary> |
57 | public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } } | 57 | public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } } |
58 | 58 | ||
59 | /// <summary> | 59 | /// <summary> |
60 | /// Return the y-coordinate of this region. | 60 | /// Return the y-coordinate of this region in region units. |
61 | /// </summary> | 61 | /// </summary> |
62 | public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } } | 62 | public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } } |
63 | 63 | ||
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 2836236..013cc53 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs | |||
@@ -46,7 +46,7 @@ namespace OpenSim.Services.GridService | |||
46 | private static readonly ILog m_log = | 46 | private static readonly ILog m_log = |
47 | LogManager.GetLogger( | 47 | LogManager.GetLogger( |
48 | MethodBase.GetCurrentMethod().DeclaringType); | 48 | MethodBase.GetCurrentMethod().DeclaringType); |
49 | // private string LogHeader = "[GRID SERVICE]"; | 49 | private string LogHeader = "[GRID SERVICE]"; |
50 | 50 | ||
51 | private bool m_DeleteOnUnregister = true; | 51 | private bool m_DeleteOnUnregister = true; |
52 | private static GridService m_RootInstance = null; | 52 | private static GridService m_RootInstance = null; |
@@ -57,6 +57,8 @@ namespace OpenSim.Services.GridService | |||
57 | protected bool m_AllowDuplicateNames = false; | 57 | protected bool m_AllowDuplicateNames = false; |
58 | protected bool m_AllowHypergridMapSearch = false; | 58 | protected bool m_AllowHypergridMapSearch = false; |
59 | 59 | ||
60 | protected bool m_SuppressVarregionOverlapCheckOnRegistration = false; | ||
61 | |||
60 | public GridService(IConfigSource config) | 62 | public GridService(IConfigSource config) |
61 | : base(config) | 63 | : base(config) |
62 | { | 64 | { |
@@ -81,6 +83,8 @@ namespace OpenSim.Services.GridService | |||
81 | m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); | 83 | m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); |
82 | m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch); | 84 | m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch); |
83 | 85 | ||
86 | m_SuppressVarregionOverlapCheckOnRegistration = gridConfig.GetBoolean("SuppressVarregionOverlapCheckOnRegistration", m_SuppressVarregionOverlapCheckOnRegistration); | ||
87 | |||
84 | // This service is also used locally by a simulator running in grid mode. This switches prevents | 88 | // This service is also used locally by a simulator running in grid mode. This switches prevents |
85 | // inappropriate console commands from being registered | 89 | // inappropriate console commands from being registered |
86 | suppressConsoleCommands = gridConfig.GetBoolean("SuppressConsoleCommands", suppressConsoleCommands); | 90 | suppressConsoleCommands = gridConfig.GetBoolean("SuppressConsoleCommands", suppressConsoleCommands); |
@@ -148,12 +152,19 @@ namespace OpenSim.Services.GridService | |||
148 | if (regionInfos.RegionID == UUID.Zero) | 152 | if (regionInfos.RegionID == UUID.Zero) |
149 | return "Invalid RegionID - cannot be zero UUID"; | 153 | return "Invalid RegionID - cannot be zero UUID"; |
150 | 154 | ||
151 | RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); | 155 | String reason = "Region overlaps another region"; |
152 | if ((region != null) && (region.RegionID != regionInfos.RegionID)) | 156 | RegionData region = FindAnyConflictingRegion(regionInfos, scopeID, out reason); |
157 | // If there is a conflicting region, if it has the same ID and same coordinates | ||
158 | // then it is a region re-registering (permissions and ownership checked later). | ||
159 | if ((region != null) | ||
160 | && ( (region.coordX != regionInfos.RegionCoordX) | ||
161 | || (region.coordY != regionInfos.RegionCoordY) | ||
162 | || (region.RegionID != regionInfos.RegionID) ) | ||
163 | ) | ||
153 | { | 164 | { |
154 | m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.", | 165 | // If not same ID and same coordinates, this new region has conflicts and can't be registered. |
155 | regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); | 166 | m_log.WarnFormat("{0} Register region conflict in scope {1}. {2}", LogHeader, scopeID, reason); |
156 | return "Region overlaps another region"; | 167 | return reason; |
157 | } | 168 | } |
158 | 169 | ||
159 | if (region != null) | 170 | if (region != null) |
@@ -283,6 +294,112 @@ namespace OpenSim.Services.GridService | |||
283 | return String.Empty; | 294 | return String.Empty; |
284 | } | 295 | } |
285 | 296 | ||
297 | /// <summary> | ||
298 | /// Search the region map for regions conflicting with this region. | ||
299 | /// The region to be added is passed and we look for any existing regions that are | ||
300 | /// in the requested location, that are large varregions that overlap this region, or | ||
301 | /// are previously defined regions that would lie under this new region. | ||
302 | /// </summary> | ||
303 | /// <param name="regionInfos">Information on region requested to be added to the world map</param> | ||
304 | /// <param name="scopeID">Grid id for region</param> | ||
305 | /// <param name="reason">The reason the returned region conflicts with passed region</param> | ||
306 | /// <returns></returns> | ||
307 | private RegionData FindAnyConflictingRegion(GridRegion regionInfos, UUID scopeID, out string reason) | ||
308 | { | ||
309 | reason = "Reregistration"; | ||
310 | // First see if there is an existing region right where this region is trying to go | ||
311 | // (We keep this result so it can be returned if suppressing errors) | ||
312 | RegionData noErrorRegion = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); | ||
313 | RegionData region = noErrorRegion; | ||
314 | if (region != null | ||
315 | && region.RegionID == regionInfos.RegionID | ||
316 | && region.sizeX == regionInfos.RegionSizeX | ||
317 | && region.sizeY == regionInfos.RegionSizeY) | ||
318 | { | ||
319 | // If this seems to be exactly the same region, return this as it could be | ||
320 | // a re-registration (permissions checked by calling routine). | ||
321 | m_log.DebugFormat("{0} FindAnyConflictingRegion: re-register of {1}", | ||
322 | LogHeader, RegionString(regionInfos)); | ||
323 | return region; | ||
324 | } | ||
325 | |||
326 | // No region exactly there or we're resizing an existing region. | ||
327 | // Fetch regions that could be varregions overlapping requested location. | ||
328 | int xmin = regionInfos.RegionLocX - (int)Constants.MaximumRegionSize + 10; | ||
329 | int xmax = regionInfos.RegionLocX; | ||
330 | int ymin = regionInfos.RegionLocY - (int)Constants.MaximumRegionSize + 10; | ||
331 | int ymax = regionInfos.RegionLocY; | ||
332 | List<RegionData> rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID); | ||
333 | foreach (RegionData rdata in rdatas) | ||
334 | { | ||
335 | // m_log.DebugFormat("{0} FindAnyConflictingRegion: find existing. Checking {1}", LogHeader, RegionString(rdata) ); | ||
336 | if ( (rdata.posX + rdata.sizeX > regionInfos.RegionLocX) | ||
337 | && (rdata.posY + rdata.sizeY > regionInfos.RegionLocY) ) | ||
338 | { | ||
339 | region = rdata; | ||
340 | m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of {1} by existing varregion {2}", | ||
341 | LogHeader, RegionString(regionInfos), RegionString(region)); | ||
342 | reason = String.Format("Region location is overlapped by existing varregion {0}", | ||
343 | RegionString(region)); | ||
344 | |||
345 | if (m_SuppressVarregionOverlapCheckOnRegistration) | ||
346 | region = noErrorRegion; | ||
347 | return region; | ||
348 | } | ||
349 | } | ||
350 | |||
351 | // There isn't a region that overlaps this potential region. | ||
352 | // See if this potential region overlaps an existing region. | ||
353 | // First, a shortcut of not looking for overlap if new region is legacy region sized | ||
354 | // and connot overlap anything. | ||
355 | if (regionInfos.RegionSizeX != Constants.RegionSize | ||
356 | || regionInfos.RegionSizeY != Constants.RegionSize) | ||
357 | { | ||
358 | // trim range looked for so we don't pick up neighbor regions just off the edges | ||
359 | xmin = regionInfos.RegionLocX; | ||
360 | xmax = regionInfos.RegionLocX + regionInfos.RegionSizeX - 10; | ||
361 | ymin = regionInfos.RegionLocY; | ||
362 | ymax = regionInfos.RegionLocY + regionInfos.RegionSizeY - 10; | ||
363 | rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID); | ||
364 | |||
365 | // If the region is being resized, the found region could be ourself. | ||
366 | foreach (RegionData rdata in rdatas) | ||
367 | { | ||
368 | // m_log.DebugFormat("{0} FindAnyConflictingRegion: see if overlap. Checking {1}", LogHeader, RegionString(rdata) ); | ||
369 | if (region == null || region.RegionID != regionInfos.RegionID) | ||
370 | { | ||
371 | region = rdata; | ||
372 | m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of varregion {1} overlaps existing region {2}", | ||
373 | LogHeader, RegionString(regionInfos), RegionString(region)); | ||
374 | reason = String.Format("Region {0} would overlap existing region {1}", | ||
375 | RegionString(regionInfos), RegionString(region)); | ||
376 | |||
377 | if (m_SuppressVarregionOverlapCheckOnRegistration) | ||
378 | region = noErrorRegion; | ||
379 | return region; | ||
380 | } | ||
381 | } | ||
382 | } | ||
383 | |||
384 | // If we get here, region is either null (nothing found here) or | ||
385 | // is the non-conflicting region found at the location being requested. | ||
386 | return region; | ||
387 | } | ||
388 | |||
389 | // String describing name and region location of passed region | ||
390 | private String RegionString(RegionData reg) | ||
391 | { | ||
392 | return String.Format("{0}/{1} at <{2},{3}>", | ||
393 | reg.RegionName, reg.RegionID, reg.coordX, reg.coordY); | ||
394 | } | ||
395 | |||
396 | // String describing name and region location of passed region | ||
397 | private String RegionString(GridRegion reg) | ||
398 | { | ||
399 | return String.Format("{0}/{1} at <{2},{3}>", | ||
400 | reg.RegionName, reg.RegionID, reg.RegionCoordX, reg.RegionCoordY); | ||
401 | } | ||
402 | |||
286 | public bool DeregisterRegion(UUID regionID) | 403 | public bool DeregisterRegion(UUID regionID) |
287 | { | 404 | { |
288 | RegionData region = m_Database.Get(regionID, UUID.Zero); | 405 | RegionData region = m_Database.Get(regionID, UUID.Zero); |
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index dec3d35..b7bcd6b 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs | |||
@@ -186,12 +186,12 @@ namespace OpenSim.Services.Interfaces | |||
186 | protected IPEndPoint m_internalEndPoint; | 186 | protected IPEndPoint m_internalEndPoint; |
187 | 187 | ||
188 | /// <summary> | 188 | /// <summary> |
189 | /// The co-ordinate of this region. | 189 | /// The co-ordinate of this region in region units. |
190 | /// </summary> | 190 | /// </summary> |
191 | public int RegionCoordX { get { return (int)Util.WorldToRegionLoc((uint)RegionLocX); } } | 191 | public int RegionCoordX { get { return (int)Util.WorldToRegionLoc((uint)RegionLocX); } } |
192 | 192 | ||
193 | /// <summary> | 193 | /// <summary> |
194 | /// The co-ordinate of this region | 194 | /// The co-ordinate of this region in region units |
195 | /// </summary> | 195 | /// </summary> |
196 | public int RegionCoordY { get { return (int)Util.WorldToRegionLoc((uint)RegionLocY); } } | 196 | public int RegionCoordY { get { return (int)Util.WorldToRegionLoc((uint)RegionLocY); } } |
197 | 197 | ||