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