clockwerk-opensim-stable – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections.Generic;
30 using System.Net;
31 using System.Reflection;
32 using Nini.Config;
33 using log4net;
34 using OpenSim.Framework;
35 using OpenSim.Framework.Console;
36 using OpenSim.Data;
37 using OpenSim.Server.Base;
38 using OpenSim.Services.Interfaces;
39 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
40 using OpenMetaverse;
41  
42 namespace OpenSim.Services.GridService
43 {
44 public class GridService : GridServiceBase, IGridService
45 {
46 private static readonly ILog m_log =
47 LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType);
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;
56 protected bool m_AllowDuplicateNames = false;
57 protected bool m_AllowHypergridMapSearch = false;
58  
59 public GridService(IConfigSource config)
60 : base(config)
61 {
62 m_log.DebugFormat("[GRID SERVICE]: Starting...");
63  
64 m_config = config;
65 IConfig gridConfig = config.Configs["GridService"];
66 if (gridConfig != null)
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 }
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("Regions", true,
88 "deregister region id",
89 "deregister region id <region-id>+",
90 "Deregister a region manually.",
91 String.Empty,
92 HandleDeregisterRegion);
93  
94 // A messy way of stopping this command being added if we are in standalone (since the simulator
95 // has an identically named command
96 //
97 // XXX: We're relying on the OpenSimulator version being registered first, which is not well defined.
98 if (MainConsole.Instance.Commands.Resolve(new string[] { "show", "regions" }).Length == 0)
99 MainConsole.Instance.Commands.AddCommand("Regions", true,
100 "show regions",
101 "show regions",
102 "Show details on all regions",
103 String.Empty,
104 HandleShowRegions);
105  
106 MainConsole.Instance.Commands.AddCommand("Regions", true,
107 "show region name",
108 "show region name <Region name>",
109 "Show details on a region",
110 String.Empty,
111 HandleShowRegion);
112  
113 MainConsole.Instance.Commands.AddCommand("Regions", true,
114 "show region at",
115 "show region at <x-coord> <y-coord>",
116 "Show details on a region at the given co-ordinate.",
117 "For example, show region at 1000 1000",
118 HandleShowRegionAt);
119  
120 MainConsole.Instance.Commands.AddCommand("Regions", true,
121 "set region flags",
122 "set region flags <Region name> <flags>",
123 "Set database flags for region",
124 String.Empty,
125 HandleSetFlags);
126 }
127 m_HypergridLinker = new HypergridLinker(m_config, this, m_Database);
128 }
129 }
130  
131 #region IGridService
132  
133 public string RegisterRegion(UUID scopeID, GridRegion regionInfos)
134 {
135 IConfig gridConfig = m_config.Configs["GridService"];
136  
137 if (regionInfos.RegionID == UUID.Zero)
138 return "Invalid RegionID - cannot be zero UUID";
139  
140 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
141 if ((region != null) && (region.RegionID != regionInfos.RegionID))
142 {
143 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
144 regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
145 return "Region overlaps another region";
146 }
147  
148 if (region != null)
149 {
150 // There is a preexisting record
151 //
152 // Get it's flags
153 //
154 OpenSim.Framework.RegionFlags rflags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(region.Data["flags"]);
155  
156 // Is this a reservation?
157 //
158 if ((rflags & OpenSim.Framework.RegionFlags.Reservation) != 0)
159 {
160 // Regions reserved for the null key cannot be taken.
161 if ((string)region.Data["PrincipalID"] == UUID.Zero.ToString())
162 return "Region location is reserved";
163  
164 // Treat it as an auth request
165 //
166 // NOTE: Fudging the flags value here, so these flags
167 // should not be used elsewhere. Don't optimize
168 // this with the later retrieval of the same flags!
169 rflags |= OpenSim.Framework.RegionFlags.Authenticate;
170 }
171  
172 if ((rflags & OpenSim.Framework.RegionFlags.Authenticate) != 0)
173 {
174 // Can we authenticate at all?
175 //
176 if (m_AuthenticationService == null)
177 return "No authentication possible";
178  
179 if (!m_AuthenticationService.Verify(new UUID(region.Data["PrincipalID"].ToString()), regionInfos.Token, 30))
180 return "Bad authentication";
181 }
182 }
183  
184 // If we get here, the destination is clear. Now for the real check.
185  
186 if (!m_AllowDuplicateNames)
187 {
188 List<RegionData> dupe = m_Database.Get(Util.EscapeForLike(regionInfos.RegionName), scopeID);
189 if (dupe != null && dupe.Count > 0)
190 {
191 foreach (RegionData d in dupe)
192 {
193 if (d.RegionID != regionInfos.RegionID)
194 {
195 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, d.RegionName, d.RegionID);
197 return "Duplicate region name";
198 }
199 }
200 }
201 }
202  
203 // If there is an old record for us, delete it if it is elsewhere.
204 region = m_Database.Get(regionInfos.RegionID, scopeID);
205 if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
206 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
207 {
208 if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.NoMove) != 0)
209 return "Can't move this region";
210  
211 if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.LockedOut) != 0)
212 return "Region locked out";
213  
214 // Region reregistering in other coordinates. Delete the old entry
215 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
216 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
217  
218 try
219 {
220 m_Database.Delete(regionInfos.RegionID);
221 }
222 catch (Exception e)
223 {
224 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
225 }
226 }
227  
228 // Everything is ok, let's register
229 RegionData rdata = RegionInfo2RegionData(regionInfos);
230 rdata.ScopeID = scopeID;
231  
232 if (region != null)
233 {
234 int oldFlags = Convert.ToInt32(region.Data["flags"]);
235  
236 oldFlags &= ~(int)OpenSim.Framework.RegionFlags.Reservation;
237  
238 rdata.Data["flags"] = oldFlags.ToString(); // Preserve flags
239 }
240 else
241 {
242 rdata.Data["flags"] = "0";
243 if ((gridConfig != null) && rdata.RegionName != string.Empty)
244 {
245 int newFlags = 0;
246 string regionName = rdata.RegionName.Trim().Replace(' ', '_');
247 newFlags = ParseFlags(newFlags, gridConfig.GetString("DefaultRegionFlags", String.Empty));
248 newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + regionName, String.Empty));
249 newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + rdata.RegionID.ToString(), String.Empty));
250 rdata.Data["flags"] = newFlags.ToString();
251 }
252 }
253  
254 int flags = Convert.ToInt32(rdata.Data["flags"]);
255 flags |= (int)OpenSim.Framework.RegionFlags.RegionOnline;
256 rdata.Data["flags"] = flags.ToString();
257  
258 try
259 {
260 rdata.Data["last_seen"] = Util.UnixTimeSinceEpoch();
261 m_Database.Store(rdata);
262 }
263 catch (Exception e)
264 {
265 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
266 }
267  
268 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3} with flags {4}",
269 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY,
270 (OpenSim.Framework.RegionFlags)flags);
271  
272 return String.Empty;
273 }
274  
275 public bool DeregisterRegion(UUID regionID)
276 {
277 RegionData region = m_Database.Get(regionID, UUID.Zero);
278 if (region == null)
279 return false;
280  
281 m_log.DebugFormat(
282 "[GRID SERVICE]: Deregistering region {0} ({1}) at {2}-{3}",
283 region.RegionName, region.RegionID, region.coordX, region.coordY);
284  
285 int flags = Convert.ToInt32(region.Data["flags"]);
286  
287 if (!m_DeleteOnUnregister || (flags & (int)OpenSim.Framework.RegionFlags.Persistent) != 0)
288 {
289 flags &= ~(int)OpenSim.Framework.RegionFlags.RegionOnline;
290 region.Data["flags"] = flags.ToString();
291 region.Data["last_seen"] = Util.UnixTimeSinceEpoch();
292 try
293 {
294 m_Database.Store(region);
295 }
296 catch (Exception e)
297 {
298 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
299 }
300  
301 return true;
302  
303 }
304  
305 return m_Database.Delete(regionID);
306 }
307  
308 public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID)
309 {
310 List<GridRegion> rinfos = new List<GridRegion>();
311 RegionData region = m_Database.Get(regionID, scopeID);
312  
313 if (region != null)
314 {
315 // Not really? Maybe?
316 List<RegionData> rdatas = m_Database.Get(region.posX - (int)Constants.RegionSize - 1, region.posY - (int)Constants.RegionSize - 1,
317 region.posX + (int)Constants.RegionSize + 1, region.posY + (int)Constants.RegionSize + 1, scopeID);
318  
319 foreach (RegionData rdata in rdatas)
320 {
321 if (rdata.RegionID != regionID)
322 {
323 int flags = Convert.ToInt32(rdata.Data["flags"]);
324 if ((flags & (int)Framework.RegionFlags.Hyperlink) == 0) // no hyperlinks as neighbours
325 rinfos.Add(RegionData2RegionInfo(rdata));
326 }
327 }
328  
329 // m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighbours", region.RegionName, rinfos.Count);
330 }
331 else
332 {
333 m_log.WarnFormat(
334 "[GRID SERVICE]: GetNeighbours() called for scope {0}, region {1} but no such region found",
335 scopeID, regionID);
336 }
337  
338 return rinfos;
339 }
340  
341 public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
342 {
343 RegionData rdata = m_Database.Get(regionID, scopeID);
344 if (rdata != null)
345 return RegionData2RegionInfo(rdata);
346  
347 return null;
348 }
349  
350 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
351 {
352 int snapX = (int)(x / Constants.RegionSize) * (int)Constants.RegionSize;
353 int snapY = (int)(y / Constants.RegionSize) * (int)Constants.RegionSize;
354 RegionData rdata = m_Database.Get(snapX, snapY, scopeID);
355 if (rdata != null)
356 return RegionData2RegionInfo(rdata);
357  
358 return null;
359 }
360  
361 public GridRegion GetRegionByName(UUID scopeID, string name)
362 {
363 List<RegionData> rdatas = m_Database.Get(Util.EscapeForLike(name), scopeID);
364 if ((rdatas != null) && (rdatas.Count > 0))
365 return RegionData2RegionInfo(rdatas[0]); // get the first
366  
367 if (m_AllowHypergridMapSearch)
368 {
369 GridRegion r = GetHypergridRegionByName(scopeID, name);
370 if (r != null)
371 return r;
372 }
373  
374 return null;
375 }
376  
377 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
378 {
379 // m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name);
380  
381 List<RegionData> rdatas = m_Database.Get(Util.EscapeForLike(name) + "%", scopeID);
382  
383 int count = 0;
384 List<GridRegion> rinfos = new List<GridRegion>();
385  
386 if (rdatas != null)
387 {
388 // m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count);
389 foreach (RegionData rdata in rdatas)
390 {
391 if (count++ < maxNumber)
392 rinfos.Add(RegionData2RegionInfo(rdata));
393 }
394 }
395  
396 if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0)))
397 {
398 GridRegion r = GetHypergridRegionByName(scopeID, name);
399 if (r != null)
400 rinfos.Add(r);
401 }
402  
403 return rinfos;
404 }
405  
406 /// <summary>
407 /// Get a hypergrid region.
408 /// </summary>
409 /// <param name="scopeID"></param>
410 /// <param name="name"></param>
411 /// <returns>null if no hypergrid region could be found.</returns>
412 protected GridRegion GetHypergridRegionByName(UUID scopeID, string name)
413 {
414 if (name.Contains("."))
415 return m_HypergridLinker.LinkRegion(scopeID, name);
416 else
417 return null;
418 }
419  
420 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
421 {
422 int xminSnap = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize;
423 int xmaxSnap = (int)(xmax / Constants.RegionSize) * (int)Constants.RegionSize;
424 int yminSnap = (int)(ymin / Constants.RegionSize) * (int)Constants.RegionSize;
425 int ymaxSnap = (int)(ymax / Constants.RegionSize) * (int)Constants.RegionSize;
426  
427 List<RegionData> rdatas = m_Database.Get(xminSnap, yminSnap, xmaxSnap, ymaxSnap, scopeID);
428 List<GridRegion> rinfos = new List<GridRegion>();
429 foreach (RegionData rdata in rdatas)
430 rinfos.Add(RegionData2RegionInfo(rdata));
431  
432 return rinfos;
433 }
434  
435 #endregion
436  
437 #region Data structure conversions
438  
439 public RegionData RegionInfo2RegionData(GridRegion rinfo)
440 {
441 RegionData rdata = new RegionData();
442 rdata.posX = (int)rinfo.RegionLocX;
443 rdata.posY = (int)rinfo.RegionLocY;
444 rdata.RegionID = rinfo.RegionID;
445 rdata.RegionName = rinfo.RegionName;
446 rdata.Data = rinfo.ToKeyValuePairs();
447 rdata.Data["regionHandle"] = Utils.UIntsToLong((uint)rdata.posX, (uint)rdata.posY);
448 rdata.Data["owner_uuid"] = rinfo.EstateOwner.ToString();
449 return rdata;
450 }
451  
452 public GridRegion RegionData2RegionInfo(RegionData rdata)
453 {
454 GridRegion rinfo = new GridRegion(rdata.Data);
455 rinfo.RegionLocX = rdata.posX;
456 rinfo.RegionLocY = rdata.posY;
457 rinfo.RegionID = rdata.RegionID;
458 rinfo.RegionName = rdata.RegionName;
459 rinfo.ScopeID = rdata.ScopeID;
460  
461 return rinfo;
462 }
463  
464 #endregion
465  
466 public List<GridRegion> GetDefaultRegions(UUID scopeID)
467 {
468 List<GridRegion> ret = new List<GridRegion>();
469  
470 List<RegionData> regions = m_Database.GetDefaultRegions(scopeID);
471  
472 foreach (RegionData r in regions)
473 {
474 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0)
475 ret.Add(RegionData2RegionInfo(r));
476 }
477  
478 m_log.DebugFormat("[GRID SERVICE]: GetDefaultRegions returning {0} regions", ret.Count);
479 return ret;
480 }
481  
482 public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
483 {
484 List<GridRegion> ret = new List<GridRegion>();
485  
486 List<RegionData> regions = m_Database.GetDefaultHypergridRegions(scopeID);
487  
488 foreach (RegionData r in regions)
489 {
490 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0)
491 ret.Add(RegionData2RegionInfo(r));
492 }
493  
494 int hgDefaultRegionsFoundOnline = regions.Count;
495  
496 // For now, hypergrid default regions will always be given precedence but we will also return simple default
497 // regions in case no specific hypergrid regions are specified.
498 ret.AddRange(GetDefaultRegions(scopeID));
499  
500 int normalDefaultRegionsFoundOnline = ret.Count - hgDefaultRegionsFoundOnline;
501  
502 m_log.DebugFormat(
503 "[GRID SERVICE]: GetDefaultHypergridRegions returning {0} hypergrid default and {1} normal default regions",
504 hgDefaultRegionsFoundOnline, normalDefaultRegionsFoundOnline);
505  
506 return ret;
507 }
508  
509 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
510 {
511 List<GridRegion> ret = new List<GridRegion>();
512  
513 List<RegionData> regions = m_Database.GetFallbackRegions(scopeID, x, y);
514  
515 foreach (RegionData r in regions)
516 {
517 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0)
518 ret.Add(RegionData2RegionInfo(r));
519 }
520  
521 m_log.DebugFormat("[GRID SERVICE]: Fallback returned {0} regions", ret.Count);
522 return ret;
523 }
524  
525 public List<GridRegion> GetHyperlinks(UUID scopeID)
526 {
527 List<GridRegion> ret = new List<GridRegion>();
528  
529 List<RegionData> regions = m_Database.GetHyperlinks(scopeID);
530  
531 foreach (RegionData r in regions)
532 {
533 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0)
534 ret.Add(RegionData2RegionInfo(r));
535 }
536  
537 m_log.DebugFormat("[GRID SERVICE]: Hyperlinks returned {0} regions", ret.Count);
538 return ret;
539 }
540  
541 public int GetRegionFlags(UUID scopeID, UUID regionID)
542 {
543 RegionData region = m_Database.Get(regionID, scopeID);
544  
545 if (region != null)
546 {
547 int flags = Convert.ToInt32(region.Data["flags"]);
548 //m_log.DebugFormat("[GRID SERVICE]: Request for flags of {0}: {1}", regionID, flags);
549 return flags;
550 }
551 else
552 return -1;
553 }
554  
555 private void HandleDeregisterRegion(string module, string[] cmd)
556 {
557 if (cmd.Length < 4)
558 {
559 MainConsole.Instance.Output("Usage: degregister region id <region-id>+");
560 return;
561 }
562  
563 for (int i = 3; i < cmd.Length; i++)
564 {
565 string rawRegionUuid = cmd[i];
566 UUID regionUuid;
567  
568 if (!UUID.TryParse(rawRegionUuid, out regionUuid))
569 {
570 MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid);
571 return;
572 }
573  
574 GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid);
575  
576 if (region == null)
577 {
578 MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid);
579 return;
580 }
581  
582 if (DeregisterRegion(regionUuid))
583 {
584 MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid);
585 }
586 else
587 {
588 // I don't think this can ever occur if we know that the region exists.
589 MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid);
590 }
591 }
592 }
593  
594 private void HandleShowRegions(string module, string[] cmd)
595 {
596 if (cmd.Length != 2)
597 {
598 MainConsole.Instance.Output("Syntax: show regions");
599 return;
600 }
601  
602 List<RegionData> regions = m_Database.Get(int.MinValue, int.MinValue, int.MaxValue, int.MaxValue, UUID.Zero);
603  
604 OutputRegionsToConsoleSummary(regions);
605 }
606  
607  
608 private void HandleShowRegion(string module, string[] cmd)
609 {
610 if (cmd.Length != 4)
611 {
612 MainConsole.Instance.Output("Syntax: show region name <region name>");
613 return;
614 }
615  
616 string regionName = cmd[3];
617  
618 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(regionName), UUID.Zero);
619 if (regions == null || regions.Count < 1)
620 {
621 MainConsole.Instance.Output("No region with name {0} found", regionName);
622 return;
623 }
624  
625 OutputRegionsToConsole(regions);
626 }
627  
628 private void HandleShowRegionAt(string module, string[] cmd)
629 {
630 if (cmd.Length != 5)
631 {
632 MainConsole.Instance.Output("Syntax: show region at <x-coord> <y-coord>");
633 return;
634 }
635  
636 int x, y;
637 if (!int.TryParse(cmd[3], out x))
638 {
639 MainConsole.Instance.Output("x-coord must be an integer");
640 return;
641 }
642  
643 if (!int.TryParse(cmd[4], out y))
644 {
645 MainConsole.Instance.Output("y-coord must be an integer");
646 return;
647 }
648  
649 RegionData region = m_Database.Get(x * (int)Constants.RegionSize, y * (int)Constants.RegionSize, UUID.Zero);
650 if (region == null)
651 {
652 MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y);
653 return;
654 }
655  
656 OutputRegionToConsole(region);
657 }
658  
659 private void OutputRegionToConsole(RegionData r)
660 {
661 OpenSim.Framework.RegionFlags flags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(r.Data["flags"]);
662  
663 ConsoleDisplayList dispList = new ConsoleDisplayList();
664 dispList.AddRow("Region Name", r.RegionName);
665 dispList.AddRow("Region ID", r.RegionID);
666 dispList.AddRow("Location", string.Format("{0},{1}", r.coordX, r.coordY));
667 dispList.AddRow("URI", r.Data["serverURI"]);
668 dispList.AddRow("Owner ID", r.Data["owner_uuid"]);
669 dispList.AddRow("Flags", flags);
670  
671 MainConsole.Instance.Output(dispList.ToString());
672 }
673  
674 private void OutputRegionsToConsole(List<RegionData> regions)
675 {
676 foreach (RegionData r in regions)
677 OutputRegionToConsole(r);
678 }
679  
680 private void OutputRegionsToConsoleSummary(List<RegionData> regions)
681 {
682 ConsoleDisplayTable dispTable = new ConsoleDisplayTable();
683 dispTable.AddColumn("Name", 16);
684 dispTable.AddColumn("ID", 36);
685 dispTable.AddColumn("Position", 11);
686 dispTable.AddColumn("Owner ID", 36);
687 dispTable.AddColumn("Flags", 60);
688  
689 foreach (RegionData r in regions)
690 {
691 OpenSim.Framework.RegionFlags flags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(r.Data["flags"]);
692 dispTable.AddRow(
693 r.RegionName,
694 r.RegionID.ToString(),
695 string.Format("{0},{1}", r.coordX, r.coordY),
696 r.Data["owner_uuid"].ToString(),
697 flags.ToString());
698 }
699  
700 MainConsole.Instance.Output(dispTable.ToString());
701 }
702  
703 private int ParseFlags(int prev, string flags)
704 {
705 OpenSim.Framework.RegionFlags f = (OpenSim.Framework.RegionFlags)prev;
706  
707 string[] parts = flags.Split(new char[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
708  
709 foreach (string p in parts)
710 {
711 int val;
712  
713 try
714 {
715 if (p.StartsWith("+"))
716 {
717 val = (int)Enum.Parse(typeof(OpenSim.Framework.RegionFlags), p.Substring(1));
718 f |= (OpenSim.Framework.RegionFlags)val;
719 }
720 else if (p.StartsWith("-"))
721 {
722 val = (int)Enum.Parse(typeof(OpenSim.Framework.RegionFlags), p.Substring(1));
723 f &= ~(OpenSim.Framework.RegionFlags)val;
724 }
725 else
726 {
727 val = (int)Enum.Parse(typeof(OpenSim.Framework.RegionFlags), p);
728 f |= (OpenSim.Framework.RegionFlags)val;
729 }
730 }
731 catch (Exception)
732 {
733 MainConsole.Instance.Output("Error in flag specification: " + p);
734 }
735 }
736  
737 return (int)f;
738 }
739  
740 private void HandleSetFlags(string module, string[] cmd)
741 {
742 if (cmd.Length < 5)
743 {
744 MainConsole.Instance.Output("Syntax: set region flags <region name> <flags>");
745 return;
746 }
747  
748 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(cmd[3]), UUID.Zero);
749 if (regions == null || regions.Count < 1)
750 {
751 MainConsole.Instance.Output("Region not found");
752 return;
753 }
754  
755 foreach (RegionData r in regions)
756 {
757 int flags = Convert.ToInt32(r.Data["flags"]);
758 flags = ParseFlags(flags, cmd[4]);
759 r.Data["flags"] = flags.ToString();
760 OpenSim.Framework.RegionFlags f = (OpenSim.Framework.RegionFlags)flags;
761  
762 MainConsole.Instance.Output(String.Format("Set region {0} to {1}", r.RegionName, f));
763 m_Database.Store(r);
764 }
765 }
766 }
767 }