opensim – Blame information for rev 1

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