aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/GridService/GridService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/GridService/GridService.cs')
-rw-r--r--OpenSim/Services/GridService/GridService.cs365
1 files changed, 355 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}