aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/GridService
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/GridService')
-rw-r--r--OpenSim/Services/GridService/GridService.cs415
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs236
-rw-r--r--OpenSim/Services/GridService/Properties/AssemblyInfo.cs4
3 files changed, 515 insertions, 140 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}
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
index 7abed20..9d016fc 100644
--- a/OpenSim/Services/GridService/HypergridLinker.cs
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -47,7 +47,7 @@ using OpenMetaverse;
47 47
48namespace OpenSim.Services.GridService 48namespace OpenSim.Services.GridService
49{ 49{
50 public class HypergridLinker 50 public class HypergridLinker : IHypergridLinker
51 { 51 {
52 private static readonly ILog m_log = 52 private static readonly ILog m_log =
53 LogManager.GetLogger( 53 LogManager.GetLogger(
@@ -63,14 +63,11 @@ namespace OpenSim.Services.GridService
63 protected GatekeeperServiceConnector m_GatekeeperConnector; 63 protected GatekeeperServiceConnector m_GatekeeperConnector;
64 64
65 protected UUID m_ScopeID = UUID.Zero; 65 protected UUID m_ScopeID = UUID.Zero;
66// protected bool m_Check4096 = true;
66 protected string m_MapTileDirectory = string.Empty; 67 protected string m_MapTileDirectory = string.Empty;
67 protected string m_ThisGatekeeper = string.Empty; 68 protected string m_ThisGatekeeper = string.Empty;
68 protected Uri m_ThisGatekeeperURI = null; 69 protected Uri m_ThisGatekeeperURI = null;
69 70
70 // Hyperlink regions are hyperlinks on the map
71 public readonly Dictionary<UUID, GridRegion> m_HyperlinkRegions = new Dictionary<UUID, GridRegion>();
72 protected Dictionary<UUID, ulong> m_HyperlinkHandles = new Dictionary<UUID, ulong>();
73
74 protected GridRegion m_DefaultRegion; 71 protected GridRegion m_DefaultRegion;
75 protected GridRegion DefaultRegion 72 protected GridRegion DefaultRegion
76 { 73 {
@@ -78,7 +75,7 @@ namespace OpenSim.Services.GridService
78 { 75 {
79 if (m_DefaultRegion == null) 76 if (m_DefaultRegion == null)
80 { 77 {
81 List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID); 78 List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
82 if (defs != null && defs.Count > 0) 79 if (defs != null && defs.Count > 0)
83 m_DefaultRegion = defs[0]; 80 m_DefaultRegion = defs[0];
84 else 81 else
@@ -123,9 +120,14 @@ namespace OpenSim.Services.GridService
123 if (scope != string.Empty) 120 if (scope != string.Empty)
124 UUID.TryParse(scope, out m_ScopeID); 121 UUID.TryParse(scope, out m_ScopeID);
125 122
123// m_Check4096 = gridConfig.GetBoolean("Check4096", true);
124
126 m_MapTileDirectory = gridConfig.GetString("MapTileDirectory", "maptiles"); 125 m_MapTileDirectory = gridConfig.GetString("MapTileDirectory", "maptiles");
127 126
128 m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", string.Empty); 127 m_ThisGatekeeper = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
128 new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty);
129 // Legacy. Remove soon!
130 m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", m_ThisGatekeeper);
129 try 131 try
130 { 132 {
131 m_ThisGatekeeperURI = new Uri(m_ThisGatekeeper); 133 m_ThisGatekeeperURI = new Uri(m_ThisGatekeeper);
@@ -154,18 +156,18 @@ namespace OpenSim.Services.GridService
154 156
155 if (MainConsole.Instance != null) 157 if (MainConsole.Instance != null)
156 { 158 {
157 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region", 159 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-region",
158 "link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]", 160 "link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]",
159 "Link a HyperGrid Region. Examples for <ServerURI>: http://grid.net:8002/ or http://example.org/path/foo.php", RunCommand); 161 "Link a HyperGrid Region. Examples for <ServerURI>: http://grid.net:8002/ or http://example.org/path/foo.php", RunCommand);
160 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region", 162 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-region",
161 "link-region <Xloc> <Yloc> <RegionIP> <RegionPort> [<RemoteRegionName>]", 163 "link-region <Xloc> <Yloc> <RegionIP> <RegionPort> [<RemoteRegionName>]",
162 "Link a hypergrid region (deprecated)", RunCommand); 164 "Link a hypergrid region (deprecated)", RunCommand);
163 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "unlink-region", 165 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "unlink-region",
164 "unlink-region <local name>", 166 "unlink-region <local name>",
165 "Unlink a hypergrid region", RunCommand); 167 "Unlink a hypergrid region", RunCommand);
166 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-mapping", "link-mapping [<x> <y>]", 168 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-mapping", "link-mapping [<x> <y>]",
167 "Set local coordinate to map HG regions to", RunCommand); 169 "Set local coordinate to map HG regions to", RunCommand);
168 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "show hyperlinks", "show hyperlinks", 170 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "show hyperlinks", "show hyperlinks",
169 "List the HG regions", HandleShow); 171 "List the HG regions", HandleShow);
170 } 172 }
171 } 173 }
@@ -177,14 +179,14 @@ namespace OpenSim.Services.GridService
177 public GridRegion LinkRegion(UUID scopeID, string regionDescriptor) 179 public GridRegion LinkRegion(UUID scopeID, string regionDescriptor)
178 { 180 {
179 string reason = string.Empty; 181 string reason = string.Empty;
180 int xloc = random.Next(0, Int16.MaxValue) * (int)Constants.RegionSize; 182 uint xloc = Util.RegionToWorldLoc((uint)random.Next(0, Int16.MaxValue));
181 return TryLinkRegionToCoords(scopeID, regionDescriptor, xloc, 0, out reason); 183 return TryLinkRegionToCoords(scopeID, regionDescriptor, (int)xloc, 0, out reason);
182 } 184 }
183 185
184 private static Random random = new Random(); 186 private static Random random = new Random();
185 187
186 // From the command line link-region (obsolete) and the map 188 // From the command line link-region (obsolete) and the map
187 public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason) 189 private GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason)
188 { 190 {
189 return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason); 191 return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason);
190 } 192 }
@@ -194,24 +196,36 @@ namespace OpenSim.Services.GridService
194 reason = string.Empty; 196 reason = string.Empty;
195 GridRegion regInfo = null; 197 GridRegion regInfo = null;
196 198
199 mapName = mapName.Trim();
200
197 if (!mapName.StartsWith("http")) 201 if (!mapName.StartsWith("http"))
198 { 202 {
199 string host = "127.0.0.1"; 203 // Formats: grid.example.com:8002:region name
200 string portstr; 204 // grid.example.com:region name
205 // grid.example.com:8002
206 // grid.example.com
207
208 string host;
209 uint port = 80;
201 string regionName = ""; 210 string regionName = "";
202 uint port = 0; 211
203 string[] parts = mapName.Split(new char[] { ':' }); 212 string[] parts = mapName.Split(new char[] { ':' });
204 if (parts.Length >= 1) 213
214 if (parts.Length == 0)
205 { 215 {
206 host = parts[0]; 216 reason = "Wrong format for link-region";
217 return null;
207 } 218 }
219
220 host = parts[0];
221
208 if (parts.Length >= 2) 222 if (parts.Length >= 2)
209 { 223 {
210 portstr = parts[1]; 224 // If it's a number then assume it's a port. Otherwise, it's a region name.
211 //m_log.Debug("-- port = " + portstr); 225 if (!UInt32.TryParse(parts[1], out port))
212 if (!UInt32.TryParse(portstr, out port))
213 regionName = parts[1]; 226 regionName = parts[1];
214 } 227 }
228
215 // always take the last one 229 // always take the last one
216 if (parts.Length >= 3) 230 if (parts.Length >= 3)
217 { 231 {
@@ -228,14 +242,30 @@ namespace OpenSim.Services.GridService
228 } 242 }
229 else 243 else
230 { 244 {
231 string[] parts = mapName.Split(new char[] {' '}); 245 // Formats: http://grid.example.com region name
232 string regionName = String.Empty; 246 // http://grid.example.com "region name"
233 if (parts.Length > 1) 247 // http://grid.example.com
248
249 string serverURI;
250 string regionName = "";
251
252 string[] parts = mapName.Split(new char[] { ' ' });
253
254 if (parts.Length == 0)
234 { 255 {
235 regionName = mapName.Substring(parts[0].Length + 1); 256 reason = "Wrong format for link-region";
236 regionName = regionName.Trim(new char[] {'"'}); 257 return null;
237 } 258 }
238 if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, parts[0], ownerID, out regInfo, out reason)) 259
260 serverURI = parts[0];
261
262 if (parts.Length >= 2)
263 {
264 regionName = mapName.Substring(serverURI.Length);
265 regionName = regionName.Trim(new char[] { '"', ' ' });
266 }
267
268 if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason))
239 { 269 {
240 regInfo.RegionName = mapName; 270 regInfo.RegionName = mapName;
241 return regInfo; 271 return regInfo;
@@ -244,31 +274,39 @@ namespace OpenSim.Services.GridService
244 274
245 return null; 275 return null;
246 } 276 }
247 277
248 public bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason) 278 private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason)
249 { 279 {
250 return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason); 280 return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason);
251 } 281 }
252 282
253 public bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason) 283 private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason)
254 { 284 {
255 m_log.DebugFormat("[HYPERGRID LINKER]: Link to {0} {1}, in {2}-{3}", 285 lock (this)
286 {
287 return TryCreateLinkImpl(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, serverURI, ownerID, out regInfo, out reason);
288 }
289 }
290
291 private bool TryCreateLinkImpl(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason)
292 {
293 m_log.InfoFormat("[HYPERGRID LINKER]: Link to {0} {1}, in <{2},{3}>",
256 ((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI), 294 ((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI),
257 remoteRegionName, xloc / Constants.RegionSize, yloc / Constants.RegionSize); 295 remoteRegionName, Util.WorldToRegionLoc((uint)xloc), Util.WorldToRegionLoc((uint)yloc));
258 296
259 reason = string.Empty; 297 reason = string.Empty;
260 Uri uri = null; 298 Uri uri = null;
261 299
262 regInfo = new GridRegion(); 300 regInfo = new GridRegion();
263 if ( externalPort > 0) 301 if (externalPort > 0)
264 regInfo.HttpPort = externalPort; 302 regInfo.HttpPort = externalPort;
265 else 303 else
266 regInfo.HttpPort = 0; 304 regInfo.HttpPort = 80;
267 if ( externalHostName != null) 305 if (externalHostName != null)
268 regInfo.ExternalHostName = externalHostName; 306 regInfo.ExternalHostName = externalHostName;
269 else 307 else
270 regInfo.ExternalHostName = "0.0.0.0"; 308 regInfo.ExternalHostName = "0.0.0.0";
271 if ( serverURI != null) 309 if (serverURI != null)
272 { 310 {
273 regInfo.ServerURI = serverURI; 311 regInfo.ServerURI = serverURI;
274 try 312 try
@@ -280,7 +318,7 @@ namespace OpenSim.Services.GridService
280 catch {} 318 catch {}
281 } 319 }
282 320
283 if ( remoteRegionName != string.Empty ) 321 if (remoteRegionName != string.Empty)
284 regInfo.RegionName = remoteRegionName; 322 regInfo.RegionName = remoteRegionName;
285 323
286 regInfo.RegionLocX = xloc; 324 regInfo.RegionLocX = xloc;
@@ -293,6 +331,7 @@ namespace OpenSim.Services.GridService
293 { 331 {
294 if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port) 332 if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port)
295 { 333 {
334 m_log.InfoFormat("[HYPERGRID LINKER]: Cannot hyperlink to regions on the same grid");
296 reason = "Cannot hyperlink to regions on the same grid"; 335 reason = "Cannot hyperlink to regions on the same grid";
297 return false; 336 return false;
298 } 337 }
@@ -304,8 +343,8 @@ namespace OpenSim.Services.GridService
304 GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY); 343 GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY);
305 if (region != null) 344 if (region != null)
306 { 345 {
307 m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates {0}-{1} are already occupied by region {2} with uuid {3}", 346 m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates <{0},{1}> are already occupied by region {2} with uuid {3}",
308 regInfo.RegionLocX / Constants.RegionSize, regInfo.RegionLocY / Constants.RegionSize, 347 Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY),
309 region.RegionName, region.RegionID); 348 region.RegionName, region.RegionID);
310 reason = "Coordinates are already in use"; 349 reason = "Coordinates are already in use";
311 return false; 350 return false;
@@ -340,12 +379,25 @@ namespace OpenSim.Services.GridService
340 region = m_GridService.GetRegionByUUID(scopeID, regionID); 379 region = m_GridService.GetRegionByUUID(scopeID, regionID);
341 if (region != null) 380 if (region != null)
342 { 381 {
343 m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates {0} {1}", 382 m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates <{0},{1}>",
344 region.RegionLocX / Constants.RegionSize, region.RegionLocY / Constants.RegionSize); 383 Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY));
345 regInfo = region; 384 regInfo = region;
346 return true; 385 return true;
347 } 386 }
348 387
388 // We are now performing this check for each individual teleport in the EntityTransferModule instead. This
389 // allows us to give better feedback when teleports fail because of the distance reason (which can't be
390 // done here) and it also hypergrid teleports that are within range (possibly because the source grid
391 // itself has regions that are very far apart).
392// uint x, y;
393// if (m_Check4096 && !Check4096(handle, out x, out y))
394// {
395// //RemoveHyperlinkRegion(regInfo.RegionID);
396// reason = "Region is too far (" + x + ", " + y + ")";
397// m_log.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")");
398// //return false;
399// }
400
349 regInfo.RegionID = regionID; 401 regInfo.RegionID = regionID;
350 402
351 if (externalName == string.Empty) 403 if (externalName == string.Empty)
@@ -362,7 +414,8 @@ namespace OpenSim.Services.GridService
362 regInfo.RegionSecret = handle.ToString(); 414 regInfo.RegionSecret = handle.ToString();
363 415
364 AddHyperlinkRegion(regInfo, handle); 416 AddHyperlinkRegion(regInfo, handle);
365 m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} with image {1}", regInfo.RegionName, regInfo.TerrainImage); 417 m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} at <{1},{2}> with image {3}",
418 regInfo.RegionName, Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY), regInfo.TerrainImage);
366 return true; 419 return true;
367 } 420 }
368 421
@@ -371,7 +424,7 @@ namespace OpenSim.Services.GridService
371 m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName); 424 m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName);
372 GridRegion regInfo = null; 425 GridRegion regInfo = null;
373 426
374 List<RegionData> regions = m_Database.Get(mapName, m_ScopeID); 427 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(mapName), m_ScopeID);
375 if (regions != null && regions.Count > 0) 428 if (regions != null && regions.Count > 0)
376 { 429 {
377 OpenSim.Framework.RegionFlags rflags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]); 430 OpenSim.Framework.RegionFlags rflags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]);
@@ -395,6 +448,52 @@ namespace OpenSim.Services.GridService
395 } 448 }
396 } 449 }
397 450
451// Not currently used
452// /// <summary>
453// /// Cope with this viewer limitation.
454// /// </summary>
455// /// <param name="regInfo"></param>
456// /// <returns></returns>
457// public bool Check4096(ulong realHandle, out uint x, out uint y)
458// {
459// uint ux = 0, uy = 0;
460// Utils.LongToUInts(realHandle, out ux, out uy);
461// x = Util.WorldToRegionLoc(ux);
462// y = Util.WorldToRegionLoc(uy);
463//
464// const uint limit = Util.RegionToWorldLoc(4096 - 1);
465// uint xmin = ux - limit;
466// uint xmax = ux + limit;
467// uint ymin = uy - limit;
468// uint ymax = uy + limit;
469// // World map boundary checks
470// if (xmin < 0 || xmin > ux)
471// xmin = 0;
472// if (xmax > int.MaxValue || xmax < ux)
473// xmax = int.MaxValue;
474// if (ymin < 0 || ymin > uy)
475// ymin = 0;
476// if (ymax > int.MaxValue || ymax < uy)
477// ymax = int.MaxValue;
478//
479// // Check for any regions that are within the possible teleport range to the linked region
480// List<GridRegion> regions = m_GridService.GetRegionRange(m_ScopeID, (int)xmin, (int)xmax, (int)ymin, (int)ymax);
481// if (regions.Count == 0)
482// {
483// return false;
484// }
485// else
486// {
487// // Check for regions which are not linked regions
488// List<GridRegion> hyperlinks = m_GridService.GetHyperlinks(m_ScopeID);
489// IEnumerable<GridRegion> availableRegions = regions.Except(hyperlinks);
490// if (availableRegions.Count() == 0)
491// return false;
492// }
493//
494// return true;
495// }
496
398 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle) 497 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle)
399 { 498 {
400 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo); 499 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo);
@@ -437,9 +536,14 @@ namespace OpenSim.Services.GridService
437 MainConsole.Instance.Output(new string('-', 72)); 536 MainConsole.Instance.Output(new string('-', 72));
438 foreach (RegionData r in regions) 537 foreach (RegionData r in regions)
439 { 538 {
440 MainConsole.Instance.Output(String.Format("{0}\n{2,-32} {1}\n", 539 MainConsole.Instance.Output(
441 r.RegionName, r.RegionID, String.Format("{0},{1} ({2},{3})", r.posX, r.posY, 540 String.Format("{0}\n{2,-32} {1}\n",
442 r.posX / Constants.RegionSize, r.posY / Constants.RegionSize))); 541 r.RegionName, r.RegionID,
542 String.Format("{0},{1} ({2},{3})", r.posX, r.posY,
543 Util.WorldToRegionLoc((uint)r.posX), Util.WorldToRegionLoc((uint)r.posY)
544 )
545 )
546 );
443 } 547 }
444 return; 548 return;
445 } 549 }
@@ -464,8 +568,8 @@ namespace OpenSim.Services.GridService
464 int xloc, yloc; 568 int xloc, yloc;
465 string serverURI; 569 string serverURI;
466 string remoteName = null; 570 string remoteName = null;
467 xloc = Convert.ToInt32(cmdparams[0]) * (int)Constants.RegionSize; 571 xloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[0]));
468 yloc = Convert.ToInt32(cmdparams[1]) * (int)Constants.RegionSize; 572 yloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[1]));
469 serverURI = cmdparams[2]; 573 serverURI = cmdparams[2];
470 if (cmdparams.Length > 3) 574 if (cmdparams.Length > 3)
471 remoteName = string.Join(" ", cmdparams, 3, cmdparams.Length - 3); 575 remoteName = string.Join(" ", cmdparams, 3, cmdparams.Length - 3);
@@ -536,13 +640,13 @@ namespace OpenSim.Services.GridService
536 { 640 {
537 // old format 641 // old format
538 GridRegion regInfo; 642 GridRegion regInfo;
539 int xloc, yloc; 643 uint xloc, yloc;
540 uint externalPort; 644 uint externalPort;
541 string externalHostName; 645 string externalHostName;
542 try 646 try
543 { 647 {
544 xloc = Convert.ToInt32(cmdparams[0]); 648 xloc = Convert.ToUInt32(cmdparams[0]);
545 yloc = Convert.ToInt32(cmdparams[1]); 649 yloc = Convert.ToUInt32(cmdparams[1]);
546 externalPort = Convert.ToUInt32(cmdparams[3]); 650 externalPort = Convert.ToUInt32(cmdparams[3]);
547 externalHostName = cmdparams[2]; 651 externalHostName = cmdparams[2];
548 //internalPort = Convert.ToUInt32(cmdparams[4]); 652 //internalPort = Convert.ToUInt32(cmdparams[4]);
@@ -556,10 +660,11 @@ namespace OpenSim.Services.GridService
556 } 660 }
557 661
558 // Convert cell coordinates given by the user to meters 662 // Convert cell coordinates given by the user to meters
559 xloc = xloc * (int)Constants.RegionSize; 663 xloc = Util.RegionToWorldLoc(xloc);
560 yloc = yloc * (int)Constants.RegionSize; 664 yloc = Util.RegionToWorldLoc(yloc);
561 string reason = string.Empty; 665 string reason = string.Empty;
562 if (TryCreateLink(UUID.Zero, xloc, yloc, string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason)) 666 if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc,
667 string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
563 { 668 {
564 // What is this? The GridRegion instance will be discarded anyway, 669 // What is this? The GridRegion instance will be discarded anyway,
565 // which effectively ignores any local name given with the command. 670 // which effectively ignores any local name given with the command.
@@ -639,13 +744,13 @@ namespace OpenSim.Services.GridService
639 private void ReadLinkFromConfig(IConfig config) 744 private void ReadLinkFromConfig(IConfig config)
640 { 745 {
641 GridRegion regInfo; 746 GridRegion regInfo;
642 int xloc, yloc; 747 uint xloc, yloc;
643 uint externalPort; 748 uint externalPort;
644 string externalHostName; 749 string externalHostName;
645 uint realXLoc, realYLoc; 750 uint realXLoc, realYLoc;
646 751
647 xloc = Convert.ToInt32(config.GetString("xloc", "0")); 752 xloc = Convert.ToUInt32(config.GetString("xloc", "0"));
648 yloc = Convert.ToInt32(config.GetString("yloc", "0")); 753 yloc = Convert.ToUInt32(config.GetString("yloc", "0"));
649 externalPort = Convert.ToUInt32(config.GetString("externalPort", "0")); 754 externalPort = Convert.ToUInt32(config.GetString("externalPort", "0"));
650 externalHostName = config.GetString("externalHostName", ""); 755 externalHostName = config.GetString("externalHostName", "");
651 realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0")); 756 realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0"));
@@ -653,18 +758,19 @@ namespace OpenSim.Services.GridService
653 758
654 if (m_enableAutoMapping) 759 if (m_enableAutoMapping)
655 { 760 {
656 xloc = (int)((xloc % 100) + m_autoMappingX); 761 xloc = (xloc % 100) + m_autoMappingX;
657 yloc = (int)((yloc % 100) + m_autoMappingY); 762 yloc = (yloc % 100) + m_autoMappingY;
658 } 763 }
659 764
660 if (((realXLoc == 0) && (realYLoc == 0)) || 765 if (((realXLoc == 0) && (realYLoc == 0)) ||
661 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) && 766 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) &&
662 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896)))) 767 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896))))
663 { 768 {
664 xloc = xloc * (int)Constants.RegionSize; 769 xloc = Util.RegionToWorldLoc(xloc);
665 yloc = yloc * (int)Constants.RegionSize; 770 yloc = Util.RegionToWorldLoc(yloc);
666 string reason = string.Empty; 771 string reason = string.Empty;
667 if (TryCreateLink(UUID.Zero, xloc, yloc, string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason)) 772 if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc,
773 string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
668 { 774 {
669 regInfo.RegionName = config.GetString("localName", ""); 775 regInfo.RegionName = config.GetString("localName", "");
670 } 776 }
diff --git a/OpenSim/Services/GridService/Properties/AssemblyInfo.cs b/OpenSim/Services/GridService/Properties/AssemblyInfo.cs
index 5c0c8f4..0841e5a 100644
--- a/OpenSim/Services/GridService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/GridService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33