aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs')
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs795
1 files changed, 795 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
new file mode 100644
index 0000000..148331b
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
@@ -0,0 +1,795 @@
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 OpenSim.Framework.Communications.Cache;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Region.Framework.Scenes.Hypergrid;
39using OpenSim.Services.Interfaces;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41using OpenSim.Server.Base;
42using OpenSim.Services.Connectors.Grid;
43using OpenSim.Framework.Console;
44
45using OpenMetaverse;
46using log4net;
47using Nini.Config;
48
49namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
50{
51 public class HGGridConnector : ISharedRegionModule, IGridService, IHyperlinkService
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56 private static string LocalAssetServerURI, LocalInventoryServerURI, LocalUserServerURI;
57
58 private bool m_Enabled = false;
59 private bool m_Initialized = false;
60
61 private Scene m_aScene;
62 private Dictionary<ulong, Scene> m_LocalScenes = new Dictionary<ulong, Scene>();
63
64 private IGridService m_GridServiceConnector;
65 private HypergridServiceConnector m_HypergridServiceConnector;
66
67 // Hyperlink regions are hyperlinks on the map
68 protected Dictionary<UUID, GridRegion> m_HyperlinkRegions = new Dictionary<UUID, GridRegion>();
69
70 // Known regions are home regions of visiting foreign users.
71 // They are not on the map as static hyperlinks. They are dynamic hyperlinks, they go away when
72 // the visitor goes away. They are mapped to X=0 on the map.
73 // This is key-ed on agent ID
74 protected Dictionary<UUID, GridRegion> m_knownRegions = new Dictionary<UUID, GridRegion>();
75
76 protected Dictionary<UUID, ulong> m_HyperlinkHandles = new Dictionary<UUID, ulong>();
77
78 #region ISharedRegionModule
79
80 public Type ReplaceableInterface
81 {
82 get { return null; }
83 }
84
85 public string Name
86 {
87 get { return "HGGridServicesConnector"; }
88 }
89
90 public void Initialise(IConfigSource source)
91 {
92 IConfig moduleConfig = source.Configs["Modules"];
93 if (moduleConfig != null)
94 {
95 string name = moduleConfig.GetString("GridServices", "");
96 if (name == Name)
97 {
98 IConfig gridConfig = source.Configs["GridService"];
99 if (gridConfig == null)
100 {
101 m_log.Error("[HGGRID CONNECTOR]: GridService missing from OpenSim.ini");
102 return;
103 }
104
105
106 InitialiseConnectorModule(source);
107
108 m_Enabled = true;
109 m_log.Info("[HGGRID CONNECTOR]: HG grid enabled");
110 }
111 }
112 }
113
114 private void InitialiseConnectorModule(IConfigSource source)
115 {
116 IConfig gridConfig = source.Configs["GridService"];
117 if (gridConfig == null)
118 {
119 m_log.Error("[HGGRID CONNECTOR]: GridService missing from OpenSim.ini");
120 throw new Exception("Grid connector init error");
121 }
122
123 string module = gridConfig.GetString("GridServiceConnectorModule", String.Empty);
124 if (module == String.Empty)
125 {
126 m_log.Error("[HGGRID CONNECTOR]: No GridServiceConnectorModule named in section GridService");
127 //return;
128 throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's");
129 }
130
131 Object[] args = new Object[] { source };
132 m_GridServiceConnector = ServerUtils.LoadPlugin<IGridService>(module, args);
133
134 }
135
136 public void PostInitialise()
137 {
138 if (m_Enabled)
139 ((ISharedRegionModule)m_GridServiceConnector).PostInitialise();
140 }
141
142 public void Close()
143 {
144 }
145
146 public void AddRegion(Scene scene)
147 {
148 if (!m_Enabled)
149 return;
150
151 m_LocalScenes[scene.RegionInfo.RegionHandle] = scene;
152 scene.RegisterModuleInterface<IGridService>(this);
153 scene.RegisterModuleInterface<IHyperlinkService>(this);
154
155 ((ISharedRegionModule)m_GridServiceConnector).AddRegion(scene);
156
157 }
158
159 public void RemoveRegion(Scene scene)
160 {
161 if (m_Enabled)
162 {
163 m_LocalScenes.Remove(scene.RegionInfo.RegionHandle);
164 ((ISharedRegionModule)m_GridServiceConnector).RemoveRegion(scene);
165 }
166 }
167
168 public void RegionLoaded(Scene scene)
169 {
170 if (!m_Enabled)
171 return;
172
173 if (!m_Initialized)
174 {
175 m_aScene = scene;
176 LocalAssetServerURI = m_aScene.CommsManager.NetworkServersInfo.UserURL;
177 LocalInventoryServerURI = m_aScene.CommsManager.NetworkServersInfo.InventoryURL;
178 LocalUserServerURI = m_aScene.CommsManager.NetworkServersInfo.UserURL;
179
180 m_HypergridServiceConnector = new HypergridServiceConnector(scene.AssetService);
181
182 HGCommands hgCommands = new HGCommands(this, scene);
183 MainConsole.Instance.Commands.AddCommand("HGGridServicesConnector", false, "link-region",
184 "link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>] <cr>",
185 "Link a hypergrid region", hgCommands.RunCommand);
186 MainConsole.Instance.Commands.AddCommand("HGGridServicesConnector", false, "unlink-region",
187 "unlink-region <local name> or <HostName>:<HttpPort> <cr>",
188 "Unlink a hypergrid region", hgCommands.RunCommand);
189 MainConsole.Instance.Commands.AddCommand("HGGridServicesConnector", false, "link-mapping", "link-mapping [<x> <y>] <cr>",
190 "Set local coordinate to map HG regions to", hgCommands.RunCommand);
191
192 // Yikes!! Remove this as soon as user services get refactored
193 HGNetworkServersInfo.Init(LocalAssetServerURI, LocalInventoryServerURI, LocalUserServerURI);
194
195 m_Initialized = true;
196 }
197 }
198
199 #endregion
200
201 #region IGridService
202
203 public bool RegisterRegion(UUID scopeID, GridRegion regionInfo)
204 {
205 // Region doesn't exist here. Trying to link remote region
206 if (regionInfo.RegionID.Equals(UUID.Zero))
207 {
208 m_log.Info("[HGrid]: Linking remote region " + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort);
209 ulong regionHandle = 0;
210 regionInfo.RegionID = m_HypergridServiceConnector.LinkRegion(regionInfo, out regionHandle);
211 if (!regionInfo.RegionID.Equals(UUID.Zero))
212 {
213 AddHyperlinkRegion(regionInfo, regionHandle);
214 m_log.Info("[HGrid]: Successfully linked to region_uuid " + regionInfo.RegionID);
215
216 // Try get the map image
217 m_HypergridServiceConnector.GetMapImage(regionInfo);
218 return true;
219 }
220 else
221 {
222 m_log.Info("[HGrid]: No such region " + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort + "(" + regionInfo.InternalEndPoint.Port + ")");
223 return false;
224 }
225 // Note that these remote regions aren't registered in localBackend, so return null, no local listeners
226 }
227 else // normal grid
228 return m_GridServiceConnector.RegisterRegion(scopeID, regionInfo);
229 }
230
231 public bool DeregisterRegion(UUID regionID)
232 {
233 // Try the hyperlink collection
234 if (m_HyperlinkRegions.ContainsKey(regionID))
235 {
236 RemoveHyperlinkRegion(regionID);
237 return true;
238 }
239 // Try the foreign users home collection
240
241 foreach (GridRegion r in m_knownRegions.Values)
242 if (r.RegionID == regionID)
243 {
244 RemoveHyperlinkHomeRegion(regionID);
245 return true;
246 }
247
248 // Finally, try the normal route
249 return m_GridServiceConnector.DeregisterRegion(regionID);
250 }
251
252 public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID)
253 {
254 // No serving neighbours on hyperliked regions.
255 // Just the regular regions.
256 return m_GridServiceConnector.GetNeighbours(scopeID, regionID);
257 }
258
259 public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
260 {
261 // Try the hyperlink collection
262 if (m_HyperlinkRegions.ContainsKey(regionID))
263 return m_HyperlinkRegions[regionID];
264
265 // Try the foreign users home collection
266 foreach (GridRegion r in m_knownRegions.Values)
267 if (r.RegionID == regionID)
268 return r;
269
270 // Finally, try the normal route
271 return m_GridServiceConnector.GetRegionByUUID(scopeID, regionID);
272 }
273
274 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
275 {
276 int snapX = (int) (x / Constants.RegionSize) * (int)Constants.RegionSize;
277 int snapY = (int) (y / Constants.RegionSize) * (int)Constants.RegionSize;
278 // Try the hyperlink collection
279 foreach (GridRegion r in m_HyperlinkRegions.Values)
280 {
281 if ((r.RegionLocX == snapX) && (r.RegionLocY == snapY))
282 return r;
283 }
284
285 // Try the foreign users home collection
286 foreach (GridRegion r in m_knownRegions.Values)
287 {
288 if ((r.RegionLocX == snapX) && (r.RegionLocY == snapY))
289 {
290 return r;
291 }
292 }
293
294 // Finally, try the normal route
295 return m_GridServiceConnector.GetRegionByPosition(scopeID, x, y);
296 }
297
298 public GridRegion GetRegionByName(UUID scopeID, string regionName)
299 {
300 // Try normal grid first
301 GridRegion region = m_GridServiceConnector.GetRegionByName(scopeID, regionName);
302 if (region != null)
303 return region;
304
305 // Try the hyperlink collection
306 foreach (GridRegion r in m_HyperlinkRegions.Values)
307 {
308 if (r.RegionName == regionName)
309 return r;
310 }
311
312 // Try the foreign users home collection
313 foreach (GridRegion r in m_knownRegions.Values)
314 {
315 if (r.RegionName == regionName)
316 return r;
317 }
318 return null;
319 }
320
321 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
322 {
323 List<GridRegion> rinfos = new List<GridRegion>();
324
325 // Commenting until regionname exists
326 //foreach (SimpleRegionInfo r in m_HyperlinkRegions.Values)
327 // if ((r.RegionName != null) && r.RegionName.StartsWith(name))
328 // rinfos.Add(r);
329
330 rinfos.AddRange(m_GridServiceConnector.GetRegionsByName(scopeID, name, maxNumber));
331 return rinfos;
332 }
333
334 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
335 {
336 int snapXmin = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize;
337 int snapXmax = (int)(xmax / Constants.RegionSize) * (int)Constants.RegionSize;
338 int snapYmin = (int)(ymin / Constants.RegionSize) * (int)Constants.RegionSize;
339 int snapYmax = (int)(ymax / Constants.RegionSize) * (int)Constants.RegionSize;
340
341 List<GridRegion> rinfos = new List<GridRegion>();
342 foreach (GridRegion r in m_HyperlinkRegions.Values)
343 if ((r.RegionLocX > snapXmin) && (r.RegionLocX < snapYmax) &&
344 (r.RegionLocY > snapYmin) && (r.RegionLocY < snapYmax))
345 rinfos.Add(r);
346
347 rinfos.AddRange(m_GridServiceConnector.GetRegionRange(scopeID, xmin, xmax, ymin, ymax));
348
349 return rinfos;
350 }
351
352 #endregion
353
354 #region Auxiliary
355
356 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle)
357 {
358 m_HyperlinkRegions[regionInfo.RegionID] = regionInfo;
359 m_HyperlinkHandles[regionInfo.RegionID] = regionHandle;
360 }
361
362 private void RemoveHyperlinkRegion(UUID regionID)
363 {
364 m_HyperlinkRegions.Remove(regionID);
365 m_HyperlinkHandles.Remove(regionID);
366 }
367
368 private void AddHyperlinkHomeRegion(UUID userID, GridRegion regionInfo, ulong regionHandle)
369 {
370 m_knownRegions[userID] = regionInfo;
371 m_HyperlinkHandles[regionInfo.RegionID] = regionHandle;
372 }
373
374 private void RemoveHyperlinkHomeRegion(UUID regionID)
375 {
376 foreach (KeyValuePair<UUID, GridRegion> kvp in m_knownRegions)
377 {
378 if (kvp.Value.RegionID == regionID)
379 {
380 m_knownRegions.Remove(kvp.Key);
381 }
382 }
383 m_HyperlinkHandles.Remove(regionID);
384 }
385 #endregion
386
387 #region IHyperlinkService
388
389 private static Random random = new Random();
390
391
392 public GridRegion TryLinkRegionToCoords(Scene m_scene, IClientAPI client, string mapName, int xloc, int yloc)
393 {
394 string host = "127.0.0.1";
395 string portstr;
396 string regionName = "";
397 uint port = 9000;
398 string[] parts = mapName.Split(new char[] { ':' });
399 if (parts.Length >= 1)
400 {
401 host = parts[0];
402 }
403 if (parts.Length >= 2)
404 {
405 portstr = parts[1];
406 if (!UInt32.TryParse(portstr, out port))
407 regionName = parts[1];
408 }
409 // always take the last one
410 if (parts.Length >= 3)
411 {
412 regionName = parts[2];
413 }
414
415 // Sanity check. Don't ever link to this sim.
416 IPAddress ipaddr = null;
417 try
418 {
419 ipaddr = Util.GetHostFromDNS(host);
420 }
421 catch { }
422
423 if ((ipaddr != null) &&
424 !((m_scene.RegionInfo.ExternalEndPoint.Address.Equals(ipaddr)) && (m_scene.RegionInfo.HttpPort == port)))
425 {
426 GridRegion regInfo;
427 bool success = TryCreateLink(m_scene, client, xloc, yloc, regionName, port, host, out regInfo);
428 if (success)
429 {
430 regInfo.RegionName = mapName;
431 return regInfo;
432 }
433 }
434
435 return null;
436 }
437
438
439 // From the map search and secondlife://blah
440 public GridRegion TryLinkRegion(Scene m_scene, IClientAPI client, string mapName)
441 {
442 int xloc = random.Next(0, Int16.MaxValue) * (int) Constants.RegionSize;
443 return TryLinkRegionToCoords(m_scene, client, mapName, xloc, 0);
444 }
445
446 public bool TryCreateLink(Scene m_scene, IClientAPI client, int xloc, int yloc,
447 string externalRegionName, uint externalPort, string externalHostName, out GridRegion regInfo)
448 {
449 m_log.DebugFormat("[HGrid]: Link to {0}:{1}, in {2}-{3}", externalHostName, externalPort, xloc, yloc);
450
451 regInfo = new GridRegion();
452 regInfo.RegionName = externalRegionName;
453 regInfo.HttpPort = externalPort;
454 regInfo.ExternalHostName = externalHostName;
455 regInfo.RegionLocX = xloc;
456 regInfo.RegionLocY = yloc;
457
458 try
459 {
460 regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0);
461 }
462 catch (Exception e)
463 {
464 m_log.Warn("[HGrid]: Wrong format for link-region: " + e.Message);
465 return false;
466 }
467
468 // Finally, link it
469 if (!RegisterRegion(UUID.Zero, regInfo))
470 {
471 m_log.Warn("[HGrid]: Unable to link region");
472 return false;
473 }
474
475 int x, y;
476 if (!Check4096(m_scene, regInfo, out x, out y))
477 {
478 DeregisterRegion(regInfo.RegionID);
479 if (client != null)
480 client.SendAlertMessage("Region is too far (" + x + ", " + y + ")");
481 m_log.Info("[HGrid]: Unable to link, region is too far (" + x + ", " + y + ")");
482 return false;
483 }
484
485 if (!CheckCoords(m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, x, y))
486 {
487 DeregisterRegion(regInfo.RegionID);
488 if (client != null)
489 client.SendAlertMessage("Region has incompatible coordinates (" + x + ", " + y + ")");
490 m_log.Info("[HGrid]: Unable to link, region has incompatible coordinates (" + x + ", " + y + ")");
491 return false;
492 }
493
494 m_log.Debug("[HGrid]: link region succeeded");
495 return true;
496 }
497
498 public bool TryUnlinkRegion(Scene m_scene, string mapName)
499 {
500 GridRegion regInfo = null;
501 if (mapName.Contains(":"))
502 {
503 string host = "127.0.0.1";
504 //string portstr;
505 //string regionName = "";
506 uint port = 9000;
507 string[] parts = mapName.Split(new char[] { ':' });
508 if (parts.Length >= 1)
509 {
510 host = parts[0];
511 }
512 // if (parts.Length >= 2)
513 // {
514 // portstr = parts[1];
515 // if (!UInt32.TryParse(portstr, out port))
516 // regionName = parts[1];
517 // }
518 // always take the last one
519 // if (parts.Length >= 3)
520 // {
521 // regionName = parts[2];
522 // }
523 foreach (GridRegion r in m_HyperlinkRegions.Values)
524 if (host.Equals(r.ExternalHostName) && (port == r.HttpPort))
525 regInfo = r;
526 }
527 else
528 {
529 foreach (GridRegion r in m_HyperlinkRegions.Values)
530 if (r.RegionName.Equals(mapName))
531 regInfo = r;
532 }
533 if (regInfo != null)
534 {
535 return DeregisterRegion(regInfo.RegionID);
536 }
537 else
538 {
539 m_log.InfoFormat("[HGrid]: Region {0} not found", mapName);
540 return false;
541 }
542 }
543
544 /// <summary>
545 /// Cope with this viewer limitation.
546 /// </summary>
547 /// <param name="regInfo"></param>
548 /// <returns></returns>
549 public bool Check4096(Scene m_scene, GridRegion regInfo, out int x, out int y)
550 {
551 ulong realHandle = m_HyperlinkHandles[regInfo.RegionID];
552 uint ux = 0, uy = 0;
553 Utils.LongToUInts(realHandle, out ux, out uy);
554 x = (int)(ux / Constants.RegionSize);
555 y = (int)(uy / Constants.RegionSize);
556
557 if ((Math.Abs((int)m_scene.RegionInfo.RegionLocX - x) >= 4096) ||
558 (Math.Abs((int)m_scene.RegionInfo.RegionLocY - y) >= 4096))
559 {
560 return false;
561 }
562 return true;
563 }
564
565 public bool CheckCoords(uint thisx, uint thisy, int x, int y)
566 {
567 if ((thisx == x) && (thisy == y))
568 return false;
569 return true;
570 }
571
572 public GridRegion TryLinkRegion(IClientAPI client, string regionDescriptor)
573 {
574 return TryLinkRegion((Scene)client.Scene, client, regionDescriptor);
575 }
576
577 public GridRegion GetHyperlinkRegion(ulong handle)
578 {
579 foreach (GridRegion r in m_HyperlinkRegions.Values)
580 if (r.RegionHandle == handle)
581 return r;
582 foreach (GridRegion r in m_knownRegions.Values)
583 if (r.RegionHandle == handle)
584 return r;
585 return null;
586 }
587
588 public ulong FindRegionHandle(ulong handle)
589 {
590 foreach (GridRegion r in m_HyperlinkRegions.Values)
591 if ((r.RegionHandle == handle) && (m_HyperlinkHandles.ContainsKey(r.RegionID)))
592 return m_HyperlinkHandles[r.RegionID];
593
594 foreach (GridRegion r in m_knownRegions.Values)
595 if ((r.RegionHandle == handle) && (m_HyperlinkHandles.ContainsKey(r.RegionID)))
596 return m_HyperlinkHandles[r.RegionID];
597
598 return handle;
599 }
600
601 public bool SendUserInformation(GridRegion regInfo, AgentCircuitData agentData)
602 {
603 CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(agentData.AgentID);
604
605 if ((IsLocalUser(uinfo) && (GetHyperlinkRegion(regInfo.RegionHandle) != null)) ||
606 (!IsLocalUser(uinfo) && !IsGoingHome(uinfo, regInfo)))
607 {
608 m_log.Info("[HGrid]: Local user is going to foreign region or foreign user is going elsewhere");
609
610 // Set the position of the region on the remote grid
611 ulong realHandle = FindRegionHandle(regInfo.RegionHandle);
612 uint x = 0, y = 0;
613 Utils.LongToUInts(regInfo.RegionHandle, out x, out y);
614 GridRegion clonedRegion = new GridRegion(regInfo);
615 clonedRegion.RegionLocX = (int)x;
616 clonedRegion.RegionLocY = (int)y;
617
618 // Get the user's home region information
619 GridRegion home = m_aScene.GridService.GetRegionByUUID(m_aScene.RegionInfo.ScopeID, uinfo.UserProfile.HomeRegionID);
620
621 // Get the user's service URLs
622 string serverURI = "";
623 if (uinfo.UserProfile is ForeignUserProfileData)
624 serverURI = Util.ServerURI(((ForeignUserProfileData)uinfo.UserProfile).UserServerURI);
625 string userServer = (serverURI == "") || (serverURI == null) ? LocalUserServerURI : serverURI;
626
627 string assetServer = Util.ServerURI(uinfo.UserProfile.UserAssetURI);
628 if ((assetServer == null) || (assetServer == ""))
629 assetServer = LocalAssetServerURI;
630
631 string inventoryServer = Util.ServerURI(uinfo.UserProfile.UserInventoryURI);
632 if ((inventoryServer == null) || (inventoryServer == ""))
633 inventoryServer = LocalInventoryServerURI;
634
635 if (!m_HypergridServiceConnector.InformRegionOfUser(clonedRegion, agentData, home, userServer, assetServer, inventoryServer))
636 {
637 m_log.Warn("[HGrid]: Could not inform remote region of transferring user.");
638 return false;
639 }
640 }
641 //if ((uinfo == null) || !IsGoingHome(uinfo, regInfo))
642 //{
643 // m_log.Info("[HGrid]: User seems to be going to foreign region.");
644 // if (!InformRegionOfUser(regInfo, agentData))
645 // {
646 // m_log.Warn("[HGrid]: Could not inform remote region of transferring user.");
647 // return false;
648 // }
649 //}
650 //else
651 // m_log.Info("[HGrid]: User seems to be going home " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
652
653 // May need to change agent's name
654 if (IsLocalUser(uinfo) && (GetHyperlinkRegion(regInfo.RegionHandle) != null))
655 {
656 agentData.firstname = agentData.firstname + "." + agentData.lastname;
657 agentData.lastname = "@" + LocalUserServerURI.Replace("http://", ""); ; //HGNetworkServersInfo.Singleton.LocalUserServerURI;
658 }
659
660 return true;
661 }
662
663 public void AdjustUserInformation(AgentCircuitData agentData)
664 {
665 CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(agentData.AgentID);
666 if ((uinfo != null) && (uinfo.UserProfile != null) &&
667 (IsLocalUser(uinfo) || !(uinfo.UserProfile is ForeignUserProfileData)))
668 {
669 //m_log.Debug("---------------> Local User!");
670 string[] parts = agentData.firstname.Split(new char[] { '.' });
671 if (parts.Length == 2)
672 {
673 agentData.firstname = parts[0];
674 agentData.lastname = parts[1];
675 }
676 }
677 //else
678 // m_log.Debug("---------------> Foreign User!");
679 }
680
681 // Check if a local user exists with the same UUID as the incoming foreign user
682 public bool CheckUserAtEntry(UUID userID, UUID sessionID, out bool comingHome)
683 {
684 comingHome = false;
685 if (!m_aScene.SceneGridService.RegionLoginsEnabled)
686 return false;
687
688 CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
689 if (uinfo != null)
690 {
691 // uh-oh we have a potential intruder
692 if (uinfo.SessionID != sessionID)
693 // can't have a foreigner with a local UUID
694 return false;
695 else
696 // oh, so it's you! welcome back
697 comingHome = true;
698 }
699
700 // OK, user can come in
701 return true;
702 }
703
704 public void AcceptUser(ForeignUserProfileData user, GridRegion home)
705 {
706 m_aScene.CommsManager.UserProfileCacheService.PreloadUserCache(user);
707 ulong realHandle = home.RegionHandle;
708 // Change the local coordinates
709 // X=0 on the map
710 home.RegionLocX = 0;
711 home.RegionLocY = random.Next(0, 10000) * (int)Constants.RegionSize;
712
713 AddHyperlinkHomeRegion(user.ID, home, realHandle);
714
715 DumpUserData(user);
716 DumpRegionData(home);
717
718 }
719
720 public bool IsLocalUser(UUID userID)
721 {
722 CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
723 return IsLocalUser(uinfo);
724 }
725
726 #endregion
727
728 #region IHyperlink Misc
729
730 protected bool IsComingHome(ForeignUserProfileData userData)
731 {
732 return (userData.UserServerURI == LocalUserServerURI);
733 }
734
735 // Is the user going back to the home region or the home grid?
736 protected bool IsGoingHome(CachedUserInfo uinfo, GridRegion rinfo)
737 {
738 if (uinfo.UserProfile == null)
739 return false;
740
741 if (!(uinfo.UserProfile is ForeignUserProfileData))
742 // it's a home user, can't be outside to return home
743 return false;
744
745 // OK, it's a foreign user with a ForeignUserProfileData
746 // and is going back to exactly the home region.
747 // We can't check if it's going back to a non-home region
748 // of the home grid. That will be dealt with in the
749 // receiving end
750 return (uinfo.UserProfile.HomeRegionID == rinfo.RegionID);
751 }
752
753 protected bool IsLocalUser(CachedUserInfo uinfo)
754 {
755 if (uinfo == null)
756 return false;
757
758 return !(uinfo.UserProfile is ForeignUserProfileData);
759
760 }
761
762 protected bool IsLocalRegion(ulong handle)
763 {
764 return m_LocalScenes.ContainsKey(handle);
765 }
766
767 private void DumpUserData(ForeignUserProfileData userData)
768 {
769 m_log.Info(" ------------ User Data Dump ----------");
770 m_log.Info(" >> Name: " + userData.FirstName + " " + userData.SurName);
771 m_log.Info(" >> HomeID: " + userData.HomeRegionID);
772 m_log.Info(" >> UserServer: " + userData.UserServerURI);
773 m_log.Info(" >> InvServer: " + userData.UserInventoryURI);
774 m_log.Info(" >> AssetServer: " + userData.UserAssetURI);
775 m_log.Info(" ------------ -------------- ----------");
776 }
777
778 private void DumpRegionData(GridRegion rinfo)
779 {
780 m_log.Info(" ------------ Region Data Dump ----------");
781 m_log.Info(" >> handle: " + rinfo.RegionHandle);
782 m_log.Info(" >> coords: " + rinfo.RegionLocX + ", " + rinfo.RegionLocY);
783 m_log.Info(" >> external host name: " + rinfo.ExternalHostName);
784 m_log.Info(" >> http port: " + rinfo.HttpPort);
785 m_log.Info(" >> external EP address: " + rinfo.ExternalEndPoint.Address);
786 m_log.Info(" >> external EP port: " + rinfo.ExternalEndPoint.Port);
787 m_log.Info(" ------------ -------------- ----------");
788 }
789
790
791 #endregion
792
793
794 }
795}