diff options
author | diva | 2009-02-07 16:10:23 +0000 |
---|---|---|
committer | diva | 2009-02-07 16:10:23 +0000 |
commit | ff0fa1290397d96dbf49477a2668fa62e9be22dc (patch) | |
tree | e7be5308f5379f5a6d2c0f663ebe0b8aa6bf87f4 /OpenSim/Region | |
parent | Fix a .NET issue where changing a locked reference would cause a crash (diff) | |
download | opensim-SC-ff0fa1290397d96dbf49477a2668fa62e9be22dc.zip opensim-SC-ff0fa1290397d96dbf49477a2668fa62e9be22dc.tar.gz opensim-SC-ff0fa1290397d96dbf49477a2668fa62e9be22dc.tar.bz2 opensim-SC-ff0fa1290397d96dbf49477a2668fa62e9be22dc.tar.xz |
Adds support for HG linking to specific regions within an instance. The format is Host:Port:Region. Refactored the linking code from MapSearchModule to HGHyperlink, so that it can be used both by the MapSearchModule and the Console command.
Diffstat (limited to 'OpenSim/Region')
4 files changed, 264 insertions, 181 deletions
diff --git a/OpenSim/Region/Application/HGOpenSimNode.cs b/OpenSim/Region/Application/HGOpenSimNode.cs index 2de9ddf..57c6fa3 100644 --- a/OpenSim/Region/Application/HGOpenSimNode.cs +++ b/OpenSim/Region/Application/HGOpenSimNode.cs | |||
@@ -79,7 +79,7 @@ namespace OpenSim | |||
79 | base.StartupSpecific(); | 79 | base.StartupSpecific(); |
80 | 80 | ||
81 | MainConsole.Instance.Commands.AddCommand("hypergrid", "link-mapping", "link-mapping [<x> <y>] <cr>", "Set local coordinate to map HG regions to", RunCommand); | 81 | MainConsole.Instance.Commands.AddCommand("hypergrid", "link-mapping", "link-mapping [<x> <y>] <cr>", "Set local coordinate to map HG regions to", RunCommand); |
82 | MainConsole.Instance.Commands.AddCommand("hypergrid", "link-region", "link-region <Xloc> <Yloc> <HostName> <HttpPort> <LocalName> <cr>", "Link a hypergrid region", RunCommand); | 82 | MainConsole.Instance.Commands.AddCommand("hypergrid", "link-region", "link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>] <cr>", "Link a hypergrid region", RunCommand); |
83 | } | 83 | } |
84 | 84 | ||
85 | protected override void InitialiseStandaloneServices(LibraryRootFolder libraryRootFolder) | 85 | protected override void InitialiseStandaloneServices(LibraryRootFolder libraryRootFolder) |
@@ -175,50 +175,71 @@ namespace OpenSim | |||
175 | } | 175 | } |
176 | else if (command.Equals("link-region")) | 176 | else if (command.Equals("link-region")) |
177 | { | 177 | { |
178 | // link-region <Xloc> <Yloc> <HostName> <HttpPort> <LocalName> | 178 | if (cmdparams.Count < 3) |
179 | if (cmdparams.Count < 4) | ||
180 | { | 179 | { |
181 | if ((cmdparams.Count == 1) || (cmdparams.Count ==2)) | 180 | LinkRegionCmdUsage(); |
181 | return; | ||
182 | } | ||
183 | |||
184 | if (cmdparams[2].Contains(":")) | ||
185 | { // New format | ||
186 | uint xloc, yloc; | ||
187 | string mapName; | ||
188 | try | ||
182 | { | 189 | { |
183 | LoadXmlLinkFile(cmdparams.ToArray()); | 190 | xloc = Convert.ToUInt32(cmdparams[0]); |
191 | yloc = Convert.ToUInt32(cmdparams[1]); | ||
192 | mapName = cmdparams[2]; | ||
193 | if (cmdparams.Count > 3) | ||
194 | for (int i = 3; i < cmdparams.Count; i++) | ||
195 | mapName += " " + cmdparams[i]; | ||
196 | |||
197 | Console.WriteLine(">> MapName: " + mapName); | ||
198 | //internalPort = Convert.ToUInt32(cmdparams[4]); | ||
199 | //remotingPort = Convert.ToUInt32(cmdparams[5]); | ||
184 | } | 200 | } |
185 | else | 201 | catch (Exception e) |
186 | { | 202 | { |
203 | m_log.Warn("[HGrid] Wrong format for link-region command: " + e.Message); | ||
187 | LinkRegionCmdUsage(); | 204 | LinkRegionCmdUsage(); |
205 | return; | ||
188 | } | 206 | } |
189 | return; | ||
190 | } | ||
191 | 207 | ||
192 | RegionInfo regInfo; | 208 | HGHyperlink.TryLinkRegionToCoords(m_sceneManager.CurrentOrFirstScene, null, mapName, xloc, yloc); |
193 | uint xloc, yloc; | ||
194 | uint externalPort; | ||
195 | string externalHostName; | ||
196 | try | ||
197 | { | ||
198 | xloc = Convert.ToUInt32(cmdparams[0]); | ||
199 | yloc = Convert.ToUInt32(cmdparams[1]); | ||
200 | externalPort = Convert.ToUInt32(cmdparams[3]); | ||
201 | externalHostName = cmdparams[2]; | ||
202 | //internalPort = Convert.ToUInt32(cmdparams[4]); | ||
203 | //remotingPort = Convert.ToUInt32(cmdparams[5]); | ||
204 | } | ||
205 | catch (Exception e) | ||
206 | { | ||
207 | m_log.Warn("[HGrid] Wrong format for link-region command: " + e.Message); | ||
208 | LinkRegionCmdUsage(); | ||
209 | return; | ||
210 | } | 209 | } |
210 | else | ||
211 | { // old format | ||
212 | RegionInfo regInfo; | ||
213 | uint xloc, yloc; | ||
214 | uint externalPort; | ||
215 | string externalHostName; | ||
216 | try | ||
217 | { | ||
218 | xloc = Convert.ToUInt32(cmdparams[0]); | ||
219 | yloc = Convert.ToUInt32(cmdparams[1]); | ||
220 | externalPort = Convert.ToUInt32(cmdparams[3]); | ||
221 | externalHostName = cmdparams[2]; | ||
222 | //internalPort = Convert.ToUInt32(cmdparams[4]); | ||
223 | //remotingPort = Convert.ToUInt32(cmdparams[5]); | ||
224 | } | ||
225 | catch (Exception e) | ||
226 | { | ||
227 | m_log.Warn("[HGrid] Wrong format for link-region command: " + e.Message); | ||
228 | LinkRegionCmdUsage(); | ||
229 | return; | ||
230 | } | ||
211 | 231 | ||
212 | if (TryCreateLink(xloc, yloc, externalPort, externalHostName, out regInfo)) | 232 | //if (TryCreateLink(xloc, yloc, externalPort, externalHostName, out regInfo)) |
213 | { | 233 | if (HGHyperlink.TryCreateLink(m_sceneManager.CurrentOrFirstScene, null, xloc, yloc, "", externalPort, externalHostName, out regInfo)) |
214 | if (cmdparams.Count >= 5) | ||
215 | { | 234 | { |
216 | regInfo.RegionName = ""; | 235 | if (cmdparams.Count >= 5) |
217 | for (int i = 4; i < cmdparams.Count; i++) | 236 | { |
218 | regInfo.RegionName += cmdparams[i] + " "; | 237 | regInfo.RegionName = ""; |
238 | for (int i = 4; i < cmdparams.Count; i++) | ||
239 | regInfo.RegionName += cmdparams[i] + " "; | ||
240 | } | ||
219 | } | 241 | } |
220 | } | 242 | } |
221 | |||
222 | return; | 243 | return; |
223 | } | 244 | } |
224 | } | 245 | } |
@@ -292,49 +313,16 @@ namespace OpenSim | |||
292 | 313 | ||
293 | if (((realXLoc == 0) && (realYLoc == 0)) || (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) && ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896)))) | 314 | if (((realXLoc == 0) && (realYLoc == 0)) || (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) && ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896)))) |
294 | { | 315 | { |
295 | if (TryCreateLink(xloc, yloc, externalPort, externalHostName, out regInfo)) | 316 | if (HGHyperlink.TryCreateLink(m_sceneManager.CurrentOrFirstScene, null, xloc, yloc, "", externalPort, externalHostName, out regInfo)) |
296 | { | 317 | { |
297 | regInfo.RegionName = config.GetString("localName", ""); | 318 | regInfo.RegionName = config.GetString("localName", ""); |
298 | } | 319 | } |
299 | } | 320 | } |
300 | } | 321 | } |
301 | 322 | ||
302 | private bool TryCreateLink(uint xloc, uint yloc, uint externalPort, string externalHostName, out RegionInfo regInfo) | ||
303 | { | ||
304 | regInfo = new RegionInfo(); | ||
305 | regInfo.RegionLocX = xloc; | ||
306 | regInfo.RegionLocY = yloc; | ||
307 | regInfo.ExternalHostName = externalHostName; | ||
308 | regInfo.HttpPort = externalPort; | ||
309 | //regInfo.RemotingPort = remotingPort; | ||
310 | try | ||
311 | { | ||
312 | regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0); | ||
313 | } | ||
314 | catch (Exception e) | ||
315 | { | ||
316 | m_log.Warn("[HGrid] Wrong format for link-region command: " + e.Message); | ||
317 | LinkRegionCmdUsage(); | ||
318 | return false; | ||
319 | } | ||
320 | regInfo.RemotingAddress = regInfo.ExternalEndPoint.Address.ToString(); | ||
321 | |||
322 | // Finally, link it | ||
323 | try | ||
324 | { | ||
325 | m_sceneManager.CurrentOrFirstScene.CommsManager.GridService.RegisterRegion(regInfo); | ||
326 | } | ||
327 | catch (Exception e) | ||
328 | { | ||
329 | m_log.Warn("[HGrid] Unable to link region: " + e.StackTrace); | ||
330 | return false; | ||
331 | } | ||
332 | |||
333 | return true; | ||
334 | } | ||
335 | |||
336 | private void LinkRegionCmdUsage() | 323 | private void LinkRegionCmdUsage() |
337 | { | 324 | { |
325 | Console.WriteLine("Usage: link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>]"); | ||
338 | Console.WriteLine("Usage: link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]"); | 326 | Console.WriteLine("Usage: link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]"); |
339 | } | 327 | } |
340 | } | 328 | } |
diff --git a/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs b/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs index a39161b..2ca956b 100644 --- a/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs +++ b/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs | |||
@@ -329,14 +329,13 @@ namespace OpenSim.Region.Communications.Hypergrid | |||
329 | info.RegionSettings.TerrainImageID = ass.Metadata.FullID; | 329 | info.RegionSettings.TerrainImageID = ass.Metadata.FullID; |
330 | ass.Metadata.Type = (int)AssetType.Texture; | 330 | ass.Metadata.Type = (int)AssetType.Texture; |
331 | ass.Metadata.Temporary = false; | 331 | ass.Metadata.Temporary = false; |
332 | //imageData.CopyTo(ass.Data, 0); | ||
333 | ass.Data = imageData; | 332 | ass.Data = imageData; |
334 | m_assetcache.AddAsset(ass); | 333 | m_assetcache.AddAsset(ass); |
335 | 334 | ||
336 | } | 335 | } |
337 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke | 336 | catch // LEGIT: Catching problems caused by OpenJPEG p/invoke |
338 | { | 337 | { |
339 | Console.WriteLine("Failed getting/storing map image: " + e); | 338 | Console.WriteLine("[HGrid]: Failed getting/storing map image, because it is probably already in the cache"); |
340 | } | 339 | } |
341 | } | 340 | } |
342 | 341 | ||
@@ -463,6 +462,7 @@ namespace OpenSim.Region.Communications.Hypergrid | |||
463 | if (hash["region_name"] != null) | 462 | if (hash["region_name"] != null) |
464 | { | 463 | { |
465 | info.RegionName = (string)hash["region_name"]; | 464 | info.RegionName = (string)hash["region_name"]; |
465 | //Console.WriteLine(">> " + info.RegionName); | ||
466 | } | 466 | } |
467 | if (hash["internal_port"] != null) | 467 | if (hash["internal_port"] != null) |
468 | { | 468 | { |
diff --git a/OpenSim/Region/Environment/Modules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/Environment/Modules/World/WorldMap/MapSearchModule.cs index fcac7e1..43ed1e4 100644 --- a/OpenSim/Region/Environment/Modules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/Environment/Modules/World/WorldMap/MapSearchModule.cs | |||
@@ -44,7 +44,7 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap | |||
44 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
46 | Scene m_scene = null; // only need one for communication with GridService | 46 | Scene m_scene = null; // only need one for communication with GridService |
47 | private Random random; | 47 | List<Scene> m_scenes = new List<Scene>(); |
48 | 48 | ||
49 | #region IRegionModule Members | 49 | #region IRegionModule Members |
50 | public void Initialise(Scene scene, IConfigSource source) | 50 | public void Initialise(Scene scene, IConfigSource source) |
@@ -52,9 +52,9 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap | |||
52 | if (m_scene == null) | 52 | if (m_scene == null) |
53 | { | 53 | { |
54 | m_scene = scene; | 54 | m_scene = scene; |
55 | random = new Random(); | ||
56 | } | 55 | } |
57 | 56 | ||
57 | m_scenes.Add(scene); | ||
58 | scene.EventManager.OnNewClient += OnNewClient; | 58 | scene.EventManager.OnNewClient += OnNewClient; |
59 | } | 59 | } |
60 | 60 | ||
@@ -65,6 +65,7 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap | |||
65 | public void Close() | 65 | public void Close() |
66 | { | 66 | { |
67 | m_scene = null; | 67 | m_scene = null; |
68 | m_scenes.Clear(); | ||
68 | } | 69 | } |
69 | 70 | ||
70 | public string Name | 71 | public string Name |
@@ -110,7 +111,11 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap | |||
110 | if (mapName.Contains(".") && mapName.Contains(":")) | 111 | if (mapName.Contains(".") && mapName.Contains(":")) |
111 | { | 112 | { |
112 | // It probably is a domain name. Try to link to it. | 113 | // It probably is a domain name. Try to link to it. |
113 | TryLinkRegion(remoteClient, mapName, regionInfos); | 114 | RegionInfo regInfo; |
115 | Scene cScene = GetClientScene(remoteClient); | ||
116 | regInfo = HGHyperlink.TryLinkRegion(cScene, remoteClient, mapName); | ||
117 | if (regInfo != null) | ||
118 | regionInfos.Add(regInfo); | ||
114 | } | 119 | } |
115 | } | 120 | } |
116 | 121 | ||
@@ -154,116 +159,14 @@ namespace OpenSim.Region.Environment.Modules.World.WorldMap | |||
154 | return (m_scene.SceneGridService is HGSceneCommunicationService); | 159 | return (m_scene.SceneGridService is HGSceneCommunicationService); |
155 | } | 160 | } |
156 | 161 | ||
157 | private void TryLinkRegion(IClientAPI client, string mapName, List<RegionInfo> regionInfos) | 162 | private Scene GetClientScene(IClientAPI client) |
158 | { | 163 | { |
159 | string host = "127.0.0.1"; | 164 | foreach (Scene s in m_scenes) |
160 | string portstr; | ||
161 | uint port = 9000; | ||
162 | string[] parts = mapName.Split(new char[] { ':' }); | ||
163 | if (parts.Length >= 1) | ||
164 | { | 165 | { |
165 | host = parts[0]; | 166 | if (client.Scene.RegionInfo.RegionHandle == s.RegionInfo.RegionHandle) |
167 | return s; | ||
166 | } | 168 | } |
167 | if (parts.Length >= 2) | 169 | return m_scene; |
168 | { | ||
169 | portstr = parts[1]; | ||
170 | UInt32.TryParse(portstr, out port); | ||
171 | } | ||
172 | |||
173 | // Sanity check. Don't ever link to this sim. | ||
174 | IPAddress ipaddr = null; | ||
175 | try | ||
176 | { | ||
177 | ipaddr = Util.GetHostFromDNS(host); | ||
178 | } | ||
179 | catch { } | ||
180 | |||
181 | if ((ipaddr != null) && | ||
182 | !((m_scene.RegionInfo.ExternalEndPoint.Address.Equals(ipaddr)) && (m_scene.RegionInfo.HttpPort == port))) | ||
183 | { | ||
184 | uint xloc = (uint)(random.Next(0, Int16.MaxValue)); | ||
185 | RegionInfo regInfo; | ||
186 | bool success = TryCreateLink(client, xloc, 0, port, host, out regInfo); | ||
187 | if (success) | ||
188 | { | ||
189 | regInfo.RegionName = mapName; | ||
190 | regionInfos.Add(regInfo); | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
195 | private bool TryCreateLink(IClientAPI client, uint xloc, uint yloc, uint externalPort, string externalHostName, out RegionInfo regInfo) | ||
196 | { | ||
197 | m_log.DebugFormat("[HGrid]: Dynamic link to {0}:{1}, in {2}-{3}", externalHostName, externalPort, xloc, yloc); | ||
198 | |||
199 | regInfo = new RegionInfo(); | ||
200 | regInfo.RegionLocX = xloc; | ||
201 | regInfo.RegionLocY = yloc; | ||
202 | regInfo.ExternalHostName = externalHostName; | ||
203 | regInfo.HttpPort = externalPort; | ||
204 | try | ||
205 | { | ||
206 | regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0); | ||
207 | } | ||
208 | catch (Exception e) | ||
209 | { | ||
210 | m_log.Warn("[HGrid] Wrong format for link-region: " + e.Message); | ||
211 | return false; | ||
212 | } | ||
213 | //regInfo.RemotingAddress = regInfo.ExternalEndPoint.Address.ToString(); | ||
214 | |||
215 | // Finally, link it | ||
216 | try | ||
217 | { | ||
218 | m_scene.CommsManager.GridService.RegisterRegion(regInfo); | ||
219 | } | ||
220 | catch (Exception e) | ||
221 | { | ||
222 | m_log.Warn("[HGrid] Unable to dynamically link region: " + e.Message); | ||
223 | return false; | ||
224 | } | ||
225 | |||
226 | if (!Check4096(client, regInfo)) | ||
227 | { | ||
228 | return false; | ||
229 | } | ||
230 | |||
231 | m_log.Debug("[HGrid] Dynamic link region succeeded"); | ||
232 | return true; | ||
233 | } | 170 | } |
234 | |||
235 | /// <summary> | ||
236 | /// Cope with this viewer limitation. | ||
237 | /// </summary> | ||
238 | /// <param name="regInfo"></param> | ||
239 | /// <returns></returns> | ||
240 | private bool Check4096(IClientAPI client, RegionInfo regInfo) | ||
241 | { | ||
242 | ulong realHandle; | ||
243 | if (UInt64.TryParse(regInfo.regionSecret, out realHandle)) | ||
244 | { | ||
245 | uint x, y; | ||
246 | Utils.LongToUInts(realHandle, out x, out y); | ||
247 | x = x / Constants.RegionSize; | ||
248 | y = y / Constants.RegionSize; | ||
249 | |||
250 | if ((Math.Abs((int)m_scene.RegionInfo.RegionLocX - (int)x) >= 4096) || | ||
251 | (Math.Abs((int)m_scene.RegionInfo.RegionLocY - (int)y) >= 4096)) | ||
252 | { | ||
253 | m_scene.CommsManager.GridService.DeregisterRegion(regInfo); | ||
254 | m_log.Debug("[HGrid]: Region deregistered."); | ||
255 | client.SendAlertMessage("Region is too far (" + x + ", " + y + ")"); | ||
256 | return false; | ||
257 | } | ||
258 | return true; | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | m_scene.CommsManager.GridService.RegisterRegion(regInfo); | ||
263 | m_log.Debug("[HGrid]: Gnomes. Region deregistered."); | ||
264 | return false; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | } | 171 | } |
269 | } | 172 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGHyperlink.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGHyperlink.cs new file mode 100644 index 0000000..6ee28cb --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGHyperlink.cs | |||
@@ -0,0 +1,192 @@ | |||
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 OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using System.Net; | ||
31 | using OpenSim.Framework; | ||
32 | using OpenSim.Framework.Communications; | ||
33 | using OpenMetaverse; | ||
34 | using log4net; | ||
35 | using Nini.Config; | ||
36 | |||
37 | namespace OpenSim.Region.Framework.Scenes.Hypergrid | ||
38 | { | ||
39 | public class HGHyperlink | ||
40 | { | ||
41 | private static readonly ILog m_log = | ||
42 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
43 | private static Random random = new Random(); | ||
44 | |||
45 | public static RegionInfo TryLinkRegionToCoords(Scene m_scene, IClientAPI client, string mapName, uint xloc, uint yloc) | ||
46 | { | ||
47 | string host = "127.0.0.1"; | ||
48 | string portstr; | ||
49 | string regionName = ""; | ||
50 | uint port = 9000; | ||
51 | string[] parts = mapName.Split(new char[] { ':' }); | ||
52 | if (parts.Length >= 1) | ||
53 | { | ||
54 | host = parts[0]; | ||
55 | } | ||
56 | if (parts.Length >= 2) | ||
57 | { | ||
58 | portstr = parts[1]; | ||
59 | if (!UInt32.TryParse(portstr, out port)) | ||
60 | regionName = parts[1]; | ||
61 | } | ||
62 | // always take the last one | ||
63 | if (parts.Length >= 3) | ||
64 | { | ||
65 | regionName = parts[2]; | ||
66 | } | ||
67 | |||
68 | // Sanity check. Don't ever link to this sim. | ||
69 | IPAddress ipaddr = null; | ||
70 | try | ||
71 | { | ||
72 | ipaddr = Util.GetHostFromDNS(host); | ||
73 | } | ||
74 | catch { } | ||
75 | |||
76 | if ((ipaddr != null) && | ||
77 | !((m_scene.RegionInfo.ExternalEndPoint.Address.Equals(ipaddr)) && (m_scene.RegionInfo.HttpPort == port))) | ||
78 | { | ||
79 | RegionInfo regInfo; | ||
80 | bool success = TryCreateLink(m_scene, client, xloc, yloc, regionName, port, host, out regInfo); | ||
81 | if (success) | ||
82 | { | ||
83 | regInfo.RegionName = mapName; | ||
84 | return regInfo; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | return null; | ||
89 | } | ||
90 | |||
91 | public static RegionInfo TryLinkRegion(Scene m_scene, IClientAPI client, string mapName) | ||
92 | { | ||
93 | uint xloc = (uint)(random.Next(0, Int16.MaxValue)); | ||
94 | return TryLinkRegionToCoords(m_scene, client, mapName, xloc, 0); | ||
95 | } | ||
96 | |||
97 | public static bool TryCreateLink(Scene m_scene, IClientAPI client, uint xloc, uint yloc, | ||
98 | string externalRegionName, uint externalPort, string externalHostName, out RegionInfo regInfo) | ||
99 | { | ||
100 | m_log.DebugFormat("[HGrid]: Link to {0}:{1}, in {2}-{3}", externalHostName, externalPort, xloc, yloc); | ||
101 | |||
102 | regInfo = new RegionInfo(); | ||
103 | regInfo.RegionName = externalRegionName; | ||
104 | regInfo.HttpPort = externalPort; | ||
105 | regInfo.ExternalHostName = externalHostName; | ||
106 | regInfo.RegionLocX = xloc; | ||
107 | regInfo.RegionLocY = yloc; | ||
108 | |||
109 | try | ||
110 | { | ||
111 | regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0); | ||
112 | } | ||
113 | catch (Exception e) | ||
114 | { | ||
115 | m_log.Warn("[HGrid]: Wrong format for link-region: " + e.Message); | ||
116 | return false; | ||
117 | } | ||
118 | //regInfo.RemotingAddress = regInfo.ExternalEndPoint.Address.ToString(); | ||
119 | |||
120 | // Finally, link it | ||
121 | try | ||
122 | { | ||
123 | m_scene.CommsManager.GridService.RegisterRegion(regInfo); | ||
124 | } | ||
125 | catch (Exception e) | ||
126 | { | ||
127 | m_log.Warn("[HGrid]: Unable to link region: " + e.Message); | ||
128 | return false; | ||
129 | } | ||
130 | |||
131 | uint x, y; | ||
132 | if (!Check4096(m_scene, regInfo, out x, out y)) | ||
133 | { | ||
134 | m_scene.CommsManager.GridService.DeregisterRegion(regInfo); | ||
135 | if (client != null) | ||
136 | client.SendAlertMessage("Region is too far (" + x + ", " + y + ")"); | ||
137 | m_log.Info("[HGrid]: Unable to link, region is too far (" + x + ", " + y + ")"); | ||
138 | return false; | ||
139 | } | ||
140 | |||
141 | if (!CheckCoords(m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, x, y)) | ||
142 | { | ||
143 | m_scene.CommsManager.GridService.DeregisterRegion(regInfo); | ||
144 | if (client != null) | ||
145 | client.SendAlertMessage("Region has incompatible coordinates (" + x + ", " + y + ")"); | ||
146 | m_log.Info("[HGrid]: Unable to link, region has incompatible coordinates (" + x + ", " + y + ")"); | ||
147 | return false; | ||
148 | } | ||
149 | |||
150 | m_log.Debug("[HGrid]: link region succeeded"); | ||
151 | return true; | ||
152 | } | ||
153 | |||
154 | /// <summary> | ||
155 | /// Cope with this viewer limitation. | ||
156 | /// </summary> | ||
157 | /// <param name="regInfo"></param> | ||
158 | /// <returns></returns> | ||
159 | public static bool Check4096(Scene m_scene, RegionInfo regInfo, out uint x, out uint y) | ||
160 | { | ||
161 | ulong realHandle; | ||
162 | if (UInt64.TryParse(regInfo.regionSecret, out realHandle)) | ||
163 | { | ||
164 | Utils.LongToUInts(realHandle, out x, out y); | ||
165 | x = x / Constants.RegionSize; | ||
166 | y = y / Constants.RegionSize; | ||
167 | |||
168 | if ((Math.Abs((int)m_scene.RegionInfo.RegionLocX - (int)x) >= 4096) || | ||
169 | (Math.Abs((int)m_scene.RegionInfo.RegionLocY - (int)y) >= 4096)) | ||
170 | { | ||
171 | return false; | ||
172 | } | ||
173 | return true; | ||
174 | } | ||
175 | else | ||
176 | { | ||
177 | m_scene.CommsManager.GridService.RegisterRegion(regInfo); | ||
178 | m_log.Debug("[HGrid]: Gnomes. Region deregistered."); | ||
179 | x = y = 0; | ||
180 | return false; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | public static bool CheckCoords(uint thisx, uint thisy, uint x, uint y) | ||
185 | { | ||
186 | if ((thisx == x) && (thisy == y)) | ||
187 | return false; | ||
188 | return true; | ||
189 | } | ||
190 | |||
191 | } | ||
192 | } | ||