aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/GridService/HypergridLinker.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/GridService/HypergridLinker.cs')
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs799
1 files changed, 799 insertions, 0 deletions
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
new file mode 100644
index 0000000..9d016fc
--- /dev/null
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -0,0 +1,799 @@
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 : IHypergridLinker
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 protected GridRegion m_DefaultRegion;
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
236 bool success = TryCreateLink(scopeID, xloc, yloc, regionName, port, host, ownerID, out regInfo, out reason);
237 if (success)
238 {
239 regInfo.RegionName = mapName;
240 return regInfo;
241 }
242 }
243 else
244 {
245 // Formats: http://grid.example.com region name
246 // http://grid.example.com "region name"
247 // http://grid.example.com
248
249 string serverURI;
250 string regionName = "";
251
252 string[] parts = mapName.Split(new char[] { ' ' });
253
254 if (parts.Length == 0)
255 {
256 reason = "Wrong format for link-region";
257 return null;
258 }
259
260 serverURI = parts[0];
261
262 if (parts.Length >= 2)
263 {
264 regionName = mapName.Substring(serverURI.Length);
265 regionName = regionName.Trim(new char[] { '"', ' ' });
266 }
267
268 if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason))
269 {
270 regInfo.RegionName = mapName;
271 return regInfo;
272 }
273 }
274
275 return null;
276 }
277
278 private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason)
279 {
280 return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason);
281 }
282
283 private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason)
284 {
285 lock (this)
286 {
287 return TryCreateLinkImpl(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, serverURI, ownerID, out regInfo, out reason);
288 }
289 }
290
291 private bool TryCreateLinkImpl(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason)
292 {
293 m_log.InfoFormat("[HYPERGRID LINKER]: Link to {0} {1}, in <{2},{3}>",
294 ((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI),
295 remoteRegionName, Util.WorldToRegionLoc((uint)xloc), Util.WorldToRegionLoc((uint)yloc));
296
297 reason = string.Empty;
298 Uri uri = null;
299
300 regInfo = new GridRegion();
301 if (externalPort > 0)
302 regInfo.HttpPort = externalPort;
303 else
304 regInfo.HttpPort = 80;
305 if (externalHostName != null)
306 regInfo.ExternalHostName = externalHostName;
307 else
308 regInfo.ExternalHostName = "0.0.0.0";
309 if (serverURI != null)
310 {
311 regInfo.ServerURI = serverURI;
312 try
313 {
314 uri = new Uri(serverURI);
315 regInfo.ExternalHostName = uri.Host;
316 regInfo.HttpPort = (uint)uri.Port;
317 }
318 catch {}
319 }
320
321 if (remoteRegionName != string.Empty)
322 regInfo.RegionName = remoteRegionName;
323
324 regInfo.RegionLocX = xloc;
325 regInfo.RegionLocY = yloc;
326 regInfo.ScopeID = scopeID;
327 regInfo.EstateOwner = ownerID;
328
329 // Make sure we're not hyperlinking to regions on this grid!
330 if (m_ThisGatekeeperURI != null)
331 {
332 if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port)
333 {
334 m_log.InfoFormat("[HYPERGRID LINKER]: Cannot hyperlink to regions on the same grid");
335 reason = "Cannot hyperlink to regions on the same grid";
336 return false;
337 }
338 }
339 else
340 m_log.WarnFormat("[HYPERGRID LINKER]: Please set this grid's Gatekeeper's address in [GridService]!");
341
342 // Check for free coordinates
343 GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY);
344 if (region != null)
345 {
346 m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates <{0},{1}> are already occupied by region {2} with uuid {3}",
347 Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY),
348 region.RegionName, region.RegionID);
349 reason = "Coordinates are already in use";
350 return false;
351 }
352
353 try
354 {
355 regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0);
356 }
357 catch (Exception e)
358 {
359 m_log.Warn("[HYPERGRID LINKER]: Wrong format for link-region: " + e.Message);
360 reason = "Internal error";
361 return false;
362 }
363
364 // Finally, link it
365 ulong handle = 0;
366 UUID regionID = UUID.Zero;
367 string externalName = string.Empty;
368 string imageURL = string.Empty;
369 if (!m_GatekeeperConnector.LinkRegion(regInfo, out regionID, out handle, out externalName, out imageURL, out reason))
370 return false;
371
372 if (regionID == UUID.Zero)
373 {
374 m_log.Warn("[HYPERGRID LINKER]: Unable to link region");
375 reason = "Remote region could not be found";
376 return false;
377 }
378
379 region = m_GridService.GetRegionByUUID(scopeID, regionID);
380 if (region != null)
381 {
382 m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates <{0},{1}>",
383 Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY));
384 regInfo = region;
385 return true;
386 }
387
388 // We are now performing this check for each individual teleport in the EntityTransferModule instead. This
389 // allows us to give better feedback when teleports fail because of the distance reason (which can't be
390 // done here) and it also hypergrid teleports that are within range (possibly because the source grid
391 // itself has regions that are very far apart).
392// uint x, y;
393// if (m_Check4096 && !Check4096(handle, out x, out y))
394// {
395// //RemoveHyperlinkRegion(regInfo.RegionID);
396// reason = "Region is too far (" + x + ", " + y + ")";
397// m_log.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")");
398// //return false;
399// }
400
401 regInfo.RegionID = regionID;
402
403 if (externalName == string.Empty)
404 regInfo.RegionName = regInfo.ServerURI;
405 else
406 regInfo.RegionName = externalName;
407
408 m_log.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString());
409
410 // Get the map image
411 regInfo.TerrainImage = GetMapImage(regionID, imageURL);
412
413 // Store the origin's coordinates somewhere
414 regInfo.RegionSecret = handle.ToString();
415
416 AddHyperlinkRegion(regInfo, handle);
417 m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} at <{1},{2}> with image {3}",
418 regInfo.RegionName, Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY), regInfo.TerrainImage);
419 return true;
420 }
421
422 public bool TryUnlinkRegion(string mapName)
423 {
424 m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName);
425 GridRegion regInfo = null;
426
427 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(mapName), m_ScopeID);
428 if (regions != null && regions.Count > 0)
429 {
430 OpenSim.Framework.RegionFlags rflags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]);
431 if ((rflags & OpenSim.Framework.RegionFlags.Hyperlink) != 0)
432 {
433 regInfo = new GridRegion();
434 regInfo.RegionID = regions[0].RegionID;
435 regInfo.ScopeID = m_ScopeID;
436 }
437 }
438
439 if (regInfo != null)
440 {
441 RemoveHyperlinkRegion(regInfo.RegionID);
442 return true;
443 }
444 else
445 {
446 m_log.InfoFormat("[HYPERGRID LINKER]: Region {0} not found", mapName);
447 return false;
448 }
449 }
450
451// Not currently used
452// /// <summary>
453// /// Cope with this viewer limitation.
454// /// </summary>
455// /// <param name="regInfo"></param>
456// /// <returns></returns>
457// public bool Check4096(ulong realHandle, out uint x, out uint y)
458// {
459// uint ux = 0, uy = 0;
460// Utils.LongToUInts(realHandle, out ux, out uy);
461// x = Util.WorldToRegionLoc(ux);
462// y = Util.WorldToRegionLoc(uy);
463//
464// const uint limit = Util.RegionToWorldLoc(4096 - 1);
465// uint xmin = ux - limit;
466// uint xmax = ux + limit;
467// uint ymin = uy - limit;
468// uint ymax = uy + limit;
469// // World map boundary checks
470// if (xmin < 0 || xmin > ux)
471// xmin = 0;
472// if (xmax > int.MaxValue || xmax < ux)
473// xmax = int.MaxValue;
474// if (ymin < 0 || ymin > uy)
475// ymin = 0;
476// if (ymax > int.MaxValue || ymax < uy)
477// ymax = int.MaxValue;
478//
479// // Check for any regions that are within the possible teleport range to the linked region
480// List<GridRegion> regions = m_GridService.GetRegionRange(m_ScopeID, (int)xmin, (int)xmax, (int)ymin, (int)ymax);
481// if (regions.Count == 0)
482// {
483// return false;
484// }
485// else
486// {
487// // Check for regions which are not linked regions
488// List<GridRegion> hyperlinks = m_GridService.GetHyperlinks(m_ScopeID);
489// IEnumerable<GridRegion> availableRegions = regions.Except(hyperlinks);
490// if (availableRegions.Count() == 0)
491// return false;
492// }
493//
494// return true;
495// }
496
497 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle)
498 {
499 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo);
500 int flags = (int)OpenSim.Framework.RegionFlags.Hyperlink + (int)OpenSim.Framework.RegionFlags.NoDirectLogin + (int)OpenSim.Framework.RegionFlags.RegionOnline;
501 rdata.Data["flags"] = flags.ToString();
502
503 m_Database.Store(rdata);
504 }
505
506 private void RemoveHyperlinkRegion(UUID regionID)
507 {
508 m_Database.Delete(regionID);
509 }
510
511 public UUID GetMapImage(UUID regionID, string imageURL)
512 {
513 return m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory);
514 }
515 #endregion
516
517
518 #region Console Commands
519
520 public void HandleShow(string module, string[] cmd)
521 {
522 if (cmd.Length != 2)
523 {
524 MainConsole.Instance.Output("Syntax: show hyperlinks");
525 return;
526 }
527 List<RegionData> regions = m_Database.GetHyperlinks(UUID.Zero);
528 if (regions == null || regions.Count < 1)
529 {
530 MainConsole.Instance.Output("No hyperlinks");
531 return;
532 }
533
534 MainConsole.Instance.Output("Region Name");
535 MainConsole.Instance.Output("Location Region UUID");
536 MainConsole.Instance.Output(new string('-', 72));
537 foreach (RegionData r in regions)
538 {
539 MainConsole.Instance.Output(
540 String.Format("{0}\n{2,-32} {1}\n",
541 r.RegionName, r.RegionID,
542 String.Format("{0},{1} ({2},{3})", r.posX, r.posY,
543 Util.WorldToRegionLoc((uint)r.posX), Util.WorldToRegionLoc((uint)r.posY)
544 )
545 )
546 );
547 }
548 return;
549 }
550
551 public void RunCommand(string module, string[] cmdparams)
552 {
553 List<string> args = new List<string>(cmdparams);
554 if (args.Count < 1)
555 return;
556
557 string command = args[0];
558 args.RemoveAt(0);
559
560 cmdparams = args.ToArray();
561
562 RunHGCommand(command, cmdparams);
563
564 }
565
566 private void RunLinkRegionCommand(string[] cmdparams)
567 {
568 int xloc, yloc;
569 string serverURI;
570 string remoteName = null;
571 xloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[0]));
572 yloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[1]));
573 serverURI = cmdparams[2];
574 if (cmdparams.Length > 3)
575 remoteName = string.Join(" ", cmdparams, 3, cmdparams.Length - 3);
576 string reason = string.Empty;
577 GridRegion regInfo;
578 if (TryCreateLink(UUID.Zero, xloc, yloc, remoteName, 0, null, serverURI, UUID.Zero, out regInfo, out reason))
579 MainConsole.Instance.Output("Hyperlink established");
580 else
581 MainConsole.Instance.Output("Failed to link region: " + reason);
582 }
583
584 private void RunHGCommand(string command, string[] cmdparams)
585 {
586 if (command.Equals("link-mapping"))
587 {
588 if (cmdparams.Length == 2)
589 {
590 try
591 {
592 m_autoMappingX = Convert.ToUInt32(cmdparams[0]);
593 m_autoMappingY = Convert.ToUInt32(cmdparams[1]);
594 m_enableAutoMapping = true;
595 }
596 catch (Exception)
597 {
598 m_autoMappingX = 0;
599 m_autoMappingY = 0;
600 m_enableAutoMapping = false;
601 }
602 }
603 }
604 else if (command.Equals("link-region"))
605 {
606 if (cmdparams.Length < 3)
607 {
608 if ((cmdparams.Length == 1) || (cmdparams.Length == 2))
609 {
610 LoadXmlLinkFile(cmdparams);
611 }
612 else
613 {
614 LinkRegionCmdUsage();
615 }
616 return;
617 }
618
619 //this should be the prefererred way of setting up hg links now
620 if (cmdparams[2].StartsWith("http"))
621 {
622 RunLinkRegionCommand(cmdparams);
623 }
624 else if (cmdparams[2].Contains(":"))
625 {
626 // New format
627 string[] parts = cmdparams[2].Split(':');
628 if (parts.Length > 2)
629 {
630 // Insert remote region name
631 ArrayList parameters = new ArrayList(cmdparams);
632 parameters.Insert(3, parts[2]);
633 cmdparams = (string[])parameters.ToArray(typeof(string));
634 }
635 cmdparams[2] = "http://" + parts[0] + ':' + parts[1];
636
637 RunLinkRegionCommand(cmdparams);
638 }
639 else
640 {
641 // old format
642 GridRegion regInfo;
643 uint xloc, yloc;
644 uint externalPort;
645 string externalHostName;
646 try
647 {
648 xloc = Convert.ToUInt32(cmdparams[0]);
649 yloc = Convert.ToUInt32(cmdparams[1]);
650 externalPort = Convert.ToUInt32(cmdparams[3]);
651 externalHostName = cmdparams[2];
652 //internalPort = Convert.ToUInt32(cmdparams[4]);
653 //remotingPort = Convert.ToUInt32(cmdparams[5]);
654 }
655 catch (Exception e)
656 {
657 MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message);
658 LinkRegionCmdUsage();
659 return;
660 }
661
662 // Convert cell coordinates given by the user to meters
663 xloc = Util.RegionToWorldLoc(xloc);
664 yloc = Util.RegionToWorldLoc(yloc);
665 string reason = string.Empty;
666 if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc,
667 string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
668 {
669 // What is this? The GridRegion instance will be discarded anyway,
670 // which effectively ignores any local name given with the command.
671 //if (cmdparams.Length >= 5)
672 //{
673 // regInfo.RegionName = "";
674 // for (int i = 4; i < cmdparams.Length; i++)
675 // regInfo.RegionName += cmdparams[i] + " ";
676 //}
677 }
678 }
679 return;
680 }
681 else if (command.Equals("unlink-region"))
682 {
683 if (cmdparams.Length < 1)
684 {
685 UnlinkRegionCmdUsage();
686 return;
687 }
688 string region = string.Join(" ", cmdparams);
689 if (TryUnlinkRegion(region))
690 MainConsole.Instance.Output("Successfully unlinked " + region);
691 else
692 MainConsole.Instance.Output("Unable to unlink " + region + ", region not found.");
693 }
694 }
695
696 private void LoadXmlLinkFile(string[] cmdparams)
697 {
698 //use http://www.hgurl.com/hypergrid.xml for test
699 try
700 {
701 XmlReader r = XmlReader.Create(cmdparams[0]);
702 XmlConfigSource cs = new XmlConfigSource(r);
703 string[] excludeSections = null;
704
705 if (cmdparams.Length == 2)
706 {
707 if (cmdparams[1].ToLower().StartsWith("excludelist:"))
708 {
709 string excludeString = cmdparams[1].ToLower();
710 excludeString = excludeString.Remove(0, 12);
711 char[] splitter = { ';' };
712
713 excludeSections = excludeString.Split(splitter);
714 }
715 }
716
717 for (int i = 0; i < cs.Configs.Count; i++)
718 {
719 bool skip = false;
720 if ((excludeSections != null) && (excludeSections.Length > 0))
721 {
722 for (int n = 0; n < excludeSections.Length; n++)
723 {
724 if (excludeSections[n] == cs.Configs[i].Name.ToLower())
725 {
726 skip = true;
727 break;
728 }
729 }
730 }
731 if (!skip)
732 {
733 ReadLinkFromConfig(cs.Configs[i]);
734 }
735 }
736 }
737 catch (Exception e)
738 {
739 m_log.Error(e.ToString());
740 }
741 }
742
743
744 private void ReadLinkFromConfig(IConfig config)
745 {
746 GridRegion regInfo;
747 uint xloc, yloc;
748 uint externalPort;
749 string externalHostName;
750 uint realXLoc, realYLoc;
751
752 xloc = Convert.ToUInt32(config.GetString("xloc", "0"));
753 yloc = Convert.ToUInt32(config.GetString("yloc", "0"));
754 externalPort = Convert.ToUInt32(config.GetString("externalPort", "0"));
755 externalHostName = config.GetString("externalHostName", "");
756 realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0"));
757 realYLoc = Convert.ToUInt32(config.GetString("real-yloc", "0"));
758
759 if (m_enableAutoMapping)
760 {
761 xloc = (xloc % 100) + m_autoMappingX;
762 yloc = (yloc % 100) + m_autoMappingY;
763 }
764
765 if (((realXLoc == 0) && (realYLoc == 0)) ||
766 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) &&
767 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896))))
768 {
769 xloc = Util.RegionToWorldLoc(xloc);
770 yloc = Util.RegionToWorldLoc(yloc);
771 string reason = string.Empty;
772 if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc,
773 string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
774 {
775 regInfo.RegionName = config.GetString("localName", "");
776 }
777 else
778 MainConsole.Instance.Output("Unable to link " + externalHostName + ": " + reason);
779 }
780 }
781
782
783 private void LinkRegionCmdUsage()
784 {
785 MainConsole.Instance.Output("Usage: link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]");
786 MainConsole.Instance.Output("Usage (deprecated): link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>]");
787 MainConsole.Instance.Output("Usage (deprecated): link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]");
788 MainConsole.Instance.Output("Usage: link-region <URI_of_xml> [<exclude>]");
789 }
790
791 private void UnlinkRegionCmdUsage()
792 {
793 MainConsole.Instance.Output("Usage: unlink-region <LocalName>");
794 }
795
796 #endregion
797
798 }
799}