aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/GridService
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/GridService')
-rw-r--r--OpenSim/Services/GridService/GridService.cs365
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs724
2 files changed, 1079 insertions, 10 deletions
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index 7749c37..89f0716 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -34,6 +34,7 @@ using log4net;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Console; 35using OpenSim.Framework.Console;
36using OpenSim.Data; 36using OpenSim.Data;
37using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion; 39using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenMetaverse; 40using OpenMetaverse;
@@ -46,17 +47,58 @@ namespace OpenSim.Services.GridService
46 LogManager.GetLogger( 47 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType); 48 MethodBase.GetCurrentMethod().DeclaringType);
48 49
50 private bool m_DeleteOnUnregister = true;
51 private static GridService m_RootInstance = null;
52 protected IConfigSource m_config;
53 protected static HypergridLinker m_HypergridLinker;
54
55 protected IAuthenticationService m_AuthenticationService = null;
49 protected bool m_AllowDuplicateNames = false; 56 protected bool m_AllowDuplicateNames = false;
57 protected bool m_AllowHypergridMapSearch = false;
50 58
51 public GridService(IConfigSource config) 59 public GridService(IConfigSource config)
52 : base(config) 60 : base(config)
53 { 61 {
54 m_log.DebugFormat("[GRID SERVICE]: Starting..."); 62 m_log.DebugFormat("[GRID SERVICE]: Starting...");
55 63
64 m_config = config;
56 IConfig gridConfig = config.Configs["GridService"]; 65 IConfig gridConfig = config.Configs["GridService"];
57 if (gridConfig != null) 66 if (gridConfig != null)
58 { 67 {
68 m_DeleteOnUnregister = gridConfig.GetBoolean("DeleteOnUnregister", true);
69
70 string authService = gridConfig.GetString("AuthenticationService", String.Empty);
71
72 if (authService != String.Empty)
73 {
74 Object[] args = new Object[] { config };
75 m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, args);
76 }
59 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); 77 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames);
78 m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch);
79 }
80
81 if (m_RootInstance == null)
82 {
83 m_RootInstance = this;
84
85 if (MainConsole.Instance != null)
86 {
87 MainConsole.Instance.Commands.AddCommand("grid", true,
88 "show region",
89 "show region <Region name>",
90 "Show details on a region",
91 String.Empty,
92 HandleShowRegion);
93
94 MainConsole.Instance.Commands.AddCommand("grid", true,
95 "set region flags",
96 "set region flags <Region name> <flags>",
97 "Set database flags for region",
98 String.Empty,
99 HandleSetFlags);
100 }
101 m_HypergridLinker = new HypergridLinker(m_config, this, m_Database);
60 } 102 }
61 } 103 }
62 104
@@ -64,18 +106,63 @@ namespace OpenSim.Services.GridService
64 106
65 public string RegisterRegion(UUID scopeID, GridRegion regionInfos) 107 public string RegisterRegion(UUID scopeID, GridRegion regionInfos)
66 { 108 {
109 IConfig gridConfig = m_config.Configs["GridService"];
110
111 if (regionInfos.RegionID == UUID.Zero)
112 return "Invalid RegionID - cannot be zero UUID";
113
67 // This needs better sanity testing. What if regionInfo is registering in 114 // This needs better sanity testing. What if regionInfo is registering in
68 // overlapping coords? 115 // overlapping coords?
69 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 116 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
117 if (region != null)
118 {
119 // There is a preexisting record
120 //
121 // Get it's flags
122 //
123 OpenSim.Data.RegionFlags rflags = (OpenSim.Data.RegionFlags)Convert.ToInt32(region.Data["flags"]);
124
125 // Is this a reservation?
126 //
127 if ((rflags & OpenSim.Data.RegionFlags.Reservation) != 0)
128 {
129 // Regions reserved for the null key cannot be taken.
130 if ((string)region.Data["PrincipalID"] == UUID.Zero.ToString())
131 return "Region location is reserved";
132
133 // Treat it as an auth request
134 //
135 // NOTE: Fudging the flags value here, so these flags
136 // should not be used elsewhere. Don't optimize
137 // this with the later retrieval of the same flags!
138 rflags |= OpenSim.Data.RegionFlags.Authenticate;
139 }
140
141 if ((rflags & OpenSim.Data.RegionFlags.Authenticate) != 0)
142 {
143 // Can we authenticate at all?
144 //
145 if (m_AuthenticationService == null)
146 return "No authentication possible";
147
148 if (!m_AuthenticationService.Verify(new UUID(region.Data["PrincipalID"].ToString()), regionInfos.Token, 30))
149 return "Bad authentication";
150 }
151 }
152
70 if ((region != null) && (region.RegionID != regionInfos.RegionID)) 153 if ((region != null) && (region.RegionID != regionInfos.RegionID))
71 { 154 {
72 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.", 155 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
73 regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 156 regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
74 return "Region overlaps another region"; 157 return "Region overlaps another region";
75 } 158 }
159
76 if ((region != null) && (region.RegionID == regionInfos.RegionID) && 160 if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
77 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY))) 161 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
78 { 162 {
163 if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0)
164 return "Can't move this region";
165
79 // Region reregistering in other coordinates. Delete the old entry 166 // Region reregistering in other coordinates. Delete the old entry
80 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.", 167 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
81 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); 168 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
@@ -110,8 +197,38 @@ namespace OpenSim.Services.GridService
110 // Everything is ok, let's register 197 // Everything is ok, let's register
111 RegionData rdata = RegionInfo2RegionData(regionInfos); 198 RegionData rdata = RegionInfo2RegionData(regionInfos);
112 rdata.ScopeID = scopeID; 199 rdata.ScopeID = scopeID;
200
201 if (region != null)
202 {
203 int oldFlags = Convert.ToInt32(region.Data["flags"]);
204 if ((oldFlags & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
205 return "Region locked out";
206
207 oldFlags &= ~(int)OpenSim.Data.RegionFlags.Reservation;
208
209 rdata.Data["flags"] = oldFlags.ToString(); // Preserve flags
210 }
211 else
212 {
213 rdata.Data["flags"] = "0";
214 if ((gridConfig != null) && rdata.RegionName != string.Empty)
215 {
216 int newFlags = 0;
217 string regionName = rdata.RegionName.Trim().Replace(' ', '_');
218 newFlags = ParseFlags(newFlags, gridConfig.GetString("DefaultRegionFlags", String.Empty));
219 newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + regionName, String.Empty));
220 newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + rdata.RegionID.ToString(), String.Empty));
221 rdata.Data["flags"] = newFlags.ToString();
222 }
223 }
224
225 int flags = Convert.ToInt32(rdata.Data["flags"]);
226 flags |= (int)OpenSim.Data.RegionFlags.RegionOnline;
227 rdata.Data["flags"] = flags.ToString();
228
113 try 229 try
114 { 230 {
231 rdata.Data["last_seen"] = Util.UnixTimeSinceEpoch();
115 m_Database.Store(rdata); 232 m_Database.Store(rdata);
116 } 233 }
117 catch (Exception e) 234 catch (Exception e)
@@ -120,14 +237,41 @@ namespace OpenSim.Services.GridService
120 } 237 }
121 238
122 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}", 239 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}",
123 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); 240 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY);
124 241
125 return String.Empty; 242 return String.Empty;
126 } 243 }
127 244
128 public bool DeregisterRegion(UUID regionID) 245 public bool DeregisterRegion(UUID regionID)
129 { 246 {
130 m_log.DebugFormat("[GRID SERVICE]: Region {0} deregistered", regionID); 247 RegionData region = m_Database.Get(regionID, UUID.Zero);
248 if (region == null)
249 return false;
250
251 m_log.DebugFormat(
252 "[GRID SERVICE]: Deregistering region {0} ({1}) at {2}-{3}",
253 region.RegionName, region.RegionID, region.coordX, region.coordY);
254
255 int flags = Convert.ToInt32(region.Data["flags"]);
256
257 if (!m_DeleteOnUnregister || (flags & (int)OpenSim.Data.RegionFlags.Persistent) != 0)
258 {
259 flags &= ~(int)OpenSim.Data.RegionFlags.RegionOnline;
260 region.Data["flags"] = flags.ToString();
261 region.Data["last_seen"] = Util.UnixTimeSinceEpoch();
262 try
263 {
264 m_Database.Store(region);
265 }
266 catch (Exception e)
267 {
268 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
269 }
270
271 return true;
272
273 }
274
131 return m_Database.Delete(regionID); 275 return m_Database.Delete(regionID);
132 } 276 }
133 277
@@ -135,17 +279,32 @@ namespace OpenSim.Services.GridService
135 { 279 {
136 List<GridRegion> rinfos = new List<GridRegion>(); 280 List<GridRegion> rinfos = new List<GridRegion>();
137 RegionData region = m_Database.Get(regionID, scopeID); 281 RegionData region = m_Database.Get(regionID, scopeID);
282
138 if (region != null) 283 if (region != null)
139 { 284 {
140 // Not really? Maybe? 285 // Not really? Maybe?
141 List<RegionData> rdatas = m_Database.Get(region.posX - (int)Constants.RegionSize, region.posY - (int)Constants.RegionSize, 286 List<RegionData> rdatas = m_Database.Get(region.posX - (int)Constants.RegionSize - 1, region.posY - (int)Constants.RegionSize - 1,
142 region.posX + (int)Constants.RegionSize, region.posY + (int)Constants.RegionSize, scopeID); 287 region.posX + (int)Constants.RegionSize + 1, region.posY + (int)Constants.RegionSize + 1, scopeID);
143 288
144 foreach (RegionData rdata in rdatas) 289 foreach (RegionData rdata in rdatas)
290 {
145 if (rdata.RegionID != regionID) 291 if (rdata.RegionID != regionID)
146 rinfos.Add(RegionData2RegionInfo(rdata)); 292 {
293 int flags = Convert.ToInt32(rdata.Data["flags"]);
294 if ((flags & (int)Data.RegionFlags.Hyperlink) == 0) // no hyperlinks as neighbours
295 rinfos.Add(RegionData2RegionInfo(rdata));
296 }
297 }
147 298
299// m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighbours", region.RegionName, rinfos.Count);
148 } 300 }
301 else
302 {
303 m_log.WarnFormat(
304 "[GRID SERVICE]: GetNeighbours() called for scope {0}, region {1} but no such region found",
305 scopeID, regionID);
306 }
307
149 return rinfos; 308 return rinfos;
150 } 309 }
151 310
@@ -169,24 +328,34 @@ namespace OpenSim.Services.GridService
169 return null; 328 return null;
170 } 329 }
171 330
172 public GridRegion GetRegionByName(UUID scopeID, string regionName) 331 public GridRegion GetRegionByName(UUID scopeID, string name)
173 { 332 {
174 List<RegionData> rdatas = m_Database.Get(regionName + "%", scopeID); 333 List<RegionData> rdatas = m_Database.Get(name, scopeID);
175 if ((rdatas != null) && (rdatas.Count > 0)) 334 if ((rdatas != null) && (rdatas.Count > 0))
176 return RegionData2RegionInfo(rdatas[0]); // get the first 335 return RegionData2RegionInfo(rdatas[0]); // get the first
177 336
337 if (m_AllowHypergridMapSearch)
338 {
339 GridRegion r = GetHypergridRegionByName(scopeID, name);
340 if (r != null)
341 return r;
342 }
343
178 return null; 344 return null;
179 } 345 }
180 346
181 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber) 347 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
182 { 348 {
183 List<RegionData> rdatas = m_Database.Get("%" + name + "%", scopeID); 349// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name);
350
351 List<RegionData> rdatas = m_Database.Get(name + "%", scopeID);
184 352
185 int count = 0; 353 int count = 0;
186 List<GridRegion> rinfos = new List<GridRegion>(); 354 List<GridRegion> rinfos = new List<GridRegion>();
187 355
188 if (rdatas != null) 356 if (rdatas != null)
189 { 357 {
358// m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count);
190 foreach (RegionData rdata in rdatas) 359 foreach (RegionData rdata in rdatas)
191 { 360 {
192 if (count++ < maxNumber) 361 if (count++ < maxNumber)
@@ -194,9 +363,30 @@ namespace OpenSim.Services.GridService
194 } 363 }
195 } 364 }
196 365
366 if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0)))
367 {
368 GridRegion r = GetHypergridRegionByName(scopeID, name);
369 if (r != null)
370 rinfos.Add(r);
371 }
372
197 return rinfos; 373 return rinfos;
198 } 374 }
199 375
376 /// <summary>
377 /// Get a hypergrid region.
378 /// </summary>
379 /// <param name="scopeID"></param>
380 /// <param name="name"></param>
381 /// <returns>null if no hypergrid region could be found.</returns>
382 protected GridRegion GetHypergridRegionByName(UUID scopeID, string name)
383 {
384 if (name.Contains("."))
385 return m_HypergridLinker.LinkRegion(scopeID, name);
386 else
387 return null;
388 }
389
200 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) 390 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
201 { 391 {
202 int xminSnap = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize; 392 int xminSnap = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize;
@@ -216,7 +406,7 @@ namespace OpenSim.Services.GridService
216 406
217 #region Data structure conversions 407 #region Data structure conversions
218 408
219 protected RegionData RegionInfo2RegionData(GridRegion rinfo) 409 public RegionData RegionInfo2RegionData(GridRegion rinfo)
220 { 410 {
221 RegionData rdata = new RegionData(); 411 RegionData rdata = new RegionData();
222 rdata.posX = (int)rinfo.RegionLocX; 412 rdata.posX = (int)rinfo.RegionLocX;
@@ -229,7 +419,7 @@ namespace OpenSim.Services.GridService
229 return rdata; 419 return rdata;
230 } 420 }
231 421
232 protected GridRegion RegionData2RegionInfo(RegionData rdata) 422 public GridRegion RegionData2RegionInfo(RegionData rdata)
233 { 423 {
234 GridRegion rinfo = new GridRegion(rdata.Data); 424 GridRegion rinfo = new GridRegion(rdata.Data);
235 rinfo.RegionLocX = rdata.posX; 425 rinfo.RegionLocX = rdata.posX;
@@ -243,5 +433,160 @@ namespace OpenSim.Services.GridService
243 433
244 #endregion 434 #endregion
245 435
436 public List<GridRegion> GetDefaultRegions(UUID scopeID)
437 {
438 List<GridRegion> ret = new List<GridRegion>();
439
440 List<RegionData> regions = m_Database.GetDefaultRegions(scopeID);
441
442 foreach (RegionData r in regions)
443 {
444 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
445 ret.Add(RegionData2RegionInfo(r));
446 }
447
448 m_log.DebugFormat("[GRID SERVICE]: GetDefaultRegions returning {0} regions", ret.Count);
449 return ret;
450 }
451
452 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
453 {
454 List<GridRegion> ret = new List<GridRegion>();
455
456 List<RegionData> regions = m_Database.GetFallbackRegions(scopeID, x, y);
457
458 foreach (RegionData r in regions)
459 {
460 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
461 ret.Add(RegionData2RegionInfo(r));
462 }
463
464 m_log.DebugFormat("[GRID SERVICE]: Fallback returned {0} regions", ret.Count);
465 return ret;
466 }
467
468 public List<GridRegion> GetHyperlinks(UUID scopeID)
469 {
470 List<GridRegion> ret = new List<GridRegion>();
471
472 List<RegionData> regions = m_Database.GetHyperlinks(scopeID);
473
474 foreach (RegionData r in regions)
475 {
476 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
477 ret.Add(RegionData2RegionInfo(r));
478 }
479
480 m_log.DebugFormat("[GRID SERVICE]: Hyperlinks returned {0} regions", ret.Count);
481 return ret;
482 }
483
484 public int GetRegionFlags(UUID scopeID, UUID regionID)
485 {
486 RegionData region = m_Database.Get(regionID, scopeID);
487
488 if (region != null)
489 {
490 int flags = Convert.ToInt32(region.Data["flags"]);
491 //m_log.DebugFormat("[GRID SERVICE]: Request for flags of {0}: {1}", regionID, flags);
492 return flags;
493 }
494 else
495 return -1;
496 }
497
498 private void HandleShowRegion(string module, string[] cmd)
499 {
500 if (cmd.Length != 3)
501 {
502 MainConsole.Instance.Output("Syntax: show region <region name>");
503 return;
504 }
505 List<RegionData> regions = m_Database.Get(cmd[2], UUID.Zero);
506 if (regions == null || regions.Count < 1)
507 {
508 MainConsole.Instance.Output("Region not found");
509 return;
510 }
511
512 MainConsole.Instance.Output("Region Name Region UUID");
513 MainConsole.Instance.Output("Location URI");
514 MainConsole.Instance.Output("Owner ID Flags");
515 MainConsole.Instance.Output("-------------------------------------------------------------------------------");
516 foreach (RegionData r in regions)
517 {
518 OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]);
519 MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} {5}\n\n",
520 r.RegionName, r.RegionID,
521 String.Format("{0},{1}", r.posX / Constants.RegionSize, r.posY / Constants.RegionSize),
522 r.Data["serverURI"],
523 r.Data["owner_uuid"], flags));
524 }
525 return;
526 }
527
528 private int ParseFlags(int prev, string flags)
529 {
530 OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)prev;
531
532 string[] parts = flags.Split(new char[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
533
534 foreach (string p in parts)
535 {
536 int val;
537
538 try
539 {
540 if (p.StartsWith("+"))
541 {
542 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p.Substring(1));
543 f |= (OpenSim.Data.RegionFlags)val;
544 }
545 else if (p.StartsWith("-"))
546 {
547 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p.Substring(1));
548 f &= ~(OpenSim.Data.RegionFlags)val;
549 }
550 else
551 {
552 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p);
553 f |= (OpenSim.Data.RegionFlags)val;
554 }
555 }
556 catch (Exception)
557 {
558 MainConsole.Instance.Output("Error in flag specification: " + p);
559 }
560 }
561
562 return (int)f;
563 }
564
565 private void HandleSetFlags(string module, string[] cmd)
566 {
567 if (cmd.Length < 5)
568 {
569 MainConsole.Instance.Output("Syntax: set region flags <region name> <flags>");
570 return;
571 }
572
573 List<RegionData> regions = m_Database.Get(cmd[3], UUID.Zero);
574 if (regions == null || regions.Count < 1)
575 {
576 MainConsole.Instance.Output("Region not found");
577 return;
578 }
579
580 foreach (RegionData r in regions)
581 {
582 int flags = Convert.ToInt32(r.Data["flags"]);
583 flags = ParseFlags(flags, cmd[4]);
584 r.Data["flags"] = flags.ToString();
585 OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)flags;
586
587 MainConsole.Instance.Output(String.Format("Set region {0} to {1}", r.RegionName, f));
588 m_Database.Store(r);
589 }
590 }
246 } 591 }
247} 592}
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
new file mode 100644
index 0000000..b70b425
--- /dev/null
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -0,0 +1,724 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Linq;
33using System.Net;
34using System.Reflection;
35using System.Xml;
36
37using Nini.Config;
38using log4net;
39using OpenSim.Framework;
40using OpenSim.Framework.Console;
41using OpenSim.Data;
42using OpenSim.Server.Base;
43using OpenSim.Services.Interfaces;
44using OpenSim.Services.Connectors.Hypergrid;
45using GridRegion = OpenSim.Services.Interfaces.GridRegion;
46using OpenMetaverse;
47
48namespace OpenSim.Services.GridService
49{
50 public class HypergridLinker
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 private static uint m_autoMappingX = 0;
57 private static uint m_autoMappingY = 0;
58 private static bool m_enableAutoMapping = false;
59
60 protected IRegionData m_Database;
61 protected GridService m_GridService;
62 protected IAssetService m_AssetService;
63 protected GatekeeperServiceConnector m_GatekeeperConnector;
64
65 protected UUID m_ScopeID = UUID.Zero;
66// protected bool m_Check4096 = true;
67 protected string m_MapTileDirectory = string.Empty;
68 protected string m_ThisGatekeeper = string.Empty;
69 protected Uri m_ThisGatekeeperURI = null;
70
71 // Hyperlink regions are hyperlinks on the map
72 public readonly Dictionary<UUID, GridRegion> m_HyperlinkRegions = new Dictionary<UUID, GridRegion>();
73 protected Dictionary<UUID, ulong> m_HyperlinkHandles = new Dictionary<UUID, ulong>();
74
75 protected GridRegion m_DefaultRegion;
76 protected GridRegion DefaultRegion
77 {
78 get
79 {
80 if (m_DefaultRegion == null)
81 {
82 List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID);
83 if (defs != null && defs.Count > 0)
84 m_DefaultRegion = defs[0];
85 else
86 {
87 // Get any region
88 defs = m_GridService.GetRegionsByName(m_ScopeID, "", 1);
89 if (defs != null && defs.Count > 0)
90 m_DefaultRegion = defs[0];
91 else
92 {
93 // This shouldn't happen
94 m_DefaultRegion = new GridRegion(1000, 1000);
95 m_log.Error("[HYPERGRID LINKER]: Something is wrong with this grid. It has no regions?");
96 }
97 }
98 }
99 return m_DefaultRegion;
100 }
101 }
102
103 public HypergridLinker(IConfigSource config, GridService gridService, IRegionData db)
104 {
105 IConfig modulesConfig = config.Configs["Modules"];
106 if (modulesConfig == null)
107 return;
108
109 if (modulesConfig.GetString("HypergridLinker", "") != "HypergridLinker")
110 return;
111
112 m_log.DebugFormat("[HYPERGRID LINKER]: Starting with db {0}", db.GetType());
113
114 m_Database = db;
115 m_GridService = gridService;
116
117 IConfig gridConfig = config.Configs["GridService"];
118 if (gridConfig != null)
119 {
120 string assetService = gridConfig.GetString("AssetService", string.Empty);
121
122 Object[] args = new Object[] { config };
123
124 if (assetService != string.Empty)
125 m_AssetService = ServerUtils.LoadPlugin<IAssetService>(assetService, args);
126
127 string scope = gridConfig.GetString("ScopeID", string.Empty);
128 if (scope != string.Empty)
129 UUID.TryParse(scope, out m_ScopeID);
130
131// m_Check4096 = gridConfig.GetBoolean("Check4096", true);
132
133 m_MapTileDirectory = gridConfig.GetString("MapTileDirectory", "maptiles");
134
135 m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", string.Empty);
136 try
137 {
138 m_ThisGatekeeperURI = new Uri(m_ThisGatekeeper);
139 }
140 catch
141 {
142 m_log.WarnFormat("[HYPERGRID LINKER]: Malformed URL in [GridService], variable Gatekeeper = {0}", m_ThisGatekeeper);
143 }
144
145 m_GatekeeperConnector = new GatekeeperServiceConnector(m_AssetService);
146
147 m_log.Debug("[HYPERGRID LINKER]: Loaded all services...");
148 }
149
150 if (!string.IsNullOrEmpty(m_MapTileDirectory))
151 {
152 try
153 {
154 Directory.CreateDirectory(m_MapTileDirectory);
155 }
156 catch (Exception e)
157 {
158 m_log.WarnFormat("[HYPERGRID LINKER]: Could not create map tile storage directory {0}: {1}", m_MapTileDirectory, e);
159 m_MapTileDirectory = string.Empty;
160 }
161 }
162
163 if (MainConsole.Instance != null)
164 {
165 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region",
166 "link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]",
167 "Link a HyperGrid Region. Examples for <ServerURI>: http://grid.net:8002/ or http://example.org/path/foo.php", RunCommand);
168 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region",
169 "link-region <Xloc> <Yloc> <RegionIP> <RegionPort> [<RemoteRegionName>]",
170 "Link a hypergrid region (deprecated)", RunCommand);
171 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "unlink-region",
172 "unlink-region <local name>",
173 "Unlink a hypergrid region", RunCommand);
174 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-mapping", "link-mapping [<x> <y>]",
175 "Set local coordinate to map HG regions to", RunCommand);
176 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "show hyperlinks", "show hyperlinks",
177 "List the HG regions", HandleShow);
178 }
179 }
180
181
182 #region Link Region
183
184 public GridRegion LinkRegion(UUID scopeID, string regionDescriptor)
185 {
186 string reason = string.Empty;
187 int xloc = random.Next(0, Int16.MaxValue) * (int)Constants.RegionSize;
188 return TryLinkRegionToCoords(scopeID, regionDescriptor, xloc, 0, out reason);
189 }
190
191 private static Random random = new Random();
192
193 // From the command line link-region
194 public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason)
195 {
196 return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason);
197 }
198
199 public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason)
200 {
201 reason = string.Empty;
202 uint port = 0;
203 string[] parts = mapName.Split(new char[] {':'});
204 string regionName = String.Empty;
205 if (parts.Length > 1)
206 {
207 regionName = mapName.Substring(parts[0].Length + 1);
208 regionName = regionName.Trim(new char[] {'"'});
209 }
210 GridRegion regInfo;
211 if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, parts[0], ownerID, out regInfo, out reason))
212 {
213 regInfo.RegionName = mapName;
214 return regInfo;
215 }
216
217 return null;
218 }
219
220 public bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason)
221 {
222 return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason);
223 }
224
225 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)
226 {
227 m_log.DebugFormat("[HYPERGRID LINKER]: Link to {0}:{1}, in {2}-{3}",
228 ((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI),
229 remoteRegionName, xloc / Constants.RegionSize, yloc / Constants.RegionSize);
230
231 reason = string.Empty;
232 Uri uri = null;
233
234 regInfo = new GridRegion();
235 if ( externalPort > 0)
236 regInfo.HttpPort = externalPort;
237 else
238 regInfo.HttpPort = 0;
239 if ( externalHostName != null)
240 regInfo.ExternalHostName = externalHostName;
241 else
242 regInfo.ExternalHostName = "0.0.0.0";
243 if ( serverURI != null)
244 {
245 regInfo.ServerURI = serverURI;
246 try
247 {
248 uri = new Uri(serverURI);
249 regInfo.ExternalHostName = uri.Host;
250 regInfo.HttpPort = (uint)uri.Port;
251 }
252 catch {}
253 }
254
255 if ( remoteRegionName != string.Empty )
256 regInfo.RegionName = remoteRegionName;
257
258 regInfo.RegionLocX = xloc;
259 regInfo.RegionLocY = yloc;
260 regInfo.ScopeID = scopeID;
261 regInfo.EstateOwner = ownerID;
262
263 // Make sure we're not hyperlinking to regions on this grid!
264 if (m_ThisGatekeeperURI != null)
265 {
266 if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port)
267 {
268 reason = "Cannot hyperlink to regions on the same grid";
269 return false;
270 }
271 }
272 else
273 m_log.WarnFormat("[HYPERGRID LINKER]: Please set this grid's Gatekeeper's address in [GridService]!");
274
275 // Check for free coordinates
276 GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY);
277 if (region != null)
278 {
279 m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates {0}-{1} are already occupied by region {2} with uuid {3}",
280 regInfo.RegionLocX / Constants.RegionSize, regInfo.RegionLocY / Constants.RegionSize,
281 region.RegionName, region.RegionID);
282 reason = "Coordinates are already in use";
283 return false;
284 }
285
286 try
287 {
288 regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0);
289 }
290 catch (Exception e)
291 {
292 m_log.Warn("[HYPERGRID LINKER]: Wrong format for link-region: " + e.Message);
293 reason = "Internal error";
294 return false;
295 }
296
297 // Finally, link it
298 ulong handle = 0;
299 UUID regionID = UUID.Zero;
300 string externalName = string.Empty;
301 string imageURL = string.Empty;
302 if (!m_GatekeeperConnector.LinkRegion(regInfo, out regionID, out handle, out externalName, out imageURL, out reason))
303 return false;
304
305 if (regionID == UUID.Zero)
306 {
307 m_log.Warn("[HYPERGRID LINKER]: Unable to link region");
308 reason = "Remote region could not be found";
309 return false;
310 }
311
312 region = m_GridService.GetRegionByUUID(scopeID, regionID);
313 if (region != null)
314 {
315 m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates {0} {1}",
316 region.RegionLocX / Constants.RegionSize, region.RegionLocY / Constants.RegionSize);
317 regInfo = region;
318 return true;
319 }
320
321 // We are now performing this check for each individual teleport in the EntityTransferModule instead. This
322 // allows us to give better feedback when teleports fail because of the distance reason (which can't be
323 // done here) and it also hypergrid teleports that are within range (possibly because the source grid
324 // itself has regions that are very far apart).
325// uint x, y;
326// if (m_Check4096 && !Check4096(handle, out x, out y))
327// {
328// //RemoveHyperlinkRegion(regInfo.RegionID);
329// reason = "Region is too far (" + x + ", " + y + ")";
330// m_log.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")");
331// //return false;
332// }
333
334 regInfo.RegionID = regionID;
335
336 if (externalName == string.Empty)
337 regInfo.RegionName = regInfo.ServerURI;
338 else
339 regInfo.RegionName = externalName;
340
341 m_log.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString());
342
343 // Get the map image
344 regInfo.TerrainImage = GetMapImage(regionID, imageURL);
345
346 // Store the origin's coordinates somewhere
347 regInfo.RegionSecret = handle.ToString();
348
349 AddHyperlinkRegion(regInfo, handle);
350 m_log.Info("[HYPERGRID LINKER]: Successfully linked to region_uuid " + regInfo.RegionID);
351 return true;
352 }
353
354 public bool TryUnlinkRegion(string mapName)
355 {
356 m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName);
357 GridRegion regInfo = null;
358
359 List<RegionData> regions = m_Database.Get(mapName, m_ScopeID);
360 if (regions != null && regions.Count > 0)
361 {
362 OpenSim.Data.RegionFlags rflags = (OpenSim.Data.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]);
363 if ((rflags & OpenSim.Data.RegionFlags.Hyperlink) != 0)
364 {
365 regInfo = new GridRegion();
366 regInfo.RegionID = regions[0].RegionID;
367 regInfo.ScopeID = m_ScopeID;
368 }
369 }
370
371 if (regInfo != null)
372 {
373 RemoveHyperlinkRegion(regInfo.RegionID);
374 return true;
375 }
376 else
377 {
378 m_log.InfoFormat("[HYPERGRID LINKER]: Region {0} not found", mapName);
379 return false;
380 }
381 }
382
383// Not currently used
384// /// <summary>
385// /// Cope with this viewer limitation.
386// /// </summary>
387// /// <param name="regInfo"></param>
388// /// <returns></returns>
389// public bool Check4096(ulong realHandle, out uint x, out uint y)
390// {
391// uint ux = 0, uy = 0;
392// Utils.LongToUInts(realHandle, out ux, out uy);
393// x = ux / Constants.RegionSize;
394// y = uy / Constants.RegionSize;
395//
396// const uint limit = (4096 - 1) * Constants.RegionSize;
397// uint xmin = ux - limit;
398// uint xmax = ux + limit;
399// uint ymin = uy - limit;
400// uint ymax = uy + limit;
401// // World map boundary checks
402// if (xmin < 0 || xmin > ux)
403// xmin = 0;
404// if (xmax > int.MaxValue || xmax < ux)
405// xmax = int.MaxValue;
406// if (ymin < 0 || ymin > uy)
407// ymin = 0;
408// if (ymax > int.MaxValue || ymax < uy)
409// ymax = int.MaxValue;
410//
411// // Check for any regions that are within the possible teleport range to the linked region
412// List<GridRegion> regions = m_GridService.GetRegionRange(m_ScopeID, (int)xmin, (int)xmax, (int)ymin, (int)ymax);
413// if (regions.Count == 0)
414// {
415// return false;
416// }
417// else
418// {
419// // Check for regions which are not linked regions
420// List<GridRegion> hyperlinks = m_GridService.GetHyperlinks(m_ScopeID);
421// IEnumerable<GridRegion> availableRegions = regions.Except(hyperlinks);
422// if (availableRegions.Count() == 0)
423// return false;
424// }
425//
426// return true;
427// }
428
429 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle)
430 {
431 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo);
432 int flags = (int)OpenSim.Data.RegionFlags.Hyperlink + (int)OpenSim.Data.RegionFlags.NoDirectLogin + (int)OpenSim.Data.RegionFlags.RegionOnline;
433 rdata.Data["flags"] = flags.ToString();
434
435 m_Database.Store(rdata);
436 }
437
438 private void RemoveHyperlinkRegion(UUID regionID)
439 {
440 m_Database.Delete(regionID);
441 }
442
443 public UUID GetMapImage(UUID regionID, string imageURL)
444 {
445 return m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory);
446 }
447 #endregion
448
449
450 #region Console Commands
451
452 public void HandleShow(string module, string[] cmd)
453 {
454 if (cmd.Length != 2)
455 {
456 MainConsole.Instance.Output("Syntax: show hyperlinks");
457 return;
458 }
459 List<RegionData> regions = m_Database.GetHyperlinks(UUID.Zero);
460 if (regions == null || regions.Count < 1)
461 {
462 MainConsole.Instance.Output("No hyperlinks");
463 return;
464 }
465
466 MainConsole.Instance.Output("Region Name");
467 MainConsole.Instance.Output("Location Region UUID");
468 MainConsole.Instance.Output(new string('-', 72));
469 foreach (RegionData r in regions)
470 {
471 MainConsole.Instance.Output(String.Format("{0}\n{2,-32} {1}\n",
472 r.RegionName, r.RegionID, String.Format("{0},{1} ({2},{3})", r.posX, r.posY,
473 r.posX / Constants.RegionSize, r.posY / Constants.RegionSize)));
474 }
475 return;
476 }
477
478 public void RunCommand(string module, string[] cmdparams)
479 {
480 List<string> args = new List<string>(cmdparams);
481 if (args.Count < 1)
482 return;
483
484 string command = args[0];
485 args.RemoveAt(0);
486
487 cmdparams = args.ToArray();
488
489 RunHGCommand(command, cmdparams);
490
491 }
492
493 private void RunLinkRegionCommand(string[] cmdparams)
494 {
495 int xloc, yloc;
496 string serverURI;
497 string remoteName = null;
498 xloc = Convert.ToInt32(cmdparams[0]) * (int)Constants.RegionSize;
499 yloc = Convert.ToInt32(cmdparams[1]) * (int)Constants.RegionSize;
500 serverURI = cmdparams[2];
501 if (cmdparams.Length > 3)
502 remoteName = string.Join(" ", cmdparams, 3, cmdparams.Length - 3);
503 string reason = string.Empty;
504 GridRegion regInfo;
505 if (TryCreateLink(UUID.Zero, xloc, yloc, remoteName, 0, null, serverURI, UUID.Zero, out regInfo, out reason))
506 MainConsole.Instance.Output("Hyperlink established");
507 else
508 MainConsole.Instance.Output("Failed to link region: " + reason);
509 }
510
511 private void RunHGCommand(string command, string[] cmdparams)
512 {
513 if (command.Equals("link-mapping"))
514 {
515 if (cmdparams.Length == 2)
516 {
517 try
518 {
519 m_autoMappingX = Convert.ToUInt32(cmdparams[0]);
520 m_autoMappingY = Convert.ToUInt32(cmdparams[1]);
521 m_enableAutoMapping = true;
522 }
523 catch (Exception)
524 {
525 m_autoMappingX = 0;
526 m_autoMappingY = 0;
527 m_enableAutoMapping = false;
528 }
529 }
530 }
531 else if (command.Equals("link-region"))
532 {
533 if (cmdparams.Length < 3)
534 {
535 if ((cmdparams.Length == 1) || (cmdparams.Length == 2))
536 {
537 LoadXmlLinkFile(cmdparams);
538 }
539 else
540 {
541 LinkRegionCmdUsage();
542 }
543 return;
544 }
545
546 //this should be the prefererred way of setting up hg links now
547 if (cmdparams[2].StartsWith("http"))
548 {
549 RunLinkRegionCommand(cmdparams);
550 }
551 else if (cmdparams[2].Contains(":"))
552 {
553 // New format
554 string[] parts = cmdparams[2].Split(':');
555 if (parts.Length > 2)
556 {
557 // Insert remote region name
558 ArrayList parameters = new ArrayList(cmdparams);
559 parameters.Insert(3, parts[2]);
560 cmdparams = (string[])parameters.ToArray(typeof(string));
561 }
562 cmdparams[2] = "http://" + parts[0] + ':' + parts[1];
563
564 RunLinkRegionCommand(cmdparams);
565 }
566 else
567 {
568 // old format
569 GridRegion regInfo;
570 int xloc, yloc;
571 uint externalPort;
572 string externalHostName;
573 try
574 {
575 xloc = Convert.ToInt32(cmdparams[0]);
576 yloc = Convert.ToInt32(cmdparams[1]);
577 externalPort = Convert.ToUInt32(cmdparams[3]);
578 externalHostName = cmdparams[2];
579 //internalPort = Convert.ToUInt32(cmdparams[4]);
580 //remotingPort = Convert.ToUInt32(cmdparams[5]);
581 }
582 catch (Exception e)
583 {
584 MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message);
585 LinkRegionCmdUsage();
586 return;
587 }
588
589 // Convert cell coordinates given by the user to meters
590 xloc = xloc * (int)Constants.RegionSize;
591 yloc = yloc * (int)Constants.RegionSize;
592 string reason = string.Empty;
593 if (TryCreateLink(UUID.Zero, xloc, yloc, string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
594 {
595 // What is this? The GridRegion instance will be discarded anyway,
596 // which effectively ignores any local name given with the command.
597 //if (cmdparams.Length >= 5)
598 //{
599 // regInfo.RegionName = "";
600 // for (int i = 4; i < cmdparams.Length; i++)
601 // regInfo.RegionName += cmdparams[i] + " ";
602 //}
603 }
604 }
605 return;
606 }
607 else if (command.Equals("unlink-region"))
608 {
609 if (cmdparams.Length < 1)
610 {
611 UnlinkRegionCmdUsage();
612 return;
613 }
614 string region = string.Join(" ", cmdparams);
615 if (TryUnlinkRegion(region))
616 MainConsole.Instance.Output("Successfully unlinked " + region);
617 else
618 MainConsole.Instance.Output("Unable to unlink " + region + ", region not found.");
619 }
620 }
621
622 private void LoadXmlLinkFile(string[] cmdparams)
623 {
624 //use http://www.hgurl.com/hypergrid.xml for test
625 try
626 {
627 XmlReader r = XmlReader.Create(cmdparams[0]);
628 XmlConfigSource cs = new XmlConfigSource(r);
629 string[] excludeSections = null;
630
631 if (cmdparams.Length == 2)
632 {
633 if (cmdparams[1].ToLower().StartsWith("excludelist:"))
634 {
635 string excludeString = cmdparams[1].ToLower();
636 excludeString = excludeString.Remove(0, 12);
637 char[] splitter = { ';' };
638
639 excludeSections = excludeString.Split(splitter);
640 }
641 }
642
643 for (int i = 0; i < cs.Configs.Count; i++)
644 {
645 bool skip = false;
646 if ((excludeSections != null) && (excludeSections.Length > 0))
647 {
648 for (int n = 0; n < excludeSections.Length; n++)
649 {
650 if (excludeSections[n] == cs.Configs[i].Name.ToLower())
651 {
652 skip = true;
653 break;
654 }
655 }
656 }
657 if (!skip)
658 {
659 ReadLinkFromConfig(cs.Configs[i]);
660 }
661 }
662 }
663 catch (Exception e)
664 {
665 m_log.Error(e.ToString());
666 }
667 }
668
669
670 private void ReadLinkFromConfig(IConfig config)
671 {
672 GridRegion regInfo;
673 int xloc, yloc;
674 uint externalPort;
675 string externalHostName;
676 uint realXLoc, realYLoc;
677
678 xloc = Convert.ToInt32(config.GetString("xloc", "0"));
679 yloc = Convert.ToInt32(config.GetString("yloc", "0"));
680 externalPort = Convert.ToUInt32(config.GetString("externalPort", "0"));
681 externalHostName = config.GetString("externalHostName", "");
682 realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0"));
683 realYLoc = Convert.ToUInt32(config.GetString("real-yloc", "0"));
684
685 if (m_enableAutoMapping)
686 {
687 xloc = (int)((xloc % 100) + m_autoMappingX);
688 yloc = (int)((yloc % 100) + m_autoMappingY);
689 }
690
691 if (((realXLoc == 0) && (realYLoc == 0)) ||
692 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) &&
693 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896))))
694 {
695 xloc = xloc * (int)Constants.RegionSize;
696 yloc = yloc * (int)Constants.RegionSize;
697 string reason = string.Empty;
698 if (TryCreateLink(UUID.Zero, xloc, yloc, string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
699 {
700 regInfo.RegionName = config.GetString("localName", "");
701 }
702 else
703 MainConsole.Instance.Output("Unable to link " + externalHostName + ": " + reason);
704 }
705 }
706
707
708 private void LinkRegionCmdUsage()
709 {
710 MainConsole.Instance.Output("Usage: link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]");
711 MainConsole.Instance.Output("Usage (deprecated): link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>]");
712 MainConsole.Instance.Output("Usage (deprecated): link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]");
713 MainConsole.Instance.Output("Usage: link-region <URI_of_xml> [<exclude>]");
714 }
715
716 private void UnlinkRegionCmdUsage()
717 {
718 MainConsole.Instance.Output("Usage: unlink-region <LocalName>");
719 }
720
721 #endregion
722
723 }
724}