aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/GridService
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/GridService')
-rw-r--r--OpenSim/Services/GridService/GridService.cs283
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs635
2 files changed, 916 insertions, 2 deletions
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index 7749c37..2faf018 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -34,6 +34,7 @@ using log4net;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Console; 35using OpenSim.Framework.Console;
36using OpenSim.Data; 36using OpenSim.Data;
37using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion; 39using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenMetaverse; 40using OpenMetaverse;
@@ -46,17 +47,58 @@ namespace OpenSim.Services.GridService
46 LogManager.GetLogger( 47 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType); 48 MethodBase.GetCurrentMethod().DeclaringType);
48 49
50 private bool m_DeleteOnUnregister = true;
51 private static GridService m_RootInstance = null;
52 protected IConfigSource m_config;
53 protected HypergridLinker m_HypergridLinker;
54
55 protected IAuthenticationService m_AuthenticationService = null;
49 protected bool m_AllowDuplicateNames = false; 56 protected bool m_AllowDuplicateNames = false;
57 protected bool m_AllowHypergridMapSearch = false;
50 58
51 public GridService(IConfigSource config) 59 public GridService(IConfigSource config)
52 : base(config) 60 : base(config)
53 { 61 {
54 m_log.DebugFormat("[GRID SERVICE]: Starting..."); 62 m_log.DebugFormat("[GRID SERVICE]: Starting...");
55 63
64 m_config = config;
56 IConfig gridConfig = config.Configs["GridService"]; 65 IConfig gridConfig = config.Configs["GridService"];
57 if (gridConfig != null) 66 if (gridConfig != null)
58 { 67 {
68 m_DeleteOnUnregister = gridConfig.GetBoolean("DeleteOnUnregister", true);
69
70 string authService = gridConfig.GetString("AuthenticationService", String.Empty);
71
72 if (authService != String.Empty)
73 {
74 Object[] args = new Object[] { config };
75 m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, args);
76 }
59 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); 77 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames);
78 m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch);
79 }
80
81 if (m_RootInstance == null)
82 {
83 m_RootInstance = this;
84
85 if (MainConsole.Instance != null)
86 {
87 MainConsole.Instance.Commands.AddCommand("grid", true,
88 "show region",
89 "show region <Region name>",
90 "Show details on a region",
91 String.Empty,
92 HandleShowRegion);
93
94 MainConsole.Instance.Commands.AddCommand("grid", true,
95 "set region flags",
96 "set region flags <Region name> <flags>",
97 "Set database flags for region",
98 String.Empty,
99 HandleSetFlags);
100 }
101 m_HypergridLinker = new HypergridLinker(m_config, this, m_Database);
60 } 102 }
61 } 103 }
62 104
@@ -64,9 +106,46 @@ namespace OpenSim.Services.GridService
64 106
65 public string RegisterRegion(UUID scopeID, GridRegion regionInfos) 107 public string RegisterRegion(UUID scopeID, GridRegion regionInfos)
66 { 108 {
109 IConfig gridConfig = m_config.Configs["GridService"];
67 // This needs better sanity testing. What if regionInfo is registering in 110 // This needs better sanity testing. What if regionInfo is registering in
68 // overlapping coords? 111 // overlapping coords?
69 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 112 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
113 if (region != null)
114 {
115 // There is a preexisting record
116 //
117 // Get it's flags
118 //
119 OpenSim.Data.RegionFlags rflags = (OpenSim.Data.RegionFlags)Convert.ToInt32(region.Data["flags"]);
120
121 // Is this a reservation?
122 //
123 if ((rflags & OpenSim.Data.RegionFlags.Reservation) != 0)
124 {
125 // Regions reserved for the null key cannot be taken.
126 if ((string)region.Data["PrincipalID"] == UUID.Zero.ToString())
127 return "Region location us reserved";
128
129 // Treat it as an auth request
130 //
131 // NOTE: Fudging the flags value here, so these flags
132 // should not be used elsewhere. Don't optimize
133 // this with the later retrieval of the same flags!
134 rflags |= OpenSim.Data.RegionFlags.Authenticate;
135 }
136
137 if ((rflags & OpenSim.Data.RegionFlags.Authenticate) != 0)
138 {
139 // Can we authenticate at all?
140 //
141 if (m_AuthenticationService == null)
142 return "No authentication possible";
143
144 if (!m_AuthenticationService.Verify(new UUID(region.Data["PrincipalID"].ToString()), regionInfos.Token, 30))
145 return "Bad authentication";
146 }
147 }
148
70 if ((region != null) && (region.RegionID != regionInfos.RegionID)) 149 if ((region != null) && (region.RegionID != regionInfos.RegionID))
71 { 150 {
72 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.", 151 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
@@ -76,6 +155,9 @@ namespace OpenSim.Services.GridService
76 if ((region != null) && (region.RegionID == regionInfos.RegionID) && 155 if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
77 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY))) 156 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
78 { 157 {
158 if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0)
159 return "Can't move this region";
160
79 // Region reregistering in other coordinates. Delete the old entry 161 // Region reregistering in other coordinates. Delete the old entry
80 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.", 162 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
81 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); 163 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
@@ -110,8 +192,37 @@ namespace OpenSim.Services.GridService
110 // Everything is ok, let's register 192 // Everything is ok, let's register
111 RegionData rdata = RegionInfo2RegionData(regionInfos); 193 RegionData rdata = RegionInfo2RegionData(regionInfos);
112 rdata.ScopeID = scopeID; 194 rdata.ScopeID = scopeID;
195
196 if (region != null)
197 {
198 int oldFlags = Convert.ToInt32(region.Data["flags"]);
199 if ((oldFlags & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
200 return "Region locked out";
201
202 oldFlags &= ~(int)OpenSim.Data.RegionFlags.Reservation;
203
204 rdata.Data["flags"] = oldFlags.ToString(); // Preserve flags
205 }
206 else
207 {
208 rdata.Data["flags"] = "0";
209 if ((gridConfig != null) && rdata.RegionName != string.Empty)
210 {
211 int newFlags = 0;
212 string regionName = rdata.RegionName.Trim().Replace(' ', '_');
213 newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + regionName, String.Empty));
214 newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + rdata.RegionID.ToString(), String.Empty));
215 rdata.Data["flags"] = newFlags.ToString();
216 }
217 }
218
219 int flags = Convert.ToInt32(rdata.Data["flags"]);
220 flags |= (int)OpenSim.Data.RegionFlags.RegionOnline;
221 rdata.Data["flags"] = flags.ToString();
222
113 try 223 try
114 { 224 {
225 rdata.Data["last_seen"] = Util.UnixTimeSinceEpoch();
115 m_Database.Store(rdata); 226 m_Database.Store(rdata);
116 } 227 }
117 catch (Exception e) 228 catch (Exception e)
@@ -128,6 +239,30 @@ namespace OpenSim.Services.GridService
128 public bool DeregisterRegion(UUID regionID) 239 public bool DeregisterRegion(UUID regionID)
129 { 240 {
130 m_log.DebugFormat("[GRID SERVICE]: Region {0} deregistered", regionID); 241 m_log.DebugFormat("[GRID SERVICE]: Region {0} deregistered", regionID);
242 RegionData region = m_Database.Get(regionID, UUID.Zero);
243 if (region == null)
244 return false;
245
246 int flags = Convert.ToInt32(region.Data["flags"]);
247
248 if (!m_DeleteOnUnregister || (flags & (int)OpenSim.Data.RegionFlags.Persistent) != 0)
249 {
250 flags &= ~(int)OpenSim.Data.RegionFlags.RegionOnline;
251 region.Data["flags"] = flags.ToString();
252 region.Data["last_seen"] = Util.UnixTimeSinceEpoch();
253 try
254 {
255 m_Database.Store(region);
256 }
257 catch (Exception e)
258 {
259 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
260 }
261
262 return true;
263
264 }
265
131 return m_Database.Delete(regionID); 266 return m_Database.Delete(regionID);
132 } 267 }
133 268
@@ -194,6 +329,13 @@ namespace OpenSim.Services.GridService
194 } 329 }
195 } 330 }
196 331
332 if (m_AllowHypergridMapSearch && rdatas == null || (rdatas != null && rdatas.Count == 0) && name.Contains("."))
333 {
334 GridRegion r = m_HypergridLinker.LinkRegion(scopeID, name);
335 if (r != null)
336 rinfos.Add(r);
337 }
338
197 return rinfos; 339 return rinfos;
198 } 340 }
199 341
@@ -216,7 +358,7 @@ namespace OpenSim.Services.GridService
216 358
217 #region Data structure conversions 359 #region Data structure conversions
218 360
219 protected RegionData RegionInfo2RegionData(GridRegion rinfo) 361 public RegionData RegionInfo2RegionData(GridRegion rinfo)
220 { 362 {
221 RegionData rdata = new RegionData(); 363 RegionData rdata = new RegionData();
222 rdata.posX = (int)rinfo.RegionLocX; 364 rdata.posX = (int)rinfo.RegionLocX;
@@ -229,7 +371,7 @@ namespace OpenSim.Services.GridService
229 return rdata; 371 return rdata;
230 } 372 }
231 373
232 protected GridRegion RegionData2RegionInfo(RegionData rdata) 374 public GridRegion RegionData2RegionInfo(RegionData rdata)
233 { 375 {
234 GridRegion rinfo = new GridRegion(rdata.Data); 376 GridRegion rinfo = new GridRegion(rdata.Data);
235 rinfo.RegionLocX = rdata.posX; 377 rinfo.RegionLocX = rdata.posX;
@@ -243,5 +385,142 @@ namespace OpenSim.Services.GridService
243 385
244 #endregion 386 #endregion
245 387
388 public List<GridRegion> GetDefaultRegions(UUID scopeID)
389 {
390 List<GridRegion> ret = new List<GridRegion>();
391
392 List<RegionData> regions = m_Database.GetDefaultRegions(scopeID);
393
394 foreach (RegionData r in regions)
395 {
396 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
397 ret.Add(RegionData2RegionInfo(r));
398 }
399
400 return ret;
401 }
402
403 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
404 {
405 List<GridRegion> ret = new List<GridRegion>();
406
407 List<RegionData> regions = m_Database.GetFallbackRegions(scopeID, x, y);
408
409 foreach (RegionData r in regions)
410 {
411 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
412 ret.Add(RegionData2RegionInfo(r));
413 }
414
415 m_log.DebugFormat("[GRID SERVICE]: Fallback returned {0} regions", ret.Count);
416 return ret;
417 }
418
419 public int GetRegionFlags(UUID scopeID, UUID regionID)
420 {
421 RegionData region = m_Database.Get(regionID, scopeID);
422
423 if (region != null)
424 {
425 int flags = Convert.ToInt32(region.Data["flags"]);
426 //m_log.DebugFormat("[GRID SERVICE]: Request for flags of {0}: {1}", regionID, flags);
427 return flags;
428 }
429 else
430 return -1;
431 }
432
433 private void HandleShowRegion(string module, string[] cmd)
434 {
435 if (cmd.Length != 3)
436 {
437 MainConsole.Instance.Output("Syntax: show region <region name>");
438 return;
439 }
440 List<RegionData> regions = m_Database.Get(cmd[2], UUID.Zero);
441 if (regions == null || regions.Count < 1)
442 {
443 MainConsole.Instance.Output("Region not found");
444 return;
445 }
446
447 MainConsole.Instance.Output("Region Name Region UUID");
448 MainConsole.Instance.Output("Location URI");
449 MainConsole.Instance.Output("Owner ID Flags");
450 MainConsole.Instance.Output("-------------------------------------------------------------------------------");
451 foreach (RegionData r in regions)
452 {
453 OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]);
454 MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} {5}\n\n",
455 r.RegionName, r.RegionID,
456 String.Format("{0},{1}", r.posX, r.posY), "http://" + r.Data["serverIP"].ToString() + ":" + r.Data["serverPort"].ToString(),
457 r.Data["owner_uuid"].ToString(), flags.ToString()));
458 }
459 return;
460 }
461
462 private int ParseFlags(int prev, string flags)
463 {
464 OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)prev;
465
466 string[] parts = flags.Split(new char[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
467
468 foreach (string p in parts)
469 {
470 int val;
471
472 try
473 {
474 if (p.StartsWith("+"))
475 {
476 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p.Substring(1));
477 f |= (OpenSim.Data.RegionFlags)val;
478 }
479 else if (p.StartsWith("-"))
480 {
481 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p.Substring(1));
482 f &= ~(OpenSim.Data.RegionFlags)val;
483 }
484 else
485 {
486 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p);
487 f |= (OpenSim.Data.RegionFlags)val;
488 }
489 }
490 catch (Exception)
491 {
492 MainConsole.Instance.Output("Error in flag specification: " + p);
493 }
494 }
495
496 return (int)f;
497 }
498
499 private void HandleSetFlags(string module, string[] cmd)
500 {
501 if (cmd.Length < 5)
502 {
503 MainConsole.Instance.Output("Syntax: set region flags <region name> <flags>");
504 return;
505 }
506
507 List<RegionData> regions = m_Database.Get(cmd[3], UUID.Zero);
508 if (regions == null || regions.Count < 1)
509 {
510 MainConsole.Instance.Output("Region not found");
511 return;
512 }
513
514 foreach (RegionData r in regions)
515 {
516 int flags = Convert.ToInt32(r.Data["flags"]);
517 flags = ParseFlags(flags, cmd[4]);
518 r.Data["flags"] = flags.ToString();
519 OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)flags;
520
521 MainConsole.Instance.Output(String.Format("Set region {0} to {1}", r.RegionName, f));
522 m_Database.Store(r);
523 }
524 }
246 } 525 }
247} 526}
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
new file mode 100644
index 0000000..58746d0
--- /dev/null
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -0,0 +1,635 @@
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.Generic;
30using System.Net;
31using System.Reflection;
32using System.Xml;
33
34using Nini.Config;
35using log4net;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Data;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42using GridRegion = OpenSim.Services.Interfaces.GridRegion;
43using OpenMetaverse;
44
45namespace OpenSim.Services.GridService
46{
47 public class HypergridLinker
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(
51 MethodBase.GetCurrentMethod().DeclaringType);
52
53 private static UUID m_HGMapImage = new UUID("00000000-0000-1111-9999-000000000013");
54
55 private static uint m_autoMappingX = 0;
56 private static uint m_autoMappingY = 0;
57 private static bool m_enableAutoMapping = false;
58
59 protected IRegionData m_Database;
60 protected GridService m_GridService;
61 protected IAssetService m_AssetService;
62 protected GatekeeperServiceConnector m_GatekeeperConnector;
63
64 protected UUID m_ScopeID = UUID.Zero;
65
66 // Hyperlink regions are hyperlinks on the map
67 public readonly Dictionary<UUID, GridRegion> m_HyperlinkRegions = new Dictionary<UUID, GridRegion>();
68 protected Dictionary<UUID, ulong> m_HyperlinkHandles = new Dictionary<UUID, ulong>();
69
70 protected GridRegion m_DefaultRegion;
71 protected GridRegion DefaultRegion
72 {
73 get
74 {
75 if (m_DefaultRegion == null)
76 {
77 List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID);
78 if (defs != null && defs.Count > 0)
79 m_DefaultRegion = defs[0];
80 else
81 {
82 // Best guess, may be totally off
83 m_DefaultRegion = new GridRegion(1000, 1000);
84 m_log.WarnFormat("[HYPERGRID LINKER]: This grid does not have a default region. Assuming default coordinates at 1000, 1000.");
85 }
86 }
87 return m_DefaultRegion;
88 }
89 }
90
91 public HypergridLinker(IConfigSource config, GridService gridService, IRegionData db)
92 {
93 m_log.DebugFormat("[HYPERGRID LINKER]: Starting...");
94
95 m_Database = db;
96 m_GridService = gridService;
97
98 IConfig gridConfig = config.Configs["GridService"];
99 if (gridConfig != null)
100 {
101 string assetService = gridConfig.GetString("AssetService", string.Empty);
102
103 Object[] args = new Object[] { config };
104
105 if (assetService != string.Empty)
106 m_AssetService = ServerUtils.LoadPlugin<IAssetService>(assetService, args);
107
108 string scope = gridConfig.GetString("ScopeID", string.Empty);
109 if (scope != string.Empty)
110 UUID.TryParse(scope, out m_ScopeID);
111
112 m_GatekeeperConnector = new GatekeeperServiceConnector(m_AssetService);
113
114 m_log.DebugFormat("[HYPERGRID LINKER]: Loaded all services...");
115 }
116
117 if (MainConsole.Instance != null)
118 {
119 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region",
120 "link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>] <cr>",
121 "Link a hypergrid region", RunCommand);
122 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "unlink-region",
123 "unlink-region <local name> or <HostName>:<HttpPort> <cr>",
124 "Unlink a hypergrid region", RunCommand);
125 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-mapping", "link-mapping [<x> <y>] <cr>",
126 "Set local coordinate to map HG regions to", RunCommand);
127 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "show hyperlinks", "show hyperlinks <cr>",
128 "List the HG regions", HandleShow);
129 }
130 }
131
132
133 #region Link Region
134
135 public GridRegion LinkRegion(UUID scopeID, string regionDescriptor)
136 {
137 string reason = string.Empty;
138 int xloc = random.Next(0, Int16.MaxValue) * (int)Constants.RegionSize;
139 return TryLinkRegionToCoords(scopeID, regionDescriptor, xloc, 0, out reason);
140 }
141
142 private static Random random = new Random();
143
144 // From the command line link-region
145 public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason)
146 {
147 reason = string.Empty;
148 string host = "127.0.0.1";
149 string portstr;
150 string regionName = "";
151 uint port = 9000;
152 string[] parts = mapName.Split(new char[] { ':' });
153 if (parts.Length >= 1)
154 {
155 host = parts[0];
156 }
157 if (parts.Length >= 2)
158 {
159 portstr = parts[1];
160 //m_log.Debug("-- port = " + portstr);
161 if (!UInt32.TryParse(portstr, out port))
162 regionName = parts[1];
163 }
164 // always take the last one
165 if (parts.Length >= 3)
166 {
167 regionName = parts[2];
168 }
169
170 // Sanity check.
171 //IPAddress ipaddr = null;
172 try
173 {
174 //ipaddr = Util.GetHostFromDNS(host);
175 Util.GetHostFromDNS(host);
176 }
177 catch
178 {
179 reason = "Malformed hostname";
180 return null;
181 }
182
183 GridRegion regInfo;
184 bool success = TryCreateLink(scopeID, xloc, yloc, regionName, port, host, out regInfo, out reason);
185 if (success)
186 {
187 regInfo.RegionName = mapName;
188 return regInfo;
189 }
190
191 return null;
192 }
193
194
195 // From the command line and the 2 above
196 public bool TryCreateLink(UUID scopeID, int xloc, int yloc,
197 string externalRegionName, uint externalPort, string externalHostName, out GridRegion regInfo, out string reason)
198 {
199 m_log.DebugFormat("[HYPERGRID LINKER]: Link to {0}:{1}, in {2}-{3}", externalHostName, externalPort, xloc, yloc);
200
201 reason = string.Empty;
202 regInfo = new GridRegion();
203 regInfo.RegionName = externalRegionName;
204 regInfo.HttpPort = externalPort;
205 regInfo.ExternalHostName = externalHostName;
206 regInfo.RegionLocX = xloc;
207 regInfo.RegionLocY = yloc;
208 regInfo.ScopeID = scopeID;
209
210 try
211 {
212 regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0);
213 }
214 catch (Exception e)
215 {
216 m_log.Warn("[HYPERGRID LINKER]: Wrong format for link-region: " + e.Message);
217 reason = "Internal error";
218 return false;
219 }
220
221 // Finally, link it
222 ulong handle = 0;
223 UUID regionID = UUID.Zero;
224 string externalName = string.Empty;
225 string imageURL = string.Empty;
226 if (!m_GatekeeperConnector.LinkRegion(regInfo, out regionID, out handle, out externalName, out imageURL, out reason))
227 return false;
228
229 if (regionID != UUID.Zero)
230 {
231 GridRegion r = m_GridService.GetRegionByUUID(scopeID, regionID);
232 if (r != null)
233 {
234 m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates {0} {1}", r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize);
235 regInfo = r;
236 return true;
237 }
238
239 regInfo.RegionID = regionID;
240 Uri uri = null;
241 try
242 {
243 uri = new Uri(externalName);
244 regInfo.ExternalHostName = uri.Host;
245 regInfo.HttpPort = (uint)uri.Port;
246 }
247 catch
248 {
249 m_log.WarnFormat("[HYPERGRID LINKER]: Remote Gatekeeper at {0} provided malformed ExternalName {1}", regInfo.ExternalHostName, externalName);
250 }
251 regInfo.RegionName = regInfo.ExternalHostName + ":" + regInfo.HttpPort + ":" + regInfo.RegionName;
252 // Try get the map image
253 //regInfo.TerrainImage = m_GatekeeperConnector.GetMapImage(regionID, imageURL);
254 // I need a texture that works for this... the one I tried doesn't seem to be working
255 regInfo.TerrainImage = m_HGMapImage;
256
257 AddHyperlinkRegion(regInfo, handle);
258 m_log.Info("[HYPERGRID LINKER]: Successfully linked to region_uuid " + regInfo.RegionID);
259
260 }
261 else
262 {
263 m_log.Warn("[HYPERGRID LINKER]: Unable to link region");
264 reason = "Remote region could not be found";
265 return false;
266 }
267
268 uint x, y;
269 if (!Check4096(handle, out x, out y))
270 {
271 RemoveHyperlinkRegion(regInfo.RegionID);
272 reason = "Region is too far (" + x + ", " + y + ")";
273 m_log.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")");
274 return false;
275 }
276
277 m_log.Debug("[HYPERGRID LINKER]: link region succeeded");
278 return true;
279 }
280
281 public bool TryUnlinkRegion(string mapName)
282 {
283 GridRegion regInfo = null;
284 if (mapName.Contains(":"))
285 {
286 string host = "127.0.0.1";
287 //string portstr;
288 //string regionName = "";
289 uint port = 9000;
290 string[] parts = mapName.Split(new char[] { ':' });
291 if (parts.Length >= 1)
292 {
293 host = parts[0];
294 }
295
296 foreach (GridRegion r in m_HyperlinkRegions.Values)
297 if (host.Equals(r.ExternalHostName) && (port == r.HttpPort))
298 regInfo = r;
299 }
300 else
301 {
302 foreach (GridRegion r in m_HyperlinkRegions.Values)
303 if (r.RegionName.Equals(mapName))
304 regInfo = r;
305 }
306 if (regInfo != null)
307 {
308 RemoveHyperlinkRegion(regInfo.RegionID);
309 return true;
310 }
311 else
312 {
313 m_log.InfoFormat("[HYPERGRID LINKER]: Region {0} not found", mapName);
314 return false;
315 }
316 }
317
318 /// <summary>
319 /// Cope with this viewer limitation.
320 /// </summary>
321 /// <param name="regInfo"></param>
322 /// <returns></returns>
323 public bool Check4096(ulong realHandle, out uint x, out uint y)
324 {
325 GridRegion defRegion = DefaultRegion;
326
327 uint ux = 0, uy = 0;
328 Utils.LongToUInts(realHandle, out ux, out uy);
329 x = ux / Constants.RegionSize;
330 y = uy / Constants.RegionSize;
331
332 if ((Math.Abs((int)defRegion.RegionLocX - ux) >= 4096 * Constants.RegionSize) ||
333 (Math.Abs((int)defRegion.RegionLocY - uy) >= 4096 * Constants.RegionSize))
334 {
335 return false;
336 }
337 return true;
338 }
339
340 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle)
341 {
342 //m_HyperlinkRegions[regionInfo.RegionID] = regionInfo;
343 //m_HyperlinkHandles[regionInfo.RegionID] = regionHandle;
344
345 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo);
346 int flags = (int)OpenSim.Data.RegionFlags.Hyperlink + (int)OpenSim.Data.RegionFlags.NoDirectLogin + (int)OpenSim.Data.RegionFlags.RegionOnline;
347 rdata.Data["flags"] = flags.ToString();
348
349 m_Database.Store(rdata);
350
351 }
352
353 private void RemoveHyperlinkRegion(UUID regionID)
354 {
355 //// Try the hyperlink collection
356 //if (m_HyperlinkRegions.ContainsKey(regionID))
357 //{
358 // m_HyperlinkRegions.Remove(regionID);
359 // m_HyperlinkHandles.Remove(regionID);
360 //}
361 m_Database.Delete(regionID);
362 }
363
364 #endregion
365
366
367 #region Console Commands
368
369 public void HandleShow(string module, string[] cmd)
370 {
371 MainConsole.Instance.Output("Not Implemented Yet");
372 //if (cmd.Length != 2)
373 //{
374 // MainConsole.Instance.Output("Syntax: show hyperlinks");
375 // return;
376 //}
377 //List<GridRegion> regions = new List<GridRegion>(m_HypergridService.m_HyperlinkRegions.Values);
378 //if (regions == null || regions.Count < 1)
379 //{
380 // MainConsole.Instance.Output("No hyperlinks");
381 // return;
382 //}
383
384 //MainConsole.Instance.Output("Region Name Region UUID");
385 //MainConsole.Instance.Output("Location URI");
386 //MainConsole.Instance.Output("Owner ID ");
387 //MainConsole.Instance.Output("-------------------------------------------------------------------------------");
388 //foreach (GridRegion r in regions)
389 //{
390 // MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} \n\n",
391 // r.RegionName, r.RegionID,
392 // String.Format("{0},{1}", r.RegionLocX, r.RegionLocY), "http://" + r.ExternalHostName + ":" + r.HttpPort.ToString(),
393 // r.EstateOwner.ToString()));
394 //}
395 //return;
396 }
397 public void RunCommand(string module, string[] cmdparams)
398 {
399 List<string> args = new List<string>(cmdparams);
400 if (args.Count < 1)
401 return;
402
403 string command = args[0];
404 args.RemoveAt(0);
405
406 cmdparams = args.ToArray();
407
408 RunHGCommand(command, cmdparams);
409
410 }
411
412 private void RunHGCommand(string command, string[] cmdparams)
413 {
414 if (command.Equals("link-mapping"))
415 {
416 if (cmdparams.Length == 2)
417 {
418 try
419 {
420 m_autoMappingX = Convert.ToUInt32(cmdparams[0]);
421 m_autoMappingY = Convert.ToUInt32(cmdparams[1]);
422 m_enableAutoMapping = true;
423 }
424 catch (Exception)
425 {
426 m_autoMappingX = 0;
427 m_autoMappingY = 0;
428 m_enableAutoMapping = false;
429 }
430 }
431 }
432 else if (command.Equals("link-region"))
433 {
434 if (cmdparams.Length < 3)
435 {
436 if ((cmdparams.Length == 1) || (cmdparams.Length == 2))
437 {
438 LoadXmlLinkFile(cmdparams);
439 }
440 else
441 {
442 LinkRegionCmdUsage();
443 }
444 return;
445 }
446
447 if (cmdparams[2].Contains(":"))
448 {
449 // New format
450 int xloc, yloc;
451 string mapName;
452 try
453 {
454 xloc = Convert.ToInt32(cmdparams[0]);
455 yloc = Convert.ToInt32(cmdparams[1]);
456 mapName = cmdparams[2];
457 if (cmdparams.Length > 3)
458 for (int i = 3; i < cmdparams.Length; i++)
459 mapName += " " + cmdparams[i];
460
461 //m_log.Info(">> MapName: " + mapName);
462 }
463 catch (Exception e)
464 {
465 MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message);
466 LinkRegionCmdUsage();
467 return;
468 }
469
470 // Convert cell coordinates given by the user to meters
471 xloc = xloc * (int)Constants.RegionSize;
472 yloc = yloc * (int)Constants.RegionSize;
473 string reason = string.Empty;
474 if (TryLinkRegionToCoords(UUID.Zero, mapName, xloc, yloc, out reason) == null)
475 MainConsole.Instance.Output("Failed to link region: " + reason);
476 else
477 MainConsole.Instance.Output("Hyperlink established");
478 }
479 else
480 {
481 // old format
482 GridRegion regInfo;
483 int xloc, yloc;
484 uint externalPort;
485 string externalHostName;
486 try
487 {
488 xloc = Convert.ToInt32(cmdparams[0]);
489 yloc = Convert.ToInt32(cmdparams[1]);
490 externalPort = Convert.ToUInt32(cmdparams[3]);
491 externalHostName = cmdparams[2];
492 //internalPort = Convert.ToUInt32(cmdparams[4]);
493 //remotingPort = Convert.ToUInt32(cmdparams[5]);
494 }
495 catch (Exception e)
496 {
497 MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message);
498 LinkRegionCmdUsage();
499 return;
500 }
501
502 // Convert cell coordinates given by the user to meters
503 xloc = xloc * (int)Constants.RegionSize;
504 yloc = yloc * (int)Constants.RegionSize;
505 string reason = string.Empty;
506 if (TryCreateLink(UUID.Zero, xloc, yloc, "", externalPort, externalHostName, out regInfo, out reason))
507 {
508 if (cmdparams.Length >= 5)
509 {
510 regInfo.RegionName = "";
511 for (int i = 4; i < cmdparams.Length; i++)
512 regInfo.RegionName += cmdparams[i] + " ";
513 }
514 }
515 }
516 return;
517 }
518 else if (command.Equals("unlink-region"))
519 {
520 if (cmdparams.Length < 1)
521 {
522 UnlinkRegionCmdUsage();
523 return;
524 }
525 if (TryUnlinkRegion(cmdparams[0]))
526 MainConsole.Instance.Output("Successfully unlinked " + cmdparams[0]);
527 else
528 MainConsole.Instance.Output("Unable to unlink " + cmdparams[0] + ", region not found.");
529 }
530 }
531
532 private void LoadXmlLinkFile(string[] cmdparams)
533 {
534 //use http://www.hgurl.com/hypergrid.xml for test
535 try
536 {
537 XmlReader r = XmlReader.Create(cmdparams[0]);
538 XmlConfigSource cs = new XmlConfigSource(r);
539 string[] excludeSections = null;
540
541 if (cmdparams.Length == 2)
542 {
543 if (cmdparams[1].ToLower().StartsWith("excludelist:"))
544 {
545 string excludeString = cmdparams[1].ToLower();
546 excludeString = excludeString.Remove(0, 12);
547 char[] splitter = { ';' };
548
549 excludeSections = excludeString.Split(splitter);
550 }
551 }
552
553 for (int i = 0; i < cs.Configs.Count; i++)
554 {
555 bool skip = false;
556 if ((excludeSections != null) && (excludeSections.Length > 0))
557 {
558 for (int n = 0; n < excludeSections.Length; n++)
559 {
560 if (excludeSections[n] == cs.Configs[i].Name.ToLower())
561 {
562 skip = true;
563 break;
564 }
565 }
566 }
567 if (!skip)
568 {
569 ReadLinkFromConfig(cs.Configs[i]);
570 }
571 }
572 }
573 catch (Exception e)
574 {
575 m_log.Error(e.ToString());
576 }
577 }
578
579
580 private void ReadLinkFromConfig(IConfig config)
581 {
582 GridRegion regInfo;
583 int xloc, yloc;
584 uint externalPort;
585 string externalHostName;
586 uint realXLoc, realYLoc;
587
588 xloc = Convert.ToInt32(config.GetString("xloc", "0"));
589 yloc = Convert.ToInt32(config.GetString("yloc", "0"));
590 externalPort = Convert.ToUInt32(config.GetString("externalPort", "0"));
591 externalHostName = config.GetString("externalHostName", "");
592 realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0"));
593 realYLoc = Convert.ToUInt32(config.GetString("real-yloc", "0"));
594
595 if (m_enableAutoMapping)
596 {
597 xloc = (int)((xloc % 100) + m_autoMappingX);
598 yloc = (int)((yloc % 100) + m_autoMappingY);
599 }
600
601 if (((realXLoc == 0) && (realYLoc == 0)) ||
602 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) &&
603 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896))))
604 {
605 xloc = xloc * (int)Constants.RegionSize;
606 yloc = yloc * (int)Constants.RegionSize;
607 string reason = string.Empty;
608 if (TryCreateLink(UUID.Zero, xloc, yloc, "", externalPort,
609 externalHostName, out regInfo, out reason))
610 {
611 regInfo.RegionName = config.GetString("localName", "");
612 }
613 else
614 MainConsole.Instance.Output("Unable to link " + externalHostName + ": " + reason);
615 }
616 }
617
618
619 private void LinkRegionCmdUsage()
620 {
621 MainConsole.Instance.Output("Usage: link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>]");
622 MainConsole.Instance.Output("Usage: link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]");
623 MainConsole.Instance.Output("Usage: link-region <URI_of_xml> [<exclude>]");
624 }
625
626 private void UnlinkRegionCmdUsage()
627 {
628 MainConsole.Instance.Output("Usage: unlink-region <HostName>:<HttpPort>");
629 MainConsole.Instance.Output("Usage: unlink-region <LocalName>");
630 }
631
632 #endregion
633
634 }
635}