aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/GridService/GridService.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Services/GridService/GridService.cs415
1 files changed, 342 insertions, 73 deletions
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
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 50
50 private bool m_DeleteOnUnregister = true; 51 private bool m_DeleteOnUnregister = true;
51 private static GridService m_RootInstance = null; 52 private static GridService m_RootInstance = null;
@@ -56,6 +57,10 @@ namespace OpenSim.Services.GridService
56 protected bool m_AllowDuplicateNames = false; 57 protected bool m_AllowDuplicateNames = false;
57 protected bool m_AllowHypergridMapSearch = false; 58 protected bool m_AllowHypergridMapSearch = false;
58 59
60 protected bool m_SuppressVarregionOverlapCheckOnRegistration = false;
61
62 private static Dictionary<string,object> m_ExtraFeatures = new Dictionary<string, object>();
63
59 public GridService(IConfigSource config) 64 public GridService(IConfigSource config)
60 : base(config) 65 : base(config)
61 { 66 {
@@ -63,6 +68,9 @@ namespace OpenSim.Services.GridService
63 68
64 m_config = config; 69 m_config = config;
65 IConfig gridConfig = config.Configs["GridService"]; 70 IConfig gridConfig = config.Configs["GridService"];
71
72 bool suppressConsoleCommands = false;
73
66 if (gridConfig != null) 74 if (gridConfig != null)
67 { 75 {
68 m_DeleteOnUnregister = gridConfig.GetBoolean("DeleteOnUnregister", true); 76 m_DeleteOnUnregister = gridConfig.GetBoolean("DeleteOnUnregister", true);
@@ -76,32 +84,33 @@ namespace OpenSim.Services.GridService
76 } 84 }
77 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); 85 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames);
78 m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch); 86 m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch);
87
88 m_SuppressVarregionOverlapCheckOnRegistration = gridConfig.GetBoolean("SuppressVarregionOverlapCheckOnRegistration", m_SuppressVarregionOverlapCheckOnRegistration);
89
90 // This service is also used locally by a simulator running in grid mode. This switches prevents
91 // inappropriate console commands from being registered
92 suppressConsoleCommands = gridConfig.GetBoolean("SuppressConsoleCommands", suppressConsoleCommands);
79 } 93 }
80 94
81 if (m_RootInstance == null) 95 if (m_RootInstance == null)
82 { 96 {
83 m_RootInstance = this; 97 m_RootInstance = this;
84 98
85 if (MainConsole.Instance != null) 99 if (!suppressConsoleCommands && MainConsole.Instance != null)
86 { 100 {
87 MainConsole.Instance.Commands.AddCommand("Regions", true, 101 MainConsole.Instance.Commands.AddCommand("Regions", true,
88 "deregister region id", 102 "deregister region id",
89 "deregister region id <Region UUID>", 103 "deregister region id <region-id>+",
90 "Deregister a region manually.", 104 "Deregister a region manually.",
91 String.Empty, 105 String.Empty,
92 HandleDeregisterRegion); 106 HandleDeregisterRegion);
93 107
94 // A messy way of stopping this command being added if we are in standalone (since the simulator 108 MainConsole.Instance.Commands.AddCommand("Regions", true,
95 // has an identically named command 109 "show regions",
96 // 110 "show regions",
97 // XXX: We're relying on the OpenSimulator version being registered first, which is not well defined. 111 "Show details on all regions",
98 if (MainConsole.Instance.Commands.Resolve(new string[] { "show", "regions" }).Length == 0) 112 String.Empty,
99 MainConsole.Instance.Commands.AddCommand("Regions", true, 113 HandleShowRegions);
100 "show regions",
101 "show regions",
102 "Show details on all regions",
103 String.Empty,
104 HandleShowRegions);
105 114
106 MainConsole.Instance.Commands.AddCommand("Regions", true, 115 MainConsole.Instance.Commands.AddCommand("Regions", true,
107 "show region name", 116 "show region name",
@@ -117,17 +126,72 @@ namespace OpenSim.Services.GridService
117 "For example, show region at 1000 1000", 126 "For example, show region at 1000 1000",
118 HandleShowRegionAt); 127 HandleShowRegionAt);
119 128
120 MainConsole.Instance.Commands.AddCommand("Regions", true, 129 MainConsole.Instance.Commands.AddCommand("General", true,
121 "set region flags", 130 "show grid size",
122 "set region flags <Region name> <flags>", 131 "show grid size",
123 "Set database flags for region", 132 "Show the current grid size (excluding hyperlink references)",
124 String.Empty, 133 String.Empty,
125 HandleSetFlags); 134 HandleShowGridSize);
135
136 MainConsole.Instance.Commands.AddCommand("Regions", true,
137 "set region flags",
138 "set region flags <Region name> <flags>",
139 "Set database flags for region",
140 String.Empty,
141 HandleSetFlags);
126 } 142 }
143
144 if (!suppressConsoleCommands)
145 SetExtraServiceURLs(config);
146
127 m_HypergridLinker = new HypergridLinker(m_config, this, m_Database); 147 m_HypergridLinker = new HypergridLinker(m_config, this, m_Database);
128 } 148 }
129 } 149 }
130 150
151 private void SetExtraServiceURLs(IConfigSource config)
152 {
153 IConfig loginConfig = config.Configs["LoginService"];
154 IConfig gridConfig = config.Configs["GridService"];
155
156 if (loginConfig == null || gridConfig == null)
157 return;
158
159 string configVal;
160
161 configVal = loginConfig.GetString("SearchURL", string.Empty);
162 if (!string.IsNullOrEmpty(configVal))
163 m_ExtraFeatures["search-server-url"] = configVal;
164
165 configVal = loginConfig.GetString("MapTileURL", string.Empty);
166 if (!string.IsNullOrEmpty(configVal))
167 {
168 // This URL must end with '/', the viewer doesn't check
169 configVal = configVal.Trim();
170 if (!configVal.EndsWith("/"))
171 configVal = configVal + "/";
172 m_ExtraFeatures["map-server-url"] = configVal;
173 }
174
175 configVal = loginConfig.GetString("DestinationGuide", string.Empty);
176 if (!string.IsNullOrEmpty(configVal))
177 m_ExtraFeatures["destination-guide-url"] = configVal;
178
179 configVal = Util.GetConfigVarFromSections<string>(
180 config, "GatekeeperURI", new string[] { "Startup", "Hypergrid" }, String.Empty);
181 if (!string.IsNullOrEmpty(configVal))
182 m_ExtraFeatures["GridURL"] = configVal;
183
184 configVal = Util.GetConfigVarFromSections<string>(
185 config, "GridName", new string[] { "Const", "Hypergrid" }, String.Empty);
186 if (string.IsNullOrEmpty(configVal))
187 configVal = Util.GetConfigVarFromSections<string>(
188 config, "gridname", new string[] { "GridInfo" }, String.Empty);
189 if (!string.IsNullOrEmpty(configVal))
190 m_ExtraFeatures["GridName"] = configVal;
191
192 m_ExtraFeatures["ExportSupported"] = gridConfig.GetString("ExportSupported", "true");
193 }
194
131 #region IGridService 195 #region IGridService
132 196
133 public string RegisterRegion(UUID scopeID, GridRegion regionInfos) 197 public string RegisterRegion(UUID scopeID, GridRegion regionInfos)
@@ -137,12 +201,19 @@ namespace OpenSim.Services.GridService
137 if (regionInfos.RegionID == UUID.Zero) 201 if (regionInfos.RegionID == UUID.Zero)
138 return "Invalid RegionID - cannot be zero UUID"; 202 return "Invalid RegionID - cannot be zero UUID";
139 203
140 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 204 String reason = "Region overlaps another region";
141 if ((region != null) && (region.RegionID != regionInfos.RegionID)) 205 RegionData region = FindAnyConflictingRegion(regionInfos, scopeID, out reason);
206 // If there is a conflicting region, if it has the same ID and same coordinates
207 // then it is a region re-registering (permissions and ownership checked later).
208 if ((region != null)
209 && ( (region.coordX != regionInfos.RegionCoordX)
210 || (region.coordY != regionInfos.RegionCoordY)
211 || (region.RegionID != regionInfos.RegionID) )
212 )
142 { 213 {
143 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.", 214 // If not same ID and same coordinates, this new region has conflicts and can't be registered.
144 regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 215 m_log.WarnFormat("{0} Register region conflict in scope {1}. {2}", LogHeader, scopeID, reason);
145 return "Region overlaps another region"; 216 return reason;
146 } 217 }
147 218
148 if (region != null) 219 if (region != null)
@@ -185,15 +256,15 @@ namespace OpenSim.Services.GridService
185 256
186 if (!m_AllowDuplicateNames) 257 if (!m_AllowDuplicateNames)
187 { 258 {
188 List<RegionData> dupe = m_Database.Get(regionInfos.RegionName, scopeID); 259 List<RegionData> dupe = m_Database.Get(Util.EscapeForLike(regionInfos.RegionName), scopeID);
189 if (dupe != null && dupe.Count > 0) 260 if (dupe != null && dupe.Count > 0)
190 { 261 {
191 foreach (RegionData d in dupe) 262 foreach (RegionData d in dupe)
192 { 263 {
193 if (d.RegionID != regionInfos.RegionID) 264 if (d.RegionID != regionInfos.RegionID)
194 { 265 {
195 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register duplicate name with ID {1}.", 266 m_log.WarnFormat("[GRID SERVICE]: Region tried to register using a duplicate name. New region: {0} ({1}), existing region: {2} ({3}).",
196 regionInfos.RegionName, regionInfos.RegionID); 267 regionInfos.RegionName, regionInfos.RegionID, d.RegionName, d.RegionID);
197 return "Duplicate region name"; 268 return "Duplicate region name";
198 } 269 }
199 } 270 }
@@ -265,12 +336,121 @@ namespace OpenSim.Services.GridService
265 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); 336 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
266 } 337 }
267 338
268 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}", 339 m_log.InfoFormat
269 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY); 340 ("[GRID SERVICE]: Region {0} ({1}, {2}x{3}) registered at {4},{5} with flags {6}",
341 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionSizeX, regionInfos.RegionSizeY,
342 regionInfos.RegionCoordX, regionInfos.RegionCoordY,
343 (OpenSim.Framework.RegionFlags)flags);
270 344
271 return String.Empty; 345 return String.Empty;
272 } 346 }
273 347
348 /// <summary>
349 /// Search the region map for regions conflicting with this region.
350 /// The region to be added is passed and we look for any existing regions that are
351 /// in the requested location, that are large varregions that overlap this region, or
352 /// are previously defined regions that would lie under this new region.
353 /// </summary>
354 /// <param name="regionInfos">Information on region requested to be added to the world map</param>
355 /// <param name="scopeID">Grid id for region</param>
356 /// <param name="reason">The reason the returned region conflicts with passed region</param>
357 /// <returns></returns>
358 private RegionData FindAnyConflictingRegion(GridRegion regionInfos, UUID scopeID, out string reason)
359 {
360 reason = "Reregistration";
361 // First see if there is an existing region right where this region is trying to go
362 // (We keep this result so it can be returned if suppressing errors)
363 RegionData noErrorRegion = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
364 RegionData region = noErrorRegion;
365 if (region != null
366 && region.RegionID == regionInfos.RegionID
367 && region.sizeX == regionInfos.RegionSizeX
368 && region.sizeY == regionInfos.RegionSizeY)
369 {
370 // If this seems to be exactly the same region, return this as it could be
371 // a re-registration (permissions checked by calling routine).
372 m_log.DebugFormat("{0} FindAnyConflictingRegion: re-register of {1}",
373 LogHeader, RegionString(regionInfos));
374 return region;
375 }
376
377 // No region exactly there or we're resizing an existing region.
378 // Fetch regions that could be varregions overlapping requested location.
379 int xmin = regionInfos.RegionLocX - (int)Constants.MaximumRegionSize + 10;
380 int xmax = regionInfos.RegionLocX;
381 int ymin = regionInfos.RegionLocY - (int)Constants.MaximumRegionSize + 10;
382 int ymax = regionInfos.RegionLocY;
383 List<RegionData> rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID);
384 foreach (RegionData rdata in rdatas)
385 {
386 // m_log.DebugFormat("{0} FindAnyConflictingRegion: find existing. Checking {1}", LogHeader, RegionString(rdata) );
387 if ( (rdata.posX + rdata.sizeX > regionInfos.RegionLocX)
388 && (rdata.posY + rdata.sizeY > regionInfos.RegionLocY) )
389 {
390 region = rdata;
391 m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of {1} by existing varregion {2}",
392 LogHeader, RegionString(regionInfos), RegionString(region));
393 reason = String.Format("Region location is overlapped by existing varregion {0}",
394 RegionString(region));
395
396 if (m_SuppressVarregionOverlapCheckOnRegistration)
397 region = noErrorRegion;
398 return region;
399 }
400 }
401
402 // There isn't a region that overlaps this potential region.
403 // See if this potential region overlaps an existing region.
404 // First, a shortcut of not looking for overlap if new region is legacy region sized
405 // and connot overlap anything.
406 if (regionInfos.RegionSizeX != Constants.RegionSize
407 || regionInfos.RegionSizeY != Constants.RegionSize)
408 {
409 // trim range looked for so we don't pick up neighbor regions just off the edges
410 xmin = regionInfos.RegionLocX;
411 xmax = regionInfos.RegionLocX + regionInfos.RegionSizeX - 10;
412 ymin = regionInfos.RegionLocY;
413 ymax = regionInfos.RegionLocY + regionInfos.RegionSizeY - 10;
414 rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID);
415
416 // If the region is being resized, the found region could be ourself.
417 foreach (RegionData rdata in rdatas)
418 {
419 // m_log.DebugFormat("{0} FindAnyConflictingRegion: see if overlap. Checking {1}", LogHeader, RegionString(rdata) );
420 if (region == null || region.RegionID != regionInfos.RegionID)
421 {
422 region = rdata;
423 m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of varregion {1} overlaps existing region {2}",
424 LogHeader, RegionString(regionInfos), RegionString(region));
425 reason = String.Format("Region {0} would overlap existing region {1}",
426 RegionString(regionInfos), RegionString(region));
427
428 if (m_SuppressVarregionOverlapCheckOnRegistration)
429 region = noErrorRegion;
430 return region;
431 }
432 }
433 }
434
435 // If we get here, region is either null (nothing found here) or
436 // is the non-conflicting region found at the location being requested.
437 return region;
438 }
439
440 // String describing name and region location of passed region
441 private String RegionString(RegionData reg)
442 {
443 return String.Format("{0}/{1} at <{2},{3}>",
444 reg.RegionName, reg.RegionID, reg.coordX, reg.coordY);
445 }
446
447 // String describing name and region location of passed region
448 private String RegionString(GridRegion reg)
449 {
450 return String.Format("{0}/{1} at <{2},{3}>",
451 reg.RegionName, reg.RegionID, reg.RegionCoordX, reg.RegionCoordY);
452 }
453
274 public bool DeregisterRegion(UUID regionID) 454 public bool DeregisterRegion(UUID regionID)
275 { 455 {
276 RegionData region = m_Database.Get(regionID, UUID.Zero); 456 RegionData region = m_Database.Get(regionID, UUID.Zero);
@@ -312,8 +492,10 @@ namespace OpenSim.Services.GridService
312 if (region != null) 492 if (region != null)
313 { 493 {
314 // Not really? Maybe? 494 // Not really? Maybe?
315 List<RegionData> rdatas = m_Database.Get(region.posX - (int)Constants.RegionSize - 1, region.posY - (int)Constants.RegionSize - 1, 495 // The adjacent regions are presumed to be the same size as the current region
316 region.posX + (int)Constants.RegionSize + 1, region.posY + (int)Constants.RegionSize + 1, scopeID); 496 List<RegionData> rdatas = m_Database.Get(
497 region.posX - region.sizeX - 1, region.posY - region.sizeY - 1,
498 region.posX + region.sizeX + 1, region.posY + region.sizeY + 1, scopeID);
317 499
318 foreach (RegionData rdata in rdatas) 500 foreach (RegionData rdata in rdatas)
319 { 501 {
@@ -325,7 +507,11 @@ namespace OpenSim.Services.GridService
325 } 507 }
326 } 508 }
327 509
328// m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighbours", region.RegionName, rinfos.Count); 510 // string rNames = "";
511 // foreach (GridRegion gr in rinfos)
512 // rNames += gr.RegionName + ",";
513 // m_log.DebugFormat("{0} region {1} has {2} neighbours ({3})",
514 // LogHeader, region.RegionName, rinfos.Count, rNames);
329 } 515 }
330 else 516 else
331 { 517 {
@@ -346,20 +532,36 @@ namespace OpenSim.Services.GridService
346 return null; 532 return null;
347 } 533 }
348 534
535 // Get a region given its base coordinates.
536 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
537 // be the base coordinate of the region.
538 // The snapping is technically unnecessary but is harmless because regions are always
539 // multiples of the legacy region size (256).
349 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 540 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
350 { 541 {
351 int snapX = (int)(x / Constants.RegionSize) * (int)Constants.RegionSize; 542 uint regionX = Util.WorldToRegionLoc((uint)x);
352 int snapY = (int)(y / Constants.RegionSize) * (int)Constants.RegionSize; 543 uint regionY = Util.WorldToRegionLoc((uint)y);
544 int snapX = (int)Util.RegionToWorldLoc(regionX);
545 int snapY = (int)Util.RegionToWorldLoc(regionY);
546
353 RegionData rdata = m_Database.Get(snapX, snapY, scopeID); 547 RegionData rdata = m_Database.Get(snapX, snapY, scopeID);
354 if (rdata != null) 548 if (rdata != null)
549 {
550 m_log.DebugFormat("{0} GetRegionByPosition. Found region {1} in database. Pos=<{2},{3}>",
551 LogHeader, rdata.RegionName, regionX, regionY);
355 return RegionData2RegionInfo(rdata); 552 return RegionData2RegionInfo(rdata);
356 553 }
357 return null; 554 else
555 {
556 m_log.DebugFormat("{0} GetRegionByPosition. Did not find region in database. Pos=<{1},{2}>",
557 LogHeader, regionX, regionY);
558 return null;
559 }
358 } 560 }
359 561
360 public GridRegion GetRegionByName(UUID scopeID, string name) 562 public GridRegion GetRegionByName(UUID scopeID, string name)
361 { 563 {
362 List<RegionData> rdatas = m_Database.Get(name, scopeID); 564 List<RegionData> rdatas = m_Database.Get(Util.EscapeForLike(name), scopeID);
363 if ((rdatas != null) && (rdatas.Count > 0)) 565 if ((rdatas != null) && (rdatas.Count > 0))
364 return RegionData2RegionInfo(rdatas[0]); // get the first 566 return RegionData2RegionInfo(rdatas[0]); // get the first
365 567
@@ -377,7 +579,7 @@ namespace OpenSim.Services.GridService
377 { 579 {
378// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); 580// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name);
379 581
380 List<RegionData> rdatas = m_Database.Get(name + "%", scopeID); 582 List<RegionData> rdatas = m_Database.Get(Util.EscapeForLike(name) + "%", scopeID);
381 583
382 int count = 0; 584 int count = 0;
383 List<GridRegion> rinfos = new List<GridRegion>(); 585 List<GridRegion> rinfos = new List<GridRegion>();
@@ -440,6 +642,8 @@ namespace OpenSim.Services.GridService
440 RegionData rdata = new RegionData(); 642 RegionData rdata = new RegionData();
441 rdata.posX = (int)rinfo.RegionLocX; 643 rdata.posX = (int)rinfo.RegionLocX;
442 rdata.posY = (int)rinfo.RegionLocY; 644 rdata.posY = (int)rinfo.RegionLocY;
645 rdata.sizeX = rinfo.RegionSizeX;
646 rdata.sizeY = rinfo.RegionSizeY;
443 rdata.RegionID = rinfo.RegionID; 647 rdata.RegionID = rinfo.RegionID;
444 rdata.RegionName = rinfo.RegionName; 648 rdata.RegionName = rinfo.RegionName;
445 rdata.Data = rinfo.ToKeyValuePairs(); 649 rdata.Data = rinfo.ToKeyValuePairs();
@@ -453,6 +657,8 @@ namespace OpenSim.Services.GridService
453 GridRegion rinfo = new GridRegion(rdata.Data); 657 GridRegion rinfo = new GridRegion(rdata.Data);
454 rinfo.RegionLocX = rdata.posX; 658 rinfo.RegionLocX = rdata.posX;
455 rinfo.RegionLocY = rdata.posY; 659 rinfo.RegionLocY = rdata.posY;
660 rinfo.RegionSizeX = rdata.sizeX;
661 rinfo.RegionSizeY = rdata.sizeY;
456 rinfo.RegionID = rdata.RegionID; 662 rinfo.RegionID = rdata.RegionID;
457 rinfo.RegionName = rdata.RegionName; 663 rinfo.RegionName = rdata.RegionName;
458 rinfo.ScopeID = rdata.ScopeID; 664 rinfo.ScopeID = rdata.ScopeID;
@@ -478,6 +684,33 @@ namespace OpenSim.Services.GridService
478 return ret; 684 return ret;
479 } 685 }
480 686
687 public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
688 {
689 List<GridRegion> ret = new List<GridRegion>();
690
691 List<RegionData> regions = m_Database.GetDefaultHypergridRegions(scopeID);
692
693 foreach (RegionData r in regions)
694 {
695 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0)
696 ret.Add(RegionData2RegionInfo(r));
697 }
698
699 int hgDefaultRegionsFoundOnline = regions.Count;
700
701 // For now, hypergrid default regions will always be given precedence but we will also return simple default
702 // regions in case no specific hypergrid regions are specified.
703 ret.AddRange(GetDefaultRegions(scopeID));
704
705 int normalDefaultRegionsFoundOnline = ret.Count - hgDefaultRegionsFoundOnline;
706
707 m_log.DebugFormat(
708 "[GRID SERVICE]: GetDefaultHypergridRegions returning {0} hypergrid default and {1} normal default regions",
709 hgDefaultRegionsFoundOnline, normalDefaultRegionsFoundOnline);
710
711 return ret;
712 }
713
481 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) 714 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
482 { 715 {
483 List<GridRegion> ret = new List<GridRegion>(); 716 List<GridRegion> ret = new List<GridRegion>();
@@ -526,40 +759,41 @@ namespace OpenSim.Services.GridService
526 759
527 private void HandleDeregisterRegion(string module, string[] cmd) 760 private void HandleDeregisterRegion(string module, string[] cmd)
528 { 761 {
529 if (cmd.Length != 4) 762 if (cmd.Length < 4)
530 { 763 {
531 MainConsole.Instance.Output("Syntax: degregister region id <Region UUID>"); 764 MainConsole.Instance.Output("Usage: degregister region id <region-id>+");
532 return; 765 return;
533 } 766 }
534 767
535 string rawRegionUuid = cmd[3]; 768 for (int i = 3; i < cmd.Length; i++)
536 UUID regionUuid;
537
538 if (!UUID.TryParse(rawRegionUuid, out regionUuid))
539 { 769 {
540 MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid); 770 string rawRegionUuid = cmd[i];
541 return; 771 UUID regionUuid;
542 }
543 772
544 GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid); 773 if (!UUID.TryParse(rawRegionUuid, out regionUuid))
774 {
775 MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid);
776 return;
777 }
545 778
546 if (region == null) 779 GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid);
547 {
548 MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid);
549 return;
550 }
551 780
552 if (DeregisterRegion(regionUuid)) 781 if (region == null)
553 { 782 {
554 MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid); 783 MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid);
555 } 784 return;
556 else 785 }
557 {
558 // I don't think this can ever occur if we know that the region exists.
559 MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid);
560 }
561 786
562 return; 787 if (DeregisterRegion(regionUuid))
788 {
789 MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid);
790 }
791 else
792 {
793 // I don't think this can ever occur if we know that the region exists.
794 MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid);
795 }
796 }
563 } 797 }
564 798
565 private void HandleShowRegions(string module, string[] cmd) 799 private void HandleShowRegions(string module, string[] cmd)
@@ -575,6 +809,27 @@ namespace OpenSim.Services.GridService
575 OutputRegionsToConsoleSummary(regions); 809 OutputRegionsToConsoleSummary(regions);
576 } 810 }
577 811
812 private void HandleShowGridSize(string module, string[] cmd)
813 {
814 List<RegionData> regions = m_Database.Get(int.MinValue, int.MinValue, int.MaxValue, int.MaxValue, UUID.Zero);
815
816 double size = 0;
817
818 foreach (RegionData region in regions)
819 {
820 int flags = Convert.ToInt32(region.Data["flags"]);
821
822 if ((flags & (int)Framework.RegionFlags.Hyperlink) == 0)
823 size += region.sizeX * region.sizeY;
824 }
825
826 MainConsole.Instance.Output("This is a very rough approximation.");
827 MainConsole.Instance.Output("Although it will not count regions that are actually links to others over the Hypergrid, ");
828 MainConsole.Instance.Output("it will count regions that are inactive but were not deregistered from the grid service");
829 MainConsole.Instance.Output("(e.g. simulator crashed rather than shutting down cleanly).\n");
830
831 MainConsole.Instance.OutputFormat("Grid size: {0} km squared.", size / 1000000);
832 }
578 833
579 private void HandleShowRegion(string module, string[] cmd) 834 private void HandleShowRegion(string module, string[] cmd)
580 { 835 {
@@ -586,7 +841,7 @@ namespace OpenSim.Services.GridService
586 841
587 string regionName = cmd[3]; 842 string regionName = cmd[3];
588 843
589 List<RegionData> regions = m_Database.Get(regionName, UUID.Zero); 844 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(regionName), UUID.Zero);
590 if (regions == null || regions.Count < 1) 845 if (regions == null || regions.Count < 1)
591 { 846 {
592 MainConsole.Instance.Output("No region with name {0} found", regionName); 847 MainConsole.Instance.Output("No region with name {0} found", regionName);
@@ -604,20 +859,20 @@ namespace OpenSim.Services.GridService
604 return; 859 return;
605 } 860 }
606 861
607 int x, y; 862 uint x, y;
608 if (!int.TryParse(cmd[3], out x)) 863 if (!uint.TryParse(cmd[3], out x))
609 { 864 {
610 MainConsole.Instance.Output("x-coord must be an integer"); 865 MainConsole.Instance.Output("x-coord must be an integer");
611 return; 866 return;
612 } 867 }
613 868
614 if (!int.TryParse(cmd[4], out y)) 869 if (!uint.TryParse(cmd[4], out y))
615 { 870 {
616 MainConsole.Instance.Output("y-coord must be an integer"); 871 MainConsole.Instance.Output("y-coord must be an integer");
617 return; 872 return;
618 } 873 }
619 874
620 RegionData region = m_Database.Get(x * (int)Constants.RegionSize, y * (int)Constants.RegionSize, UUID.Zero); 875 RegionData region = m_Database.Get((int)Util.RegionToWorldLoc(x), (int)Util.RegionToWorldLoc(y), UUID.Zero);
621 if (region == null) 876 if (region == null)
622 { 877 {
623 MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y); 878 MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y);
@@ -634,7 +889,8 @@ namespace OpenSim.Services.GridService
634 ConsoleDisplayList dispList = new ConsoleDisplayList(); 889 ConsoleDisplayList dispList = new ConsoleDisplayList();
635 dispList.AddRow("Region Name", r.RegionName); 890 dispList.AddRow("Region Name", r.RegionName);
636 dispList.AddRow("Region ID", r.RegionID); 891 dispList.AddRow("Region ID", r.RegionID);
637 dispList.AddRow("Location", string.Format("{0},{1}", r.coordX, r.coordY)); 892 dispList.AddRow("Position", string.Format("{0},{1}", r.coordX, r.coordY));
893 dispList.AddRow("Size", string.Format("{0}x{1}", r.sizeX, r.sizeY));
638 dispList.AddRow("URI", r.Data["serverURI"]); 894 dispList.AddRow("URI", r.Data["serverURI"]);
639 dispList.AddRow("Owner ID", r.Data["owner_uuid"]); 895 dispList.AddRow("Owner ID", r.Data["owner_uuid"]);
640 dispList.AddRow("Flags", flags); 896 dispList.AddRow("Flags", flags);
@@ -651,10 +907,10 @@ namespace OpenSim.Services.GridService
651 private void OutputRegionsToConsoleSummary(List<RegionData> regions) 907 private void OutputRegionsToConsoleSummary(List<RegionData> regions)
652 { 908 {
653 ConsoleDisplayTable dispTable = new ConsoleDisplayTable(); 909 ConsoleDisplayTable dispTable = new ConsoleDisplayTable();
654 dispTable.AddColumn("Name", 16); 910 dispTable.AddColumn("Name", 44);
655 dispTable.AddColumn("ID", 36); 911 dispTable.AddColumn("ID", 36);
656 dispTable.AddColumn("Position", 11); 912 dispTable.AddColumn("Position", 11);
657 dispTable.AddColumn("Owner ID", 36); 913 dispTable.AddColumn("Size", 11);
658 dispTable.AddColumn("Flags", 60); 914 dispTable.AddColumn("Flags", 60);
659 915
660 foreach (RegionData r in regions) 916 foreach (RegionData r in regions)
@@ -664,7 +920,7 @@ namespace OpenSim.Services.GridService
664 r.RegionName, 920 r.RegionName,
665 r.RegionID.ToString(), 921 r.RegionID.ToString(),
666 string.Format("{0},{1}", r.coordX, r.coordY), 922 string.Format("{0},{1}", r.coordX, r.coordY),
667 r.Data["owner_uuid"].ToString(), 923 string.Format("{0}x{1}", r.sizeX, r.sizeY),
668 flags.ToString()); 924 flags.ToString());
669 } 925 }
670 926
@@ -716,7 +972,7 @@ namespace OpenSim.Services.GridService
716 return; 972 return;
717 } 973 }
718 974
719 List<RegionData> regions = m_Database.Get(cmd[3], UUID.Zero); 975 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(cmd[3]), UUID.Zero);
720 if (regions == null || regions.Count < 1) 976 if (regions == null || regions.Count < 1)
721 { 977 {
722 MainConsole.Instance.Output("Region not found"); 978 MainConsole.Instance.Output("Region not found");
@@ -734,5 +990,18 @@ namespace OpenSim.Services.GridService
734 m_Database.Store(r); 990 m_Database.Store(r);
735 } 991 }
736 } 992 }
993
994 /// <summary>
995 /// Gets the grid extra service URls we wish for the region to send in OpenSimExtras to dynamically refresh
996 /// parameters in the viewer used to access services like map, search and destination guides.
997 /// <para>see "SimulatorFeaturesModule" </para>
998 /// </summary>
999 /// <returns>
1000 /// The grid extra service URls.
1001 /// </returns>
1002 public Dictionary<string,object> GetExtraFeatures()
1003 {
1004 return m_ExtraFeatures;
1005 }
737 } 1006 }
738} 1007}