diff options
author | Justin Clarke Casey | 2008-11-25 15:19:00 +0000 |
---|---|---|
committer | Justin Clarke Casey | 2008-11-25 15:19:00 +0000 |
commit | e187972377c19bdd85093677c4c54034e4f9196e (patch) | |
tree | cc1bb5f003628b018b823eafc9ee0a67f98df31c /OpenSim/Region/Communications/Hypergrid/HGGridServices.cs | |
parent | * Adding some virtual hooks and making some privaets protected for great just... (diff) | |
download | opensim-SC_OLD-e187972377c19bdd85093677c4c54034e4f9196e.zip opensim-SC_OLD-e187972377c19bdd85093677c4c54034e4f9196e.tar.gz opensim-SC_OLD-e187972377c19bdd85093677c4c54034e4f9196e.tar.bz2 opensim-SC_OLD-e187972377c19bdd85093677c4c54034e4f9196e.tar.xz |
* Apply http://opensimulator.org/mantis/view.php?id=2640
* This is Diva's hypergrid patch, as perviously discussed on the opensim-dev mailing list
* Applied some minor prebuild.xml jiggling to resolve a dependency issue
* Thanks Diva!
Diffstat (limited to 'OpenSim/Region/Communications/Hypergrid/HGGridServices.cs')
-rw-r--r-- | OpenSim/Region/Communications/Hypergrid/HGGridServices.cs | 1294 |
1 files changed, 1294 insertions, 0 deletions
diff --git a/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs b/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs new file mode 100644 index 0000000..5433e41 --- /dev/null +++ b/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs | |||
@@ -0,0 +1,1294 @@ | |||
1 | /** | ||
2 | * Copyright (c) 2008, Contributors. All rights reserved. | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without modification, | ||
6 | * are permitted provided that the following conditions are met: | ||
7 | * | ||
8 | * * Redistributions of source code must retain the above copyright notice, | ||
9 | * this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright notice, | ||
11 | * this list of conditions and the following disclaimer in the documentation | ||
12 | * and/or other materials provided with the distribution. | ||
13 | * * Neither the name of the Organizations nor the names of Individual | ||
14 | * Contributors may be used to endorse or promote products derived from | ||
15 | * this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | ||
20 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | ||
22 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | ||
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
25 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | |||
30 | using System; | ||
31 | using System.Collections; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Drawing; | ||
34 | using System.Drawing.Drawing2D; | ||
35 | using System.Drawing.Imaging; | ||
36 | using System.IO; | ||
37 | using System.Net; | ||
38 | using System.Net.Sockets; | ||
39 | using System.Reflection; | ||
40 | using System.Runtime.Remoting; | ||
41 | using System.Runtime.Remoting.Channels; | ||
42 | using System.Runtime.Remoting.Channels.Tcp; | ||
43 | using System.Security.Authentication; | ||
44 | using System.Threading; | ||
45 | using OpenMetaverse; | ||
46 | using OpenMetaverse.Imaging; | ||
47 | using log4net; | ||
48 | using Nwc.XmlRpc; | ||
49 | using OpenSim.Framework; | ||
50 | using OpenSim.Framework.Communications; | ||
51 | using OpenSim.Framework.Communications.Cache; | ||
52 | using OpenSim.Framework.Servers; | ||
53 | using OpenSim.Region.Communications.Local; | ||
54 | using OpenSim.Region.Communications.OGS1; | ||
55 | using OpenSim.Region.Environment.Modules.Framework; | ||
56 | using OpenSim.Region.Environment.Scenes; | ||
57 | using OpenSim.Region.Interfaces; | ||
58 | |||
59 | namespace OpenSim.Region.Communications.Hypergrid | ||
60 | { | ||
61 | /// <summary> | ||
62 | /// This class encapsulates the main hypergrid functions related to creating and managing | ||
63 | /// hyperlinks, as well as processing all the inter-region comms between a region and | ||
64 | /// an hyperlinked region. | ||
65 | /// </summary> | ||
66 | public class HGGridServices : IGridServices, IInterRegionCommunications, IHyperlink | ||
67 | { | ||
68 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
69 | |||
70 | |||
71 | public BaseHttpServer httpListener; | ||
72 | public NetworkServersInfo serversInfo; | ||
73 | public BaseHttpServer httpServer; | ||
74 | |||
75 | protected List<RegionInfo> m_regionsOnInstance = new List<RegionInfo>(); | ||
76 | |||
77 | // Hyperlink regions are hyperlinks on the map | ||
78 | protected List<RegionInfo> m_hyperlinkRegions = new List<RegionInfo>(); | ||
79 | |||
80 | // Known regions are home regions of visiting foreign users. | ||
81 | // They are not on the map as static hyperlinks. They are dynamic hyperlinks, they go away when | ||
82 | // the visitor goes away. They are mapped to X=0 on the map. | ||
83 | // This is key-ed on agent ID | ||
84 | protected Dictionary<UUID, RegionInfo> m_knownRegions = new Dictionary<UUID, RegionInfo>(); | ||
85 | |||
86 | protected AssetCache m_assetcache; | ||
87 | protected UserProfileCacheService m_userProfileCache; | ||
88 | protected SceneManager m_sceneman; | ||
89 | |||
90 | private Dictionary<string, string> m_queuedGridSettings = new Dictionary<string, string>(); | ||
91 | |||
92 | public virtual string gdebugRegionName | ||
93 | { | ||
94 | get { return "Override me"; } | ||
95 | set { ; } | ||
96 | } | ||
97 | |||
98 | public string rdebugRegionName | ||
99 | { | ||
100 | get { return _rdebugRegionName; } | ||
101 | set { _rdebugRegionName = value; } | ||
102 | } | ||
103 | private string _rdebugRegionName = String.Empty; | ||
104 | |||
105 | public virtual bool RegionLoginsEnabled | ||
106 | { | ||
107 | get { return true; } | ||
108 | set { ; } | ||
109 | } | ||
110 | |||
111 | public UserProfileCacheService UserProfileCache | ||
112 | { | ||
113 | set { m_userProfileCache = value; } | ||
114 | } | ||
115 | |||
116 | /// <summary> | ||
117 | /// Contructor. Adds "expect_hg_user" and "check" xmlrpc method handlers | ||
118 | /// </summary> | ||
119 | /// <param name="servers_info"></param> | ||
120 | /// <param name="httpServe"></param> | ||
121 | public HGGridServices(NetworkServersInfo servers_info, BaseHttpServer httpServe, AssetCache asscache, SceneManager sman) | ||
122 | { | ||
123 | serversInfo = servers_info; | ||
124 | httpServer = httpServe; | ||
125 | m_assetcache = asscache; | ||
126 | m_sceneman = sman; | ||
127 | |||
128 | httpServer.AddXmlRPCHandler("link_region", LinkRegionRequest); | ||
129 | httpServer.AddXmlRPCHandler("expect_hg_user", ExpectHGUser); | ||
130 | |||
131 | HGNetworkServersInfo.Init(servers_info.AssetURL, servers_info.InventoryURL, servers_info.UserURL); | ||
132 | } | ||
133 | |||
134 | // see IGridServices | ||
135 | public virtual RegionCommsListener RegisterRegion(RegionInfo regionInfo) | ||
136 | { | ||
137 | // Region doesn't exist here. Trying to link remote region | ||
138 | |||
139 | m_log.Info("[HGrid]: Linking remote region " + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort ); | ||
140 | regionInfo.RegionID = LinkRegion(regionInfo); // UUID.Random(); | ||
141 | if (!regionInfo.RegionID.Equals(UUID.Zero)) | ||
142 | { | ||
143 | m_hyperlinkRegions.Add(regionInfo); | ||
144 | m_log.Info("[HGrid]: Successfully linked to region_uuid " + regionInfo.RegionID); | ||
145 | |||
146 | //Try get the map image | ||
147 | GetMapImage(regionInfo); | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | m_log.Info("[HGrid]: No such region " + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort + "(" + regionInfo.InternalEndPoint.Port + ")"); | ||
152 | } | ||
153 | // Note that these remote regions aren't registered in localBackend, so return null, no local listeners | ||
154 | return null; | ||
155 | } | ||
156 | |||
157 | // see IGridServices | ||
158 | public virtual bool DeregisterRegion(RegionInfo regionInfo) | ||
159 | { | ||
160 | if (m_hyperlinkRegions.Contains(regionInfo)) | ||
161 | { | ||
162 | m_hyperlinkRegions.Remove(regionInfo); | ||
163 | return true; | ||
164 | } | ||
165 | foreach (KeyValuePair<UUID, RegionInfo> kvp in m_knownRegions) | ||
166 | { | ||
167 | if (kvp.Value == regionInfo) | ||
168 | { | ||
169 | m_knownRegions.Remove(kvp.Key); | ||
170 | return true; | ||
171 | } | ||
172 | } | ||
173 | return false; | ||
174 | } | ||
175 | |||
176 | public virtual Dictionary<string, string> GetGridSettings() | ||
177 | { | ||
178 | Dictionary<string, string> returnGridSettings = new Dictionary<string, string>(); | ||
179 | lock (m_queuedGridSettings) | ||
180 | { | ||
181 | foreach (string Dictkey in m_queuedGridSettings.Keys) | ||
182 | { | ||
183 | returnGridSettings.Add(Dictkey, m_queuedGridSettings[Dictkey]); | ||
184 | } | ||
185 | |||
186 | m_queuedGridSettings.Clear(); | ||
187 | } | ||
188 | |||
189 | return returnGridSettings; | ||
190 | } | ||
191 | |||
192 | // see IGridServices | ||
193 | public virtual List<SimpleRegionInfo> RequestNeighbours(uint x, uint y) | ||
194 | { | ||
195 | List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>(); | ||
196 | foreach (RegionInfo reg in m_hyperlinkRegions) | ||
197 | { | ||
198 | if (reg.RegionLocX != x || reg.RegionLocY != y) | ||
199 | { | ||
200 | //Console.WriteLine("CommsManager- RequestNeighbours() - found a different region in list, checking location"); | ||
201 | if ((reg.RegionLocX > (x - 2)) && (reg.RegionLocX < (x + 2))) | ||
202 | { | ||
203 | if ((reg.RegionLocY > (y - 2)) && (reg.RegionLocY < (y + 2))) | ||
204 | { | ||
205 | neighbours.Add(reg); | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
211 | return neighbours; | ||
212 | } | ||
213 | |||
214 | /// <summary> | ||
215 | /// Request information about a region. | ||
216 | /// </summary> | ||
217 | /// <param name="regionHandle"></param> | ||
218 | /// <returns> | ||
219 | /// null on a failure to contact or get a response from the grid server | ||
220 | /// FIXME: Might be nicer to return a proper exception here since we could inform the client more about the | ||
221 | /// nature of the faiulre. | ||
222 | /// </returns> | ||
223 | public virtual RegionInfo RequestNeighbourInfo(UUID Region_UUID) | ||
224 | { | ||
225 | foreach (RegionInfo info in m_hyperlinkRegions) | ||
226 | { | ||
227 | if (info.RegionID == Region_UUID) return info; | ||
228 | } | ||
229 | |||
230 | // I don't trust region uuids to be unique... | ||
231 | //foreach (RegionInfo info in m_knownRegions.Values) | ||
232 | //{ | ||
233 | // if (info.RegionID == Region_UUID) return info; | ||
234 | //} | ||
235 | |||
236 | return null; | ||
237 | } | ||
238 | |||
239 | /// <summary> | ||
240 | /// Request information about a region. | ||
241 | /// </summary> | ||
242 | /// <param name="regionHandle"></param> | ||
243 | /// <returns></returns> | ||
244 | public virtual RegionInfo RequestNeighbourInfo(ulong regionHandle) | ||
245 | { | ||
246 | //Console.WriteLine("RequestNeighbourInfo for " + regionHandle); | ||
247 | foreach (RegionInfo info in m_hyperlinkRegions) | ||
248 | { | ||
249 | //Console.WriteLine(" .. " + info.RegionHandle); | ||
250 | if (info.RegionHandle == regionHandle) return info; | ||
251 | } | ||
252 | |||
253 | foreach (RegionInfo info in m_knownRegions.Values) | ||
254 | { | ||
255 | if (info.RegionHandle == regionHandle) | ||
256 | { | ||
257 | //Console.WriteLine("XXX------ Found known region " + info.RegionHandle); | ||
258 | return info; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | return null; | ||
263 | } | ||
264 | |||
265 | public virtual RegionInfo RequestClosestRegion(string regionName) | ||
266 | { | ||
267 | foreach (RegionInfo info in m_hyperlinkRegions) | ||
268 | { | ||
269 | if (info.RegionName == regionName) return info; | ||
270 | } | ||
271 | |||
272 | return null; | ||
273 | } | ||
274 | |||
275 | /// <summary> | ||
276 | /// | ||
277 | /// </summary> | ||
278 | /// <param name="minX"></param> | ||
279 | /// <param name="minY"></param> | ||
280 | /// <param name="maxX"></param> | ||
281 | /// <param name="maxY"></param> | ||
282 | /// <returns></returns> | ||
283 | public virtual List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) | ||
284 | { | ||
285 | List<MapBlockData> neighbours = new List<MapBlockData>(); | ||
286 | |||
287 | foreach (RegionInfo regInfo in m_hyperlinkRegions) | ||
288 | { | ||
289 | if (((regInfo.RegionLocX >= minX) && (regInfo.RegionLocX <= maxX)) && | ||
290 | ((regInfo.RegionLocY >= minY) && (regInfo.RegionLocY <= maxY))) | ||
291 | { | ||
292 | MapBlockData map = new MapBlockData(); | ||
293 | map.Name = regInfo.RegionName; | ||
294 | map.X = (ushort)regInfo.RegionLocX; | ||
295 | map.Y = (ushort)regInfo.RegionLocY; | ||
296 | map.WaterHeight = (byte)regInfo.RegionSettings.WaterHeight; | ||
297 | map.MapImageId = regInfo.RegionSettings.TerrainImageID; | ||
298 | // Console.WriteLine("ImgID: " + map.MapImageId); | ||
299 | map.Agents = 1; | ||
300 | map.RegionFlags = 72458694; | ||
301 | map.Access = 13; | ||
302 | neighbours.Add(map); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | return neighbours; | ||
307 | } | ||
308 | |||
309 | |||
310 | protected virtual void GetMapImage(RegionInfo info) | ||
311 | { | ||
312 | try | ||
313 | { | ||
314 | string regionimage = "regionImage" + info.RegionID.ToString(); | ||
315 | regionimage = regionimage.Replace("-", ""); | ||
316 | |||
317 | WebClient c = new WebClient(); | ||
318 | string uri = "http://" + info.ExternalHostName + ":" + info.HttpPort + "/index.php?method=" + regionimage; | ||
319 | //Console.WriteLine("JPEG: " + uri); | ||
320 | c.DownloadFile(uri, info.RegionID.ToString() + ".jpg"); | ||
321 | Bitmap m = new Bitmap(info.RegionID.ToString() + ".jpg"); | ||
322 | //Console.WriteLine("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); | ||
323 | byte[] imageData = OpenJPEG.EncodeFromImage(m, true); | ||
324 | AssetBase ass = new AssetBase(UUID.Random(), "region " + info.RegionID.ToString()); | ||
325 | info.RegionSettings.TerrainImageID = ass.FullID; | ||
326 | ass.Type = (int)AssetType.Texture; | ||
327 | ass.Temporary = false; | ||
328 | //imageData.CopyTo(ass.Data, 0); | ||
329 | ass.Data = imageData; | ||
330 | m_assetcache.AddAsset(ass); | ||
331 | |||
332 | } | ||
333 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke | ||
334 | { | ||
335 | Console.WriteLine("Failed getting/storing map image: " + e); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | // A little ugly, since this code is exactly the same as OSG1's, and we're already | ||
340 | // calling that for when the region in in grid mode... (for the grid regions) | ||
341 | // | ||
342 | public virtual LandData RequestLandData (ulong regionHandle, uint x, uint y) | ||
343 | { | ||
344 | m_log.DebugFormat("[HGrid]: requests land data in {0}, at {1}, {2}", | ||
345 | regionHandle, x, y); | ||
346 | |||
347 | // Remote region | ||
348 | |||
349 | Hashtable hash = new Hashtable(); | ||
350 | hash["region_handle"] = regionHandle.ToString(); | ||
351 | hash["x"] = x.ToString(); | ||
352 | hash["y"] = y.ToString(); | ||
353 | |||
354 | IList paramList = new ArrayList(); | ||
355 | paramList.Add(hash); | ||
356 | LandData landData = null; | ||
357 | |||
358 | try | ||
359 | { | ||
360 | RegionInfo info = RequestNeighbourInfo(regionHandle); | ||
361 | if (info != null) // just to be sure | ||
362 | { | ||
363 | XmlRpcRequest request = new XmlRpcRequest("land_data", paramList); | ||
364 | string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/"; | ||
365 | XmlRpcResponse response = request.Send(uri, 10000); | ||
366 | if (response.IsFault) | ||
367 | { | ||
368 | m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString); | ||
369 | } | ||
370 | else | ||
371 | { | ||
372 | hash = (Hashtable)response.Value; | ||
373 | try | ||
374 | { | ||
375 | landData = new LandData(); | ||
376 | landData.AABBMax = Vector3.Parse((string)hash["AABBMax"]); | ||
377 | landData.AABBMin = Vector3.Parse((string)hash["AABBMin"]); | ||
378 | landData.Area = Convert.ToInt32(hash["Area"]); | ||
379 | landData.AuctionID = Convert.ToUInt32(hash["AuctionID"]); | ||
380 | landData.Description = (string)hash["Description"]; | ||
381 | landData.Flags = Convert.ToUInt32(hash["Flags"]); | ||
382 | landData.GlobalID = new UUID((string)hash["GlobalID"]); | ||
383 | landData.Name = (string)hash["Name"]; | ||
384 | landData.OwnerID = new UUID((string)hash["OwnerID"]); | ||
385 | landData.SalePrice = Convert.ToInt32(hash["SalePrice"]); | ||
386 | landData.SnapshotID = new UUID((string)hash["SnapshotID"]); | ||
387 | landData.UserLocation = Vector3.Parse((string)hash["UserLocation"]); | ||
388 | m_log.DebugFormat("[HGrid]: Got land data for parcel {0}", landData.Name); | ||
389 | } | ||
390 | catch (Exception e) | ||
391 | { | ||
392 | m_log.Error("[HGrid]: Got exception while parsing land-data:", e); | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | else m_log.WarnFormat("[HGrid]: Couldn't find region with handle {0}", regionHandle); | ||
397 | } | ||
398 | catch (Exception e) | ||
399 | { | ||
400 | m_log.ErrorFormat("[HGrid]: Couldn't contact region {0}: {1}", regionHandle, e); | ||
401 | } | ||
402 | |||
403 | return landData; | ||
404 | } | ||
405 | |||
406 | // Grid Request Processing | ||
407 | public virtual List<RegionInfo> RequestNamedRegions (string name, int maxNumber) | ||
408 | { | ||
409 | List<RegionInfo> infos = new List<RegionInfo>(); | ||
410 | foreach (RegionInfo info in m_hyperlinkRegions) | ||
411 | { | ||
412 | if (info.RegionName.ToLower().Contains(name)) | ||
413 | { | ||
414 | infos.Add(info); | ||
415 | } | ||
416 | } | ||
417 | return infos; | ||
418 | } | ||
419 | |||
420 | |||
421 | private UUID LinkRegion(RegionInfo info) | ||
422 | { | ||
423 | UUID uuid = UUID.Zero; | ||
424 | |||
425 | Hashtable hash = new Hashtable(); | ||
426 | hash["region_name"] = info.RegionName; | ||
427 | |||
428 | IList paramList = new ArrayList(); | ||
429 | paramList.Add(hash); | ||
430 | |||
431 | XmlRpcRequest request = new XmlRpcRequest("link_region", paramList); | ||
432 | string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/"; | ||
433 | m_log.Debug("[HGrid]: Linking to " + uri); | ||
434 | XmlRpcResponse response = request.Send(uri, 10000); | ||
435 | if (response.IsFault) | ||
436 | { | ||
437 | m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString); | ||
438 | } | ||
439 | else | ||
440 | { | ||
441 | hash = (Hashtable)response.Value; | ||
442 | //foreach (Object o in hash) | ||
443 | // Console.WriteLine(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); | ||
444 | try | ||
445 | { | ||
446 | UUID.TryParse((string)hash["uuid"], out uuid); | ||
447 | info.RegionID = uuid; | ||
448 | if ((string)hash["handle"] != null) | ||
449 | { | ||
450 | info.regionSecret = (string)hash["handle"]; | ||
451 | //Console.WriteLine(">> HERE: " + info.regionSecret); | ||
452 | } | ||
453 | if (hash["region_image"] != null) | ||
454 | { | ||
455 | UUID img = UUID.Zero; | ||
456 | UUID.TryParse((string)hash["region_image"], out img); | ||
457 | info.RegionSettings.TerrainImageID = img; | ||
458 | } | ||
459 | if (hash["region_name"] != null) | ||
460 | { | ||
461 | info.RegionName = (string)hash["region_name"]; | ||
462 | } | ||
463 | if (hash["internal_port"] != null) | ||
464 | { | ||
465 | int port = Convert.ToInt32((string)hash["internal_port"]); | ||
466 | info.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port); | ||
467 | //Console.WriteLine(">> " + info.InternalEndPoint.ToString()); | ||
468 | } | ||
469 | if (hash["remoting_port"] != null) | ||
470 | { | ||
471 | info.RemotingPort = Convert.ToUInt32(hash["remoting_port"]); | ||
472 | //Console.WriteLine(">> " + info.RemotingPort); | ||
473 | } | ||
474 | |||
475 | } | ||
476 | catch (Exception e) | ||
477 | { | ||
478 | m_log.Error("[HGrid]: Got exception while parsing hyperlink response " + e.StackTrace); | ||
479 | } | ||
480 | } | ||
481 | return uuid; | ||
482 | } | ||
483 | |||
484 | /// <summary> | ||
485 | /// Someone wants to link to us | ||
486 | /// </summary> | ||
487 | /// <param name="request"></param> | ||
488 | /// <returns></returns> | ||
489 | public XmlRpcResponse LinkRegionRequest(XmlRpcRequest request) | ||
490 | { | ||
491 | Hashtable requestData = (Hashtable)request.Params[0]; | ||
492 | //string host = (string)requestData["host"]; | ||
493 | //string portstr = (string)requestData["port"]; | ||
494 | string name = (string)requestData["region_name"]; | ||
495 | |||
496 | m_log.DebugFormat("[HGrid]: Hyperlink request"); | ||
497 | |||
498 | |||
499 | RegionInfo regInfo = null; | ||
500 | foreach (RegionInfo r in m_regionsOnInstance) | ||
501 | { | ||
502 | if ((r.RegionName != null) && (name != null) && (r.RegionName.ToLower() == name.ToLower())) | ||
503 | { | ||
504 | regInfo = r; | ||
505 | break; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | if (regInfo == null) | ||
510 | regInfo = m_regionsOnInstance[0]; // Send out the first region | ||
511 | |||
512 | Hashtable hash = new Hashtable(); | ||
513 | hash["uuid"] = regInfo.RegionID.ToString(); | ||
514 | hash["handle"] = regInfo.RegionHandle.ToString(); | ||
515 | //Console.WriteLine(">> Here " + regInfo.RegionHandle); | ||
516 | hash["region_image"] = regInfo.RegionSettings.TerrainImageID.ToString(); | ||
517 | hash["region_name"] = regInfo.RegionName; | ||
518 | hash["internal_port"] = regInfo.InternalEndPoint.Port.ToString(); | ||
519 | hash["remoting_port"] = NetworkServersInfo.RemotingListenerPort.ToString(); | ||
520 | //Console.WriteLine(">> Here: " + regInfo.InternalEndPoint.Port); | ||
521 | |||
522 | |||
523 | XmlRpcResponse response = new XmlRpcResponse(); | ||
524 | response.Value = hash; | ||
525 | return response; | ||
526 | } | ||
527 | |||
528 | public bool InformRegionOfUser(RegionInfo regInfo, AgentCircuitData agentData) | ||
529 | { | ||
530 | ulong regionHandle = regInfo.RegionHandle; | ||
531 | try | ||
532 | { | ||
533 | regionHandle = Convert.ToUInt64(regInfo.regionSecret); | ||
534 | m_log.Info("[HGrid]: InformRegionOfUser: Remote hyperlinked region " + regInfo.regionSecret); | ||
535 | } | ||
536 | catch | ||
537 | { | ||
538 | m_log.Info("[HGrid]: InformRegionOfUser: Local grid region " + regInfo.regionSecret); | ||
539 | } | ||
540 | |||
541 | string capsPath = agentData.CapsPath; | ||
542 | Hashtable loginParams = new Hashtable(); | ||
543 | loginParams["session_id"] = agentData.SessionID.ToString(); | ||
544 | loginParams["secure_session_id"] = agentData.SecureSessionID.ToString(); | ||
545 | |||
546 | loginParams["firstname"] = agentData.firstname; | ||
547 | loginParams["lastname"] = agentData.lastname; | ||
548 | |||
549 | loginParams["agent_id"] = agentData.AgentID.ToString(); | ||
550 | loginParams["circuit_code"] = agentData.circuitcode.ToString(); | ||
551 | loginParams["startpos_x"] = agentData.startpos.X.ToString(); | ||
552 | loginParams["startpos_y"] = agentData.startpos.Y.ToString(); | ||
553 | loginParams["startpos_z"] = agentData.startpos.Z.ToString(); | ||
554 | loginParams["caps_path"] = capsPath; | ||
555 | |||
556 | CachedUserInfo u = m_userProfileCache.GetUserDetails(agentData.AgentID); | ||
557 | if (u != null && u.UserProfile != null) | ||
558 | { | ||
559 | loginParams["region_uuid"] = u.UserProfile.HomeRegionID.ToString(); // This seems to be always Zero | ||
560 | //Console.WriteLine(" --------- Home Region UUID -------"); | ||
561 | //Console.WriteLine(" >> " + loginParams["region_uuid"] + " <<"); | ||
562 | //Console.WriteLine(" --------- ---------------- -------"); | ||
563 | |||
564 | string serverURI = ""; | ||
565 | if (u.UserProfile is ForeignUserProfileData) | ||
566 | serverURI = HGNetworkServersInfo.ServerURI(((ForeignUserProfileData)u.UserProfile).UserServerURI); | ||
567 | loginParams["userserver_id"] = (serverURI == "") || (serverURI == null) ? HGNetworkServersInfo.Singleton.LocalUserServerURI : serverURI; | ||
568 | |||
569 | serverURI = HGNetworkServersInfo.ServerURI(u.UserProfile.UserAssetURI); | ||
570 | loginParams["assetserver_id"] = (serverURI == "") || (serverURI == null) ? HGNetworkServersInfo.Singleton.LocalAssetServerURI : serverURI; | ||
571 | |||
572 | serverURI = HGNetworkServersInfo.ServerURI(u.UserProfile.UserInventoryURI); | ||
573 | loginParams["inventoryserver_id"] = (serverURI == "") || (serverURI == null) ? HGNetworkServersInfo.Singleton.LocalInventoryServerURI : serverURI; | ||
574 | |||
575 | loginParams["root_folder_id"] = u.UserProfile.RootInventoryFolderID; | ||
576 | |||
577 | RegionInfo rinfo = RequestNeighbourInfo(u.UserProfile.HomeRegion); | ||
578 | if (rinfo != null) | ||
579 | { | ||
580 | loginParams["internal_port"] = rinfo.InternalEndPoint.Port.ToString(); | ||
581 | if (!IsLocalUser(u)) | ||
582 | { | ||
583 | loginParams["regionhandle"] = rinfo.regionSecret; // user.CurrentAgent.Handle.ToString(); | ||
584 | //Console.WriteLine("XXX--- informregionofuser (foreign user) here handle: " + rinfo.regionSecret); | ||
585 | |||
586 | loginParams["home_address"] = ((ForeignUserProfileData)(u.UserProfile)).UserHomeAddress; | ||
587 | loginParams["home_port"] = ((ForeignUserProfileData)(u.UserProfile)).UserHomePort; | ||
588 | loginParams["home_remoting"] = ((ForeignUserProfileData)(u.UserProfile)).UserHomeRemotingPort; | ||
589 | } | ||
590 | else | ||
591 | { | ||
592 | //Console.WriteLine("XXX--- informregionofuser (local user) here handle: " + rinfo.regionSecret); | ||
593 | |||
594 | //// local user about to jump out, let's process the name | ||
595 | // On second thoughts, let's not do this for the *user*; let's only do it for the *agent* | ||
596 | //loginParams["firstname"] = agentData.firstname + "." + agentData.lastname; | ||
597 | //loginParams["lastname"] = serversInfo.UserURL; | ||
598 | |||
599 | // local user, first time out. let's ask the grid about this user's home region | ||
600 | loginParams["regionhandle"] = u.UserProfile.HomeRegion.ToString(); // user.CurrentAgent.Handle.ToString(); | ||
601 | |||
602 | loginParams["home_address"] = rinfo.ExternalHostName; | ||
603 | Console.WriteLine(" --------- Home Address -------"); | ||
604 | Console.WriteLine(" >> " + loginParams["home_address"] + " <<"); | ||
605 | Console.WriteLine(" --------- ------------ -------"); | ||
606 | loginParams["home_port"] = rinfo.HttpPort.ToString(); | ||
607 | loginParams["home_remoting"] = NetworkServersInfo.RemotingListenerPort.ToString(); ; | ||
608 | } | ||
609 | } | ||
610 | else | ||
611 | { | ||
612 | m_log.Warn("[HGrid]: User's home region info not found: " + u.UserProfile.HomeRegionX + ", " + u.UserProfile.HomeRegionY); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | ArrayList SendParams = new ArrayList(); | ||
617 | SendParams.Add(loginParams); | ||
618 | |||
619 | // Send | ||
620 | string uri = "http://" + regInfo.ExternalHostName + ":" + regInfo.HttpPort + "/"; | ||
621 | //Console.WriteLine("XXX uri: " + uri); | ||
622 | XmlRpcRequest request = new XmlRpcRequest("expect_hg_user", SendParams); | ||
623 | XmlRpcResponse reply = request.Send(uri, 6000); | ||
624 | |||
625 | if (!reply.IsFault) | ||
626 | { | ||
627 | bool responseSuccess = true; | ||
628 | if (reply.Value != null) | ||
629 | { | ||
630 | Hashtable resp = (Hashtable)reply.Value; | ||
631 | if (resp.ContainsKey("success")) | ||
632 | { | ||
633 | if ((string)resp["success"] == "FALSE") | ||
634 | { | ||
635 | responseSuccess = false; | ||
636 | } | ||
637 | } | ||
638 | } | ||
639 | if (responseSuccess) | ||
640 | { | ||
641 | m_log.Info("[HGrid]: Successfully informed remote region about user " + agentData.AgentID); | ||
642 | return true; | ||
643 | } | ||
644 | else | ||
645 | { | ||
646 | m_log.ErrorFormat("[HGrid]: Region responded that it is not available to receive clients"); | ||
647 | return false; | ||
648 | } | ||
649 | } | ||
650 | else | ||
651 | { | ||
652 | m_log.ErrorFormat("[HGrid]: XmlRpc request to region failed with message {0}, code {1} ", reply.FaultString, reply.FaultCode); | ||
653 | return false; | ||
654 | } | ||
655 | } | ||
656 | |||
657 | |||
658 | /// <summary> | ||
659 | /// Received from other HGrid nodes when a user wants to teleport here. This call allows | ||
660 | /// the region to prepare for direct communication from the client. Sends back an empty | ||
661 | /// xmlrpc response on completion. | ||
662 | /// This is somewhat similar to OGS1's ExpectUser, but with the additional task of | ||
663 | /// registering the user in the local user cache. | ||
664 | /// </summary> | ||
665 | /// <param name="request"></param> | ||
666 | /// <returns></returns> | ||
667 | public XmlRpcResponse ExpectHGUser(XmlRpcRequest request) | ||
668 | { | ||
669 | Hashtable requestData = (Hashtable)request.Params[0]; | ||
670 | ForeignUserProfileData userData = new ForeignUserProfileData(); | ||
671 | |||
672 | userData.FirstName = (string)requestData["firstname"]; | ||
673 | userData.SurName = (string)requestData["lastname"]; | ||
674 | userData.ID = new UUID((string)requestData["agent_id"]); | ||
675 | userData.HomeLocation = new Vector3((float)Convert.ToDecimal((string)requestData["startpos_x"]), | ||
676 | (float)Convert.ToDecimal((string)requestData["startpos_y"]), | ||
677 | (float)Convert.ToDecimal((string)requestData["startpos_z"])); | ||
678 | |||
679 | userData.UserServerURI = (string)requestData["userserver_id"]; | ||
680 | userData.UserAssetURI = (string)requestData["assetserver_id"]; | ||
681 | userData.UserInventoryURI = (string)requestData["inventoryserver_id"]; | ||
682 | |||
683 | UUID rootID = UUID.Zero; | ||
684 | UUID.TryParse((string)requestData["root_folder_id"], out rootID); | ||
685 | userData.RootInventoryFolderID = rootID; | ||
686 | |||
687 | UUID uuid = UUID.Zero; | ||
688 | UUID.TryParse((string)requestData["region_uuid"], out uuid); | ||
689 | userData.HomeRegionID = uuid; // not quite comfortable about this... | ||
690 | ulong userRegionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); | ||
691 | //userData.HomeRegion = userRegionHandle; | ||
692 | userData.UserHomeAddress = (string)requestData["home_address"]; | ||
693 | userData.UserHomePort = (string)requestData["home_port"]; | ||
694 | int userhomeinternalport = Convert.ToInt32((string)requestData["internal_port"]); | ||
695 | userData.UserHomeRemotingPort = (string)requestData["home_remoting"]; | ||
696 | |||
697 | |||
698 | m_log.DebugFormat("[HGrid]: Told by user service to prepare for a connection from {0} {1} {2}", | ||
699 | userData.FirstName, userData.SurName, userData.ID); | ||
700 | m_log.Debug("[HGrid]: home_address: " + userData.UserHomeAddress + | ||
701 | "; home_port: " + userData.UserHomePort + "; remoting: " + userData.UserHomeRemotingPort); | ||
702 | |||
703 | |||
704 | XmlRpcResponse resp = new XmlRpcResponse(); | ||
705 | |||
706 | if (!RegionLoginsEnabled) | ||
707 | { | ||
708 | m_log.InfoFormat( | ||
709 | "[HGrid]: Denying access for user {0} {1} because region login is currently disabled", | ||
710 | userData.FirstName, userData.SurName); | ||
711 | |||
712 | Hashtable respdata = new Hashtable(); | ||
713 | respdata["success"] = "FALSE"; | ||
714 | respdata["reason"] = "region login currently disabled"; | ||
715 | resp.Value = respdata; | ||
716 | } | ||
717 | else | ||
718 | { | ||
719 | RegionInfo[] regions = m_regionsOnInstance.ToArray(); | ||
720 | //bool banned = false; | ||
721 | // Just check one region. We assume they all belong to the same estate. | ||
722 | if ((regions.Length > 0) && (regions[0].EstateSettings.IsBanned(userData.ID))) | ||
723 | { | ||
724 | m_log.InfoFormat( | ||
725 | "[HGrid]: Denying access for user {0} {1} because user is banned", | ||
726 | userData.FirstName, userData.SurName); | ||
727 | |||
728 | Hashtable respdata = new Hashtable(); | ||
729 | respdata["success"] = "FALSE"; | ||
730 | respdata["reason"] = "banned"; | ||
731 | resp.Value = respdata; | ||
732 | } | ||
733 | else | ||
734 | { | ||
735 | // Finally, everything looks ok | ||
736 | //Console.WriteLine("XXX---- EVERYTHING OK ---XXX"); | ||
737 | |||
738 | // Nope, let's do it only for the *agent* | ||
739 | //// 0 - Switch name if necessary | ||
740 | //if (IsComingHome(userData)) | ||
741 | //{ | ||
742 | // string[] parts = userData.FirstName.Split( new char[] {'.'}); | ||
743 | // if (parts.Length >= 1) | ||
744 | // userData.FirstName = parts[0]; | ||
745 | // if (parts.Length == 2) | ||
746 | // userData.SurName = parts[1]; | ||
747 | // else | ||
748 | // m_log.Warn("[HGrid]: Something fishy with user " + userData.FirstName + userData.SurName); | ||
749 | |||
750 | // m_log.Info("[HGrid]: Welcome home, " + userData.FirstName + " " + userData.SurName); | ||
751 | //} | ||
752 | |||
753 | // 1 - Preload the user data | ||
754 | m_userProfileCache.PreloadUserCache(userData.ID, userData); | ||
755 | |||
756 | // 2 - Load the region info into list of known regions | ||
757 | RegionInfo rinfo = new RegionInfo(); | ||
758 | rinfo.RegionID = userData.HomeRegionID; | ||
759 | rinfo.ExternalHostName = userData.UserHomeAddress; | ||
760 | rinfo.HttpPort = Convert.ToUInt32(userData.UserHomePort); | ||
761 | rinfo.RemotingPort = Convert.ToUInt32(userData.UserHomeRemotingPort); | ||
762 | rinfo.RegionID = userData.HomeRegionID; | ||
763 | // X=0 on the map | ||
764 | rinfo.RegionLocX = 0; | ||
765 | rinfo.RegionLocY = (uint)m_knownRegions.Count; | ||
766 | rinfo.regionSecret = userRegionHandle.ToString(); | ||
767 | //Console.WriteLine("XXX--- Here: handle = " + rinfo.regionSecret); | ||
768 | try | ||
769 | { | ||
770 | rinfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)userhomeinternalport); | ||
771 | } | ||
772 | catch (Exception e) | ||
773 | { | ||
774 | m_log.Warn("[HGrid]: Exception while constructing internal endpoint: " + e); | ||
775 | } | ||
776 | rinfo.RemotingAddress = rinfo.ExternalEndPoint.Address.ToString(); //userData.UserHomeAddress; | ||
777 | |||
778 | if (!IsComingHome(userData)) | ||
779 | { | ||
780 | // Change the user's home region here!!! | ||
781 | userData.HomeRegion = rinfo.RegionHandle; | ||
782 | } | ||
783 | |||
784 | if (!m_knownRegions.ContainsKey(userData.ID)) | ||
785 | m_knownRegions.Add(userData.ID, rinfo); | ||
786 | else | ||
787 | // just update it. The previous one was left there when the user departed | ||
788 | m_knownRegions[userData.ID] = rinfo; | ||
789 | |||
790 | // 3 - Send the reply | ||
791 | Hashtable respdata = new Hashtable(); | ||
792 | respdata["success"] = "TRUE"; | ||
793 | resp.Value = respdata; | ||
794 | |||
795 | DumpUserData(userData); | ||
796 | DumpRegionData(rinfo); | ||
797 | } | ||
798 | } | ||
799 | |||
800 | return resp; | ||
801 | } | ||
802 | |||
803 | #region IInterRegionCommunications interface | ||
804 | |||
805 | public virtual bool AcknowledgeAgentCrossed(ulong regionHandle, UUID agentId) { return false; } | ||
806 | public virtual bool AcknowledgePrimCrossed(ulong regionHandle, UUID primID) { return false; } | ||
807 | public virtual bool CheckRegion(string address, uint port) { return false; } | ||
808 | public virtual bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) { return false; } | ||
809 | |||
810 | public virtual bool ExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying) { | ||
811 | // Remote region | ||
812 | RegionInfo regInfo = null; | ||
813 | ulong remoteHandle = 0; | ||
814 | try | ||
815 | { | ||
816 | regInfo = RequestNeighbourInfo(regionHandle); | ||
817 | if (regInfo != null) | ||
818 | { | ||
819 | try | ||
820 | { | ||
821 | remoteHandle = Convert.ToUInt64(regInfo.regionSecret); | ||
822 | } | ||
823 | catch | ||
824 | { | ||
825 | m_log.Warn("[HGrid]: Invalid remote region with handle " + regInfo.regionSecret); | ||
826 | return false; | ||
827 | } | ||
828 | //Console.WriteLine("XXX---- Sending Expectavatarcrossing into : " + remoteHandle); | ||
829 | |||
830 | bool retValue = false; | ||
831 | OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( | ||
832 | typeof(OGS1InterRegionRemoting), | ||
833 | "tcp://" + regInfo.RemotingAddress + | ||
834 | ":" + regInfo.RemotingPort + | ||
835 | "/InterRegions"); | ||
836 | |||
837 | if (remObject != null) | ||
838 | { | ||
839 | retValue = | ||
840 | remObject.ExpectAvatarCrossing(remoteHandle, agentID.Guid, new sLLVector3(position), | ||
841 | isFlying); | ||
842 | } | ||
843 | else | ||
844 | { | ||
845 | m_log.Warn("[HGrid]: Remoting object not found"); | ||
846 | } | ||
847 | remObject = null; | ||
848 | |||
849 | return retValue; | ||
850 | } | ||
851 | //TODO need to see if we know about where this region is and use .net remoting | ||
852 | // to inform it. | ||
853 | //NoteDeadRegion(regionHandle); | ||
854 | return false; | ||
855 | } | ||
856 | catch (RemotingException e) | ||
857 | { | ||
858 | // NoteDeadRegion(regionHandle); | ||
859 | |||
860 | m_log.WarnFormat( | ||
861 | "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", | ||
862 | regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); | ||
863 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
864 | |||
865 | return false; | ||
866 | } | ||
867 | catch | ||
868 | { | ||
869 | // NoteDeadRegion(regionHandle); | ||
870 | return false; | ||
871 | } | ||
872 | |||
873 | } | ||
874 | |||
875 | public virtual bool ExpectPrimCrossing(ulong regionHandle, UUID primID, Vector3 position, bool isFlying) { return false; } | ||
876 | |||
877 | public virtual bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData) | ||
878 | { | ||
879 | // If we're here, it's because regionHandle is a remote, non-grided region | ||
880 | m_log.Info("[HGrid]: InformRegionOfChildAgent for " + regionHandle); | ||
881 | |||
882 | RegionInfo regInfo = GetHyperlinkRegion(regionHandle); | ||
883 | if (regInfo == null) | ||
884 | return false; | ||
885 | |||
886 | ulong realHandle = regionHandle; | ||
887 | |||
888 | CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(agentData.AgentID); | ||
889 | if ((uinfo == null) || !IsGoingHome(uinfo, regInfo)) | ||
890 | { | ||
891 | m_log.Info("[HGrid]: User seems to be going to foreign region " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName); | ||
892 | if (!InformRegionOfUser(regInfo, agentData)) | ||
893 | { | ||
894 | m_log.Warn("[HGrid]: Could not inform remote region of transferring user."); | ||
895 | return false; | ||
896 | } | ||
897 | } | ||
898 | else | ||
899 | m_log.Info("[HGrid]: User seems to be going home " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName); | ||
900 | |||
901 | try | ||
902 | { | ||
903 | // ... and then | ||
904 | |||
905 | m_log.Debug("[HGrid]: Region is hyperlink."); | ||
906 | bool retValue = false; | ||
907 | try | ||
908 | { | ||
909 | regionHandle = Convert.ToUInt64(regInfo.regionSecret); | ||
910 | } | ||
911 | catch (Exception) | ||
912 | { | ||
913 | m_log.Warn("[HGrid]: Invalid hyperlink region."); | ||
914 | return false; | ||
915 | } | ||
916 | |||
917 | OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( | ||
918 | typeof(OGS1InterRegionRemoting), | ||
919 | "tcp://" + regInfo.RemotingAddress + | ||
920 | ":" + regInfo.RemotingPort + | ||
921 | "/InterRegions"); | ||
922 | |||
923 | if (remObject != null) | ||
924 | { | ||
925 | sAgentCircuitData sag = new sAgentCircuitData(agentData); | ||
926 | // May need to change agent's name | ||
927 | if (IsLocalUser(uinfo)) | ||
928 | { | ||
929 | sag.firstname = agentData.firstname + "." + agentData.lastname; | ||
930 | sag.lastname = serversInfo.UserURL; //HGNetworkServersInfo.Singleton.LocalUserServerURI; | ||
931 | } | ||
932 | retValue = remObject.InformRegionOfChildAgent(regionHandle, sag); | ||
933 | } | ||
934 | else | ||
935 | { | ||
936 | m_log.Warn("[HGrid]: remoting object not found"); | ||
937 | } | ||
938 | remObject = null; | ||
939 | m_log.Info("[HGrid]: tried to InformRegionOfChildAgent for " + | ||
940 | agentData.firstname + " " + agentData.lastname + " and got " + | ||
941 | retValue.ToString()); | ||
942 | |||
943 | // Remove the info from this region | ||
944 | if (m_knownRegions.ContainsKey(uinfo.UserProfile.ID)) | ||
945 | m_knownRegions.Remove(uinfo.UserProfile.ID); | ||
946 | |||
947 | return retValue; | ||
948 | } | ||
949 | catch (RemotingException e) | ||
950 | { | ||
951 | //NoteDeadRegion(regionHandle); | ||
952 | |||
953 | m_log.WarnFormat( | ||
954 | "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", | ||
955 | regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); | ||
956 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
957 | |||
958 | return false; | ||
959 | } | ||
960 | catch (SocketException e) | ||
961 | { | ||
962 | //NoteDeadRegion(regionHandle); | ||
963 | |||
964 | m_log.WarnFormat( | ||
965 | "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", | ||
966 | regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); | ||
967 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
968 | |||
969 | return false; | ||
970 | } | ||
971 | catch (InvalidCredentialException e) | ||
972 | { | ||
973 | //NoteDeadRegion(regionHandle); | ||
974 | |||
975 | m_log.WarnFormat( | ||
976 | "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", | ||
977 | regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); | ||
978 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
979 | |||
980 | return false; | ||
981 | } | ||
982 | catch (AuthenticationException e) | ||
983 | { | ||
984 | //NoteDeadRegion(regionHandle); | ||
985 | |||
986 | m_log.WarnFormat( | ||
987 | "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", | ||
988 | regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); | ||
989 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
990 | |||
991 | return false; | ||
992 | } | ||
993 | catch (Exception e) | ||
994 | { | ||
995 | //NoteDeadRegion(regionHandle); | ||
996 | |||
997 | if (regInfo != null) | ||
998 | { | ||
999 | m_log.WarnFormat( | ||
1000 | "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", | ||
1001 | regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); | ||
1002 | } | ||
1003 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
1004 | |||
1005 | return false; | ||
1006 | } | ||
1007 | |||
1008 | |||
1009 | } | ||
1010 | |||
1011 | public virtual bool InformRegionOfPrimCrossing(ulong regionHandle, UUID primID, string objData, int XMLMethod) { return false; } | ||
1012 | |||
1013 | public virtual bool RegionUp(SerializableRegionInfo region, ulong regionhandle) { | ||
1014 | |||
1015 | ulong realHandle = FindRegionHandle(regionhandle); | ||
1016 | |||
1017 | if (realHandle == regionhandle) // something wrong, not remote region | ||
1018 | return false; | ||
1019 | |||
1020 | SerializableRegionInfo regInfo = null; | ||
1021 | try | ||
1022 | { | ||
1023 | // You may ask why this is in here... | ||
1024 | // The region asking the grid services about itself.. | ||
1025 | // And, surprisingly, the reason is.. it doesn't know | ||
1026 | // it's own remoting port! How special. | ||
1027 | RegionUpData regiondata = new RegionUpData(region.RegionLocX, region.RegionLocY, region.ExternalHostName, region.InternalEndPoint.Port); | ||
1028 | |||
1029 | region = new SerializableRegionInfo(RequestNeighbourInfo(realHandle)); | ||
1030 | region.RemotingAddress = region.ExternalHostName; | ||
1031 | region.RemotingPort = NetworkServersInfo.RemotingListenerPort; | ||
1032 | region.HttpPort = serversInfo.HttpListenerPort; | ||
1033 | |||
1034 | regInfo = new SerializableRegionInfo(RequestNeighbourInfo(regionhandle)); | ||
1035 | if (regInfo != null) | ||
1036 | { | ||
1037 | // If we're not trying to remote to ourselves. | ||
1038 | if (regInfo.RemotingAddress != region.RemotingAddress && region.RemotingAddress != null) | ||
1039 | { | ||
1040 | //don't want to be creating a new link to the remote instance every time like we are here | ||
1041 | bool retValue = false; | ||
1042 | |||
1043 | OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( | ||
1044 | typeof(OGS1InterRegionRemoting), | ||
1045 | "tcp://" + | ||
1046 | regInfo.RemotingAddress + | ||
1047 | ":" + regInfo.RemotingPort + | ||
1048 | "/InterRegions"); | ||
1049 | |||
1050 | if (remObject != null) | ||
1051 | { | ||
1052 | retValue = remObject.RegionUp(regiondata, realHandle); | ||
1053 | } | ||
1054 | else | ||
1055 | { | ||
1056 | m_log.Warn("[HGrid]: remoting object not found"); | ||
1057 | } | ||
1058 | remObject = null; | ||
1059 | |||
1060 | m_log.Info( | ||
1061 | "[HGrid]: tried to inform region I'm up"); | ||
1062 | |||
1063 | return retValue; | ||
1064 | } | ||
1065 | else | ||
1066 | { | ||
1067 | // We're trying to inform ourselves via remoting. | ||
1068 | // This is here because we're looping over the listeners before we get here. | ||
1069 | // Odd but it should work. | ||
1070 | return true; | ||
1071 | } | ||
1072 | } | ||
1073 | |||
1074 | return false; | ||
1075 | } | ||
1076 | catch (RemotingException e) | ||
1077 | { | ||
1078 | m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region using tcp://" + | ||
1079 | regInfo.RemotingAddress + | ||
1080 | ":" + regInfo.RemotingPort + | ||
1081 | "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + | ||
1082 | " - Is this neighbor up?"); | ||
1083 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
1084 | return false; | ||
1085 | } | ||
1086 | catch (SocketException e) | ||
1087 | { | ||
1088 | m_log.Warn("[HGrid]: Socket Error: Unable to connect to adjacent region using tcp://" + | ||
1089 | regInfo.RemotingAddress + | ||
1090 | ":" + regInfo.RemotingPort + | ||
1091 | "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + | ||
1092 | " - Is this neighbor up?"); | ||
1093 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
1094 | return false; | ||
1095 | } | ||
1096 | catch (InvalidCredentialException e) | ||
1097 | { | ||
1098 | m_log.Warn("[HGrid]: Invalid Credentials: Unable to connect to adjacent region using tcp://" + | ||
1099 | regInfo.RemotingAddress + | ||
1100 | ":" + regInfo.RemotingPort + | ||
1101 | "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY); | ||
1102 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
1103 | return false; | ||
1104 | } | ||
1105 | catch (AuthenticationException e) | ||
1106 | { | ||
1107 | m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region using tcp://" + | ||
1108 | regInfo.RemotingAddress + | ||
1109 | ":" + regInfo.RemotingPort + | ||
1110 | "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY); | ||
1111 | m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); | ||
1112 | return false; | ||
1113 | } | ||
1114 | catch (Exception e) | ||
1115 | { | ||
1116 | m_log.Debug(e.ToString()); | ||
1117 | return false; | ||
1118 | } | ||
1119 | |||
1120 | } | ||
1121 | |||
1122 | public virtual bool TellRegionToCloseChildConnection(ulong regionHandle, UUID agentID) { return false; } | ||
1123 | |||
1124 | public virtual List<UUID> InformFriendsInOtherRegion(UUID agentId, ulong destRegionHandle, List<UUID> friends, bool online) | ||
1125 | { | ||
1126 | return new List<UUID>(); | ||
1127 | } | ||
1128 | |||
1129 | public virtual bool TriggerTerminateFriend(ulong regionHandle, UUID agentID, UUID exFriendID) | ||
1130 | { | ||
1131 | return true; | ||
1132 | } | ||
1133 | |||
1134 | |||
1135 | #endregion | ||
1136 | |||
1137 | #region Methods triggered by calls from external instances | ||
1138 | |||
1139 | /// <summary> | ||
1140 | /// | ||
1141 | /// </summary> | ||
1142 | /// <param name="regionHandle"></param> | ||
1143 | /// <param name="agentData"></param> | ||
1144 | /// <returns></returns> | ||
1145 | protected bool HGIncomingChildAgent(ulong regionHandle, AgentCircuitData agentData) | ||
1146 | { | ||
1147 | CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(agentData.AgentID); | ||
1148 | if ((uinfo != null) && (uinfo.UserProfile != null) && | ||
1149 | (IsLocalUser(uinfo) || !(uinfo.UserProfile is ForeignUserProfileData))) | ||
1150 | { | ||
1151 | //Console.WriteLine("---------------> Local User!"); | ||
1152 | string[] parts = agentData.firstname.Split(new char[] { '.' }); | ||
1153 | if (parts.Length == 2) | ||
1154 | { | ||
1155 | agentData.firstname = parts[0]; | ||
1156 | agentData.lastname = parts[1]; | ||
1157 | } | ||
1158 | } | ||
1159 | //else | ||
1160 | // Console.WriteLine("---------------> Foreign User!"); | ||
1161 | return true; | ||
1162 | } | ||
1163 | #endregion | ||
1164 | |||
1165 | |||
1166 | #region IHyperGrid interface | ||
1167 | |||
1168 | public virtual bool IsHyperlinkRegion(ulong ihandle) | ||
1169 | { | ||
1170 | if (GetHyperlinkRegion(ihandle) == null) | ||
1171 | return false; | ||
1172 | else | ||
1173 | return true; | ||
1174 | } | ||
1175 | |||
1176 | public virtual RegionInfo GetHyperlinkRegion(ulong ihandle) | ||
1177 | { | ||
1178 | foreach (RegionInfo info in m_hyperlinkRegions) | ||
1179 | { | ||
1180 | if (info.RegionHandle == ihandle) | ||
1181 | return info; | ||
1182 | } | ||
1183 | |||
1184 | foreach (RegionInfo info in m_knownRegions.Values) | ||
1185 | { | ||
1186 | if (info.RegionHandle == ihandle) | ||
1187 | return info; | ||
1188 | } | ||
1189 | |||
1190 | return null; | ||
1191 | } | ||
1192 | |||
1193 | public virtual ulong FindRegionHandle(ulong ihandle) | ||
1194 | { | ||
1195 | long ohandle = -1; | ||
1196 | List<RegionInfo> rlist = new List<RegionInfo>(m_hyperlinkRegions); | ||
1197 | rlist.AddRange(m_knownRegions.Values); | ||
1198 | foreach (RegionInfo info in rlist) | ||
1199 | { | ||
1200 | if (info.RegionHandle == ihandle) | ||
1201 | { | ||
1202 | try | ||
1203 | { | ||
1204 | ohandle = Convert.ToInt64(info.regionSecret); | ||
1205 | m_log.Info("[HGrid] remote region " + ohandle); | ||
1206 | } | ||
1207 | catch | ||
1208 | { | ||
1209 | m_log.Error("[HGrid] Could not convert secret for " + ihandle + " (" + info.regionSecret + ")"); | ||
1210 | } | ||
1211 | break; | ||
1212 | } | ||
1213 | } | ||
1214 | return ohandle < 0 ? ihandle : (ulong)ohandle; | ||
1215 | } | ||
1216 | #endregion | ||
1217 | |||
1218 | #region Misc | ||
1219 | |||
1220 | protected bool IsComingHome(ForeignUserProfileData userData) | ||
1221 | { | ||
1222 | return (userData.UserServerURI == HGNetworkServersInfo.Singleton.LocalUserServerURI); | ||
1223 | } | ||
1224 | |||
1225 | protected bool IsGoingHome(CachedUserInfo uinfo, RegionInfo rinfo) | ||
1226 | { | ||
1227 | if (uinfo.UserProfile == null) | ||
1228 | return false; | ||
1229 | |||
1230 | string userUserServerURI = String.Empty; | ||
1231 | if (uinfo.UserProfile is ForeignUserProfileData) | ||
1232 | { | ||
1233 | userUserServerURI = HGNetworkServersInfo.ServerURI(((ForeignUserProfileData)uinfo.UserProfile).UserServerURI); | ||
1234 | } | ||
1235 | |||
1236 | return ((uinfo.UserProfile.HomeRegionID == rinfo.RegionID) && | ||
1237 | (userUserServerURI != HGNetworkServersInfo.Singleton.LocalUserServerURI)); | ||
1238 | } | ||
1239 | |||
1240 | protected bool IsLocalUser(CachedUserInfo uinfo) | ||
1241 | { | ||
1242 | if (uinfo == null) | ||
1243 | return true; | ||
1244 | |||
1245 | if (uinfo.UserProfile is ForeignUserProfileData) | ||
1246 | return HGNetworkServersInfo.Singleton.IsLocalUser(((ForeignUserProfileData)uinfo.UserProfile).UserServerURI); | ||
1247 | else | ||
1248 | return true; | ||
1249 | |||
1250 | } | ||
1251 | |||
1252 | protected bool IsLocalRegion(ulong handle) | ||
1253 | { | ||
1254 | foreach (RegionInfo reg in m_regionsOnInstance) | ||
1255 | if (reg.RegionHandle == handle) | ||
1256 | return true; | ||
1257 | return false; | ||
1258 | } | ||
1259 | |||
1260 | private void DumpUserData(ForeignUserProfileData userData) | ||
1261 | { | ||
1262 | Console.WriteLine(" ------------ User Data Dump ----------"); | ||
1263 | Console.WriteLine(" >> Name: " + userData.FirstName + " " + userData.SurName); | ||
1264 | Console.WriteLine(" >> HomeID: " + userData.HomeRegionID); | ||
1265 | Console.WriteLine(" >> HomeHandle: " + userData.HomeRegion); | ||
1266 | Console.WriteLine(" >> HomeX: " + userData.HomeRegionX); | ||
1267 | Console.WriteLine(" >> HomeY: " + userData.HomeRegionY); | ||
1268 | Console.WriteLine(" >> UserServer: " + userData.UserServerURI); | ||
1269 | Console.WriteLine(" >> InvServer: " + userData.UserInventoryURI); | ||
1270 | Console.WriteLine(" >> AssetServer: " + userData.UserAssetURI); | ||
1271 | Console.WriteLine(" ------------ -------------- ----------"); | ||
1272 | } | ||
1273 | |||
1274 | private void DumpRegionData(RegionInfo rinfo) | ||
1275 | { | ||
1276 | Console.WriteLine(" ------------ Region Data Dump ----------"); | ||
1277 | Console.WriteLine(" >> handle: " + rinfo.RegionHandle); | ||
1278 | Console.WriteLine(" >> coords: " + rinfo.RegionLocX + ", " + rinfo.RegionLocY); | ||
1279 | Console.WriteLine(" >> secret: " + rinfo.regionSecret); | ||
1280 | Console.WriteLine(" >> remoting address: " + rinfo.RemotingAddress); | ||
1281 | Console.WriteLine(" >> remoting port: " + rinfo.RemotingPort); | ||
1282 | Console.WriteLine(" >> external host name: " + rinfo.ExternalHostName); | ||
1283 | Console.WriteLine(" >> http port: " + rinfo.HttpPort); | ||
1284 | Console.WriteLine(" >> external EP address: " + rinfo.ExternalEndPoint.Address); | ||
1285 | Console.WriteLine(" >> external EP port: " + rinfo.ExternalEndPoint.Port); | ||
1286 | Console.WriteLine(" ------------ -------------- ----------"); | ||
1287 | } | ||
1288 | |||
1289 | |||
1290 | #endregion | ||
1291 | |||
1292 | |||
1293 | } | ||
1294 | } | ||