OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
HypergridLinker.cs
Go to the documentation of this file.
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;
30 using System.Collections.Generic;
31 using System.IO;
32 using System.Linq;
33 using System.Net;
34 using System.Reflection;
35 using System.Xml;
36 
37 using Nini.Config;
38 using log4net;
39 using OpenSim.Framework;
40 using OpenSim.Framework.Console;
41 using OpenSim.Data;
42 using OpenSim.Server.Base;
43 using OpenSim.Services.Interfaces;
44 using OpenSim.Services.Connectors.Hypergrid;
46 using OpenMetaverse;
47 
48 namespace OpenSim.Services.GridService
49 {
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 
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 
72  protected GridRegion DefaultRegion
73  {
74  get
75  {
76  if (m_DefaultRegion == null)
77  {
78  List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
79  if (defs != null && defs.Count > 0)
80  m_DefaultRegion = defs[0];
81  else
82  {
83  // Get any region
84  defs = m_GridService.GetRegionsByName(m_ScopeID, "", 1);
85  if (defs != null && defs.Count > 0)
86  m_DefaultRegion = defs[0];
87  else
88  {
89  // This shouldn't happen
90  m_DefaultRegion = new GridRegion(1000, 1000);
91  m_log.Error("[HYPERGRID LINKER]: Something is wrong with this grid. It has no regions?");
92  }
93  }
94  }
95  return m_DefaultRegion;
96  }
97  }
98 
99  public HypergridLinker(IConfigSource config, GridService gridService, IRegionData db)
100  {
101  IConfig gridConfig = config.Configs["GridService"];
102  if (gridConfig == null)
103  return;
104 
105  if (!gridConfig.GetBoolean("HypergridLinker", false))
106  return;
107 
108  m_Database = db;
109  m_GridService = gridService;
110  m_log.DebugFormat("[HYPERGRID LINKER]: Starting with db {0}", db.GetType());
111 
112  string assetService = gridConfig.GetString("AssetService", string.Empty);
113 
114  Object[] args = new Object[] { config };
115 
116  if (assetService != string.Empty)
117  m_AssetService = ServerUtils.LoadPlugin<IAssetService>(assetService, args);
118 
119  string scope = gridConfig.GetString("ScopeID", string.Empty);
120  if (scope != string.Empty)
121  UUID.TryParse(scope, out m_ScopeID);
122 
123 // m_Check4096 = gridConfig.GetBoolean("Check4096", true);
124 
125  m_MapTileDirectory = gridConfig.GetString("MapTileDirectory", "maptiles");
126 
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);
131  try
132  {
133  m_ThisGatekeeperURI = new Uri(m_ThisGatekeeper);
134  }
135  catch
136  {
137  m_log.WarnFormat("[HYPERGRID LINKER]: Malformed URL in [GridService], variable Gatekeeper = {0}", m_ThisGatekeeper);
138  }
139 
140  m_GatekeeperConnector = new GatekeeperServiceConnector(m_AssetService);
141 
142  m_log.Debug("[HYPERGRID LINKER]: Loaded all services...");
143 
144  if (!string.IsNullOrEmpty(m_MapTileDirectory))
145  {
146  try
147  {
148  Directory.CreateDirectory(m_MapTileDirectory);
149  }
150  catch (Exception e)
151  {
152  m_log.WarnFormat("[HYPERGRID LINKER]: Could not create map tile storage directory {0}: {1}", m_MapTileDirectory, e);
153  m_MapTileDirectory = string.Empty;
154  }
155  }
156 
157  if (MainConsole.Instance != null)
158  {
159  MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-region",
160  "link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]",
161  "Link a HyperGrid Region. Examples for <ServerURI>: http://grid.net:8002/ or http://example.org/path/foo.php", RunCommand);
162  MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-region",
163  "link-region <Xloc> <Yloc> <RegionIP> <RegionPort> [<RemoteRegionName>]",
164  "Link a hypergrid region (deprecated)", RunCommand);
165  MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "unlink-region",
166  "unlink-region <local name>",
167  "Unlink a hypergrid region", RunCommand);
168  MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-mapping", "link-mapping [<x> <y>]",
169  "Set local coordinate to map HG regions to", RunCommand);
170  MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "show hyperlinks", "show hyperlinks",
171  "List the HG regions", HandleShow);
172  }
173  }
174 
175 
176  #region Link Region
177 
178  // from map search
179  public GridRegion LinkRegion(UUID scopeID, string regionDescriptor)
180  {
181  string reason = string.Empty;
182  uint xloc = Util.RegionToWorldLoc((uint)random.Next(0, Int16.MaxValue));
183  return TryLinkRegionToCoords(scopeID, regionDescriptor, (int)xloc, 0, out reason);
184  }
185 
186  private static Random random = new Random();
187 
188  // From the command line link-region (obsolete) and the map
189  private GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason)
190  {
191  return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason);
192  }
193 
194  public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason)
195  {
196  reason = string.Empty;
197  GridRegion regInfo = null;
198 
199  mapName = mapName.Trim();
200 
201  if (!mapName.StartsWith("http"))
202  {
203  // Formats: grid.example.com:8002:region name
204  // grid.example.com:region name
205  // grid.example.com:8002
206  // grid.example.com
207 
208  string host;
209  uint port = 80;
210  string regionName = "";
211 
212  string[] parts = mapName.Split(new char[] { ':' });
213 
214  if (parts.Length == 0)
215  {
216  reason = "Wrong format for link-region";
217  return null;
218  }
219 
220  host = parts[0];
221 
222  if (parts.Length >= 2)
223  {
224  // If it's a number then assume it's a port. Otherwise, it's a region name.
225  if (!UInt32.TryParse(parts[1], out port))
226  regionName = parts[1];
227  }
228 
229  // always take the last one
230  if (parts.Length >= 3)
231  {
232  regionName = parts[2];
233  }
234 
235  bool success = TryCreateLink(scopeID, xloc, yloc, regionName, port, host, ownerID, out regInfo, out reason);
236  if (success)
237  {
238  regInfo.RegionName = mapName;
239  return regInfo;
240  }
241  }
242  else
243  {
244  // Formats: http://grid.example.com region name
245  // http://grid.example.com "region name"
246  // http://grid.example.com
247 
248  string serverURI;
249  string regionName = "";
250 
251  string[] parts = mapName.Split(new char[] { ' ' });
252 
253  if (parts.Length == 0)
254  {
255  reason = "Wrong format for link-region";
256  return null;
257  }
258 
259  serverURI = parts[0];
260 
261  if (parts.Length >= 2)
262  {
263  regionName = mapName.Substring(serverURI.Length);
264  regionName = regionName.Trim(new char[] { '"', ' ' });
265  }
266 
267  if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason))
268  {
269  regInfo.RegionName = mapName;
270  return regInfo;
271  }
272  }
273 
274  return null;
275  }
276 
277  private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason)
278  {
279  return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason);
280  }
281 
282  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)
283  {
284  lock (this)
285  {
286  return TryCreateLinkImpl(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, serverURI, ownerID, out regInfo, out reason);
287  }
288  }
289 
290  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)
291  {
292  m_log.InfoFormat("[HYPERGRID LINKER]: Link to {0} {1}, in <{2},{3}>",
293  ((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI),
294  remoteRegionName, Util.WorldToRegionLoc((uint)xloc), Util.WorldToRegionLoc((uint)yloc));
295 
296  reason = string.Empty;
297  Uri uri = null;
298 
299  regInfo = new GridRegion();
300  if (externalPort > 0)
301  regInfo.HttpPort = externalPort;
302  else
303  regInfo.HttpPort = 80;
304  if (externalHostName != null)
305  regInfo.ExternalHostName = externalHostName;
306  else
307  regInfo.ExternalHostName = "0.0.0.0";
308  if (serverURI != null)
309  {
310  regInfo.ServerURI = serverURI;
311  try
312  {
313  uri = new Uri(serverURI);
314  regInfo.ExternalHostName = uri.Host;
315  regInfo.HttpPort = (uint)uri.Port;
316  }
317  catch {}
318  }
319 
320  if (remoteRegionName != string.Empty)
321  regInfo.RegionName = remoteRegionName;
322 
323  regInfo.RegionLocX = xloc;
324  regInfo.RegionLocY = yloc;
325  regInfo.ScopeID = scopeID;
326  regInfo.EstateOwner = ownerID;
327 
328  // Make sure we're not hyperlinking to regions on this grid!
329  if (m_ThisGatekeeperURI != null)
330  {
331  if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port)
332  {
333  m_log.InfoFormat("[HYPERGRID LINKER]: Cannot hyperlink to regions on the same grid");
334  reason = "Cannot hyperlink to regions on the same grid";
335  return false;
336  }
337  }
338  else
339  m_log.WarnFormat("[HYPERGRID LINKER]: Please set this grid's Gatekeeper's address in [GridService]!");
340 
341  // Check for free coordinates
342  GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY);
343  if (region != null)
344  {
345  m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates <{0},{1}> are already occupied by region {2} with uuid {3}",
346  Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY),
347  region.RegionName, region.RegionID);
348  reason = "Coordinates are already in use";
349  return false;
350  }
351 
352  try
353  {
354  regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0);
355  }
356  catch (Exception e)
357  {
358  m_log.Warn("[HYPERGRID LINKER]: Wrong format for link-region: " + e.Message);
359  reason = "Internal error";
360  return false;
361  }
362 
363  // Finally, link it
364  ulong handle = 0;
365  UUID regionID = UUID.Zero;
366  string externalName = string.Empty;
367  string imageURL = string.Empty;
368  if (!m_GatekeeperConnector.LinkRegion(regInfo, out regionID, out handle, out externalName, out imageURL, out reason))
369  return false;
370 
371  if (regionID == UUID.Zero)
372  {
373  m_log.Warn("[HYPERGRID LINKER]: Unable to link region");
374  reason = "Remote region could not be found";
375  return false;
376  }
377 
378  region = m_GridService.GetRegionByUUID(scopeID, regionID);
379  if (region != null)
380  {
381  m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates <{0},{1}>", Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY));
382  regInfo = region;
383  return true;
384  }
385 
386  // We are now performing this check for each individual teleport in the EntityTransferModule instead. This
387  // allows us to give better feedback when teleports fail because of the distance reason (which can't be
388  // done here) and it also hypergrid teleports that are within range (possibly because the source grid
389  // itself has regions that are very far apart).
390 // uint x, y;
391 // if (m_Check4096 && !Check4096(handle, out x, out y))
392 // {
393 // //RemoveHyperlinkRegion(regInfo.RegionID);
394 // reason = "Region is too far (" + x + ", " + y + ")";
395 // m_log.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")");
396 // //return false;
397 // }
398 
399  regInfo.RegionID = regionID;
400 
401  if (externalName == string.Empty)
402  regInfo.RegionName = regInfo.ServerURI;
403  else
404  regInfo.RegionName = externalName;
405 
406  m_log.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString());
407 
408  // Get the map image
409  regInfo.TerrainImage = GetMapImage(regionID, imageURL);
410 
411  // Store the origin's coordinates somewhere
412  regInfo.RegionSecret = handle.ToString();
413 
414  AddHyperlinkRegion(regInfo, handle);
415  m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} at <{1},{2}> with image {3}",
416  regInfo.RegionName, Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY), regInfo.TerrainImage);
417  return true;
418  }
419 
420  public bool TryUnlinkRegion(string mapName)
421  {
422  m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName);
423  GridRegion regInfo = null;
424 
425  List<RegionData> regions = m_Database.Get(Util.EscapeForLike(mapName), m_ScopeID);
426  if (regions != null && regions.Count > 0)
427  {
428  OpenSim.Framework.RegionFlags rflags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]);
429  if ((rflags & OpenSim.Framework.RegionFlags.Hyperlink) != 0)
430  {
431  regInfo = new GridRegion();
432  regInfo.RegionID = regions[0].RegionID;
433  regInfo.ScopeID = m_ScopeID;
434  }
435  }
436 
437  if (regInfo != null)
438  {
439  RemoveHyperlinkRegion(regInfo.RegionID);
440  return true;
441  }
442  else
443  {
444  m_log.InfoFormat("[HYPERGRID LINKER]: Region {0} not found", mapName);
445  return false;
446  }
447  }
448 
449 // Not currently used
450 // /// <summary>
451 // /// Cope with this viewer limitation.
452 // /// </summary>
453 // /// <param name="regInfo"></param>
454 // /// <returns></returns>
455 // public bool Check4096(ulong realHandle, out uint x, out uint y)
456 // {
457 // uint ux = 0, uy = 0;
458 // Utils.LongToUInts(realHandle, out ux, out uy);
459 // x = Util.WorldToRegionLoc(ux);
460 // y = Util.WorldToRegionLoc(uy);
461 //
462 // const uint limit = Util.RegionToWorldLoc(4096 - 1);
463 // uint xmin = ux - limit;
464 // uint xmax = ux + limit;
465 // uint ymin = uy - limit;
466 // uint ymax = uy + limit;
467 // // World map boundary checks
468 // if (xmin < 0 || xmin > ux)
469 // xmin = 0;
470 // if (xmax > int.MaxValue || xmax < ux)
471 // xmax = int.MaxValue;
472 // if (ymin < 0 || ymin > uy)
473 // ymin = 0;
474 // if (ymax > int.MaxValue || ymax < uy)
475 // ymax = int.MaxValue;
476 //
477 // // Check for any regions that are within the possible teleport range to the linked region
478 // List<GridRegion> regions = m_GridService.GetRegionRange(m_ScopeID, (int)xmin, (int)xmax, (int)ymin, (int)ymax);
479 // if (regions.Count == 0)
480 // {
481 // return false;
482 // }
483 // else
484 // {
485 // // Check for regions which are not linked regions
486 // List<GridRegion> hyperlinks = m_GridService.GetHyperlinks(m_ScopeID);
487 // IEnumerable<GridRegion> availableRegions = regions.Except(hyperlinks);
488 // if (availableRegions.Count() == 0)
489 // return false;
490 // }
491 //
492 // return true;
493 // }
494 
495  private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle)
496  {
497  RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo);
498  int flags = (int)OpenSim.Framework.RegionFlags.Hyperlink + (int)OpenSim.Framework.RegionFlags.NoDirectLogin + (int)OpenSim.Framework.RegionFlags.RegionOnline;
499  rdata.Data["flags"] = flags.ToString();
500 
501  m_Database.Store(rdata);
502  }
503 
504  private void RemoveHyperlinkRegion(UUID regionID)
505  {
506  m_Database.Delete(regionID);
507  }
508 
509  public UUID GetMapImage(UUID regionID, string imageURL)
510  {
511  return m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory);
512  }
513  #endregion
514 
515 
516  #region Console Commands
517 
518  public void HandleShow(string module, string[] cmd)
519  {
520  if (cmd.Length != 2)
521  {
522  MainConsole.Instance.Output("Syntax: show hyperlinks");
523  return;
524  }
525  List<RegionData> regions = m_Database.GetHyperlinks(UUID.Zero);
526  if (regions == null || regions.Count < 1)
527  {
528  MainConsole.Instance.Output("No hyperlinks");
529  return;
530  }
531 
532  MainConsole.Instance.Output("Region Name");
533  MainConsole.Instance.Output("Location Region UUID");
534  MainConsole.Instance.Output(new string('-', 72));
535  foreach (RegionData r in regions)
536  {
537  MainConsole.Instance.Output(
538  String.Format("{0}\n{2,-32} {1}\n",
539  r.RegionName, r.RegionID,
540  String.Format("{0},{1} ({2},{3})", r.posX, r.posY,
541  Util.WorldToRegionLoc((uint)r.posX), Util.WorldToRegionLoc((uint)r.posY)
542  )
543  )
544  );
545  }
546  return;
547  }
548 
549  public void RunCommand(string module, string[] cmdparams)
550  {
551  List<string> args = new List<string>(cmdparams);
552  if (args.Count < 1)
553  return;
554 
555  string command = args[0];
556  args.RemoveAt(0);
557 
558  cmdparams = args.ToArray();
559 
560  RunHGCommand(command, cmdparams);
561 
562  }
563 
564  private void RunLinkRegionCommand(string[] cmdparams)
565  {
566  int xloc, yloc;
567  string serverURI;
568  string remoteName = null;
569  xloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[0]));
570  yloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[1]));
571  serverURI = cmdparams[2];
572  if (cmdparams.Length > 3)
573  remoteName = string.Join(" ", cmdparams, 3, cmdparams.Length - 3);
574  string reason = string.Empty;
575  GridRegion regInfo;
576  if (TryCreateLink(UUID.Zero, xloc, yloc, remoteName, 0, null, serverURI, UUID.Zero, out regInfo, out reason))
577  MainConsole.Instance.Output("Hyperlink established");
578  else
579  MainConsole.Instance.Output("Failed to link region: " + reason);
580  }
581 
582  private void RunHGCommand(string command, string[] cmdparams)
583  {
584  if (command.Equals("link-mapping"))
585  {
586  if (cmdparams.Length == 2)
587  {
588  try
589  {
590  m_autoMappingX = Convert.ToUInt32(cmdparams[0]);
591  m_autoMappingY = Convert.ToUInt32(cmdparams[1]);
592  m_enableAutoMapping = true;
593  }
594  catch (Exception)
595  {
596  m_autoMappingX = 0;
597  m_autoMappingY = 0;
598  m_enableAutoMapping = false;
599  }
600  }
601  }
602  else if (command.Equals("link-region"))
603  {
604  if (cmdparams.Length < 3)
605  {
606  if ((cmdparams.Length == 1) || (cmdparams.Length == 2))
607  {
608  LoadXmlLinkFile(cmdparams);
609  }
610  else
611  {
612  LinkRegionCmdUsage();
613  }
614  return;
615  }
616 
617  //this should be the prefererred way of setting up hg links now
618  if (cmdparams[2].StartsWith("http"))
619  {
620  RunLinkRegionCommand(cmdparams);
621  }
622  else if (cmdparams[2].Contains(":"))
623  {
624  // New format
625  string[] parts = cmdparams[2].Split(':');
626  if (parts.Length > 2)
627  {
628  // Insert remote region name
629  ArrayList parameters = new ArrayList(cmdparams);
630  parameters.Insert(3, parts[2]);
631  cmdparams = (string[])parameters.ToArray(typeof(string));
632  }
633  cmdparams[2] = "http://" + parts[0] + ':' + parts[1];
634 
635  RunLinkRegionCommand(cmdparams);
636  }
637  else
638  {
639  // old format
640  GridRegion regInfo;
641  uint xloc, yloc;
642  uint externalPort;
643  string externalHostName;
644  try
645  {
646  xloc = Convert.ToUInt32(cmdparams[0]);
647  yloc = Convert.ToUInt32(cmdparams[1]);
648  externalPort = Convert.ToUInt32(cmdparams[3]);
649  externalHostName = cmdparams[2];
650  //internalPort = Convert.ToUInt32(cmdparams[4]);
651  //remotingPort = Convert.ToUInt32(cmdparams[5]);
652  }
653  catch (Exception e)
654  {
655  MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message);
656  LinkRegionCmdUsage();
657  return;
658  }
659 
660  // Convert cell coordinates given by the user to meters
661  xloc = Util.RegionToWorldLoc(xloc);
662  yloc = Util.RegionToWorldLoc(yloc);
663  string reason = string.Empty;
664  if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc,
665  string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
666  {
667  // What is this? The GridRegion instance will be discarded anyway,
668  // which effectively ignores any local name given with the command.
669  //if (cmdparams.Length >= 5)
670  //{
671  // regInfo.RegionName = "";
672  // for (int i = 4; i < cmdparams.Length; i++)
673  // regInfo.RegionName += cmdparams[i] + " ";
674  //}
675  }
676  }
677  return;
678  }
679  else if (command.Equals("unlink-region"))
680  {
681  if (cmdparams.Length < 1)
682  {
683  UnlinkRegionCmdUsage();
684  return;
685  }
686  string region = string.Join(" ", cmdparams);
687  if (TryUnlinkRegion(region))
688  MainConsole.Instance.Output("Successfully unlinked " + region);
689  else
690  MainConsole.Instance.Output("Unable to unlink " + region + ", region not found.");
691  }
692  }
693 
694  private void LoadXmlLinkFile(string[] cmdparams)
695  {
696  //use http://www.hgurl.com/hypergrid.xml for test
697  try
698  {
699  XmlReader r = XmlReader.Create(cmdparams[0]);
700  XmlConfigSource cs = new XmlConfigSource(r);
701  string[] excludeSections = null;
702 
703  if (cmdparams.Length == 2)
704  {
705  if (cmdparams[1].ToLower().StartsWith("excludelist:"))
706  {
707  string excludeString = cmdparams[1].ToLower();
708  excludeString = excludeString.Remove(0, 12);
709  char[] splitter = { ';' };
710 
711  excludeSections = excludeString.Split(splitter);
712  }
713  }
714 
715  for (int i = 0; i < cs.Configs.Count; i++)
716  {
717  bool skip = false;
718  if ((excludeSections != null) && (excludeSections.Length > 0))
719  {
720  for (int n = 0; n < excludeSections.Length; n++)
721  {
722  if (excludeSections[n] == cs.Configs[i].Name.ToLower())
723  {
724  skip = true;
725  break;
726  }
727  }
728  }
729  if (!skip)
730  {
731  ReadLinkFromConfig(cs.Configs[i]);
732  }
733  }
734  }
735  catch (Exception e)
736  {
737  m_log.Error(e.ToString());
738  }
739  }
740 
741 
742  private void ReadLinkFromConfig(IConfig config)
743  {
744  GridRegion regInfo;
745  uint xloc, yloc;
746  uint externalPort;
747  string externalHostName;
748  uint realXLoc, realYLoc;
749 
750  xloc = Convert.ToUInt32(config.GetString("xloc", "0"));
751  yloc = Convert.ToUInt32(config.GetString("yloc", "0"));
752  externalPort = Convert.ToUInt32(config.GetString("externalPort", "0"));
753  externalHostName = config.GetString("externalHostName", "");
754  realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0"));
755  realYLoc = Convert.ToUInt32(config.GetString("real-yloc", "0"));
756 
757  if (m_enableAutoMapping)
758  {
759  xloc = (xloc % 100) + m_autoMappingX;
760  yloc = (yloc % 100) + m_autoMappingY;
761  }
762 
763  if (((realXLoc == 0) && (realYLoc == 0)) ||
764  (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) &&
765  ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896))))
766  {
767  xloc = Util.RegionToWorldLoc(xloc);
768  yloc = Util.RegionToWorldLoc(yloc);
769  string reason = string.Empty;
770  if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc,
771  string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
772  {
773  regInfo.RegionName = config.GetString("localName", "");
774  }
775  else
776  MainConsole.Instance.Output("Unable to link " + externalHostName + ": " + reason);
777  }
778  }
779 
780 
781  private void LinkRegionCmdUsage()
782  {
783  MainConsole.Instance.Output("Usage: link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]");
784  MainConsole.Instance.Output("Usage (deprecated): link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>]");
785  MainConsole.Instance.Output("Usage (deprecated): link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]");
786  MainConsole.Instance.Output("Usage: link-region <URI_of_xml> [<exclude>]");
787  }
788 
789  private void UnlinkRegionCmdUsage()
790  {
791  MainConsole.Instance.Output("Usage: unlink-region <LocalName>");
792  }
793 
794  #endregion
795 
796  }
797 }
UUID GetMapImage(UUID regionID, string imageURL)
int posX
The position in meters of this region.
Definition: IRegionData.cs:44
An interface for connecting to the authentication datastore
Definition: IRegionData.cs:70
void RunCommand(string module, string[] cmdparams)
GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason)
int posY
The position in meters of this region.
Definition: IRegionData.cs:49
Dictionary< string, object > Data
Definition: IRegionData.cs:64
GridRegion LinkRegion(UUID scopeID, string regionDescriptor)
RegionFlags
Region flags used internally by OpenSimulator to store installation specific information about region...
Definition: RegionFlags.cs:40
GatekeeperServiceConnector m_GatekeeperConnector
static ICommandConsole Instance
Definition: MainConsole.cs:35
OpenSim.Services.Interfaces.GridRegion GridRegion
void Output(string text, string level)
Interactive OpenSim region server
Definition: OpenSim.cs:55
HypergridLinker(IConfigSource config, GridService gridService, IRegionData db)
void HandleShow(string module, string[] cmd)