opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Collections.Generic;
30 using System.Collections.Specialized;
31 using System.IO;
32 using System.Net;
33 using System.Reflection;
34 using log4net;
35 using Mono.Addins;
36 using Nini.Config;
37 using OpenSim.Framework;
38 using OpenSim.Region.Framework.Interfaces;
39 using OpenSim.Region.Framework.Scenes;
40 using OpenSim.Services.Interfaces;
41 using OpenMetaverse;
42 using OpenMetaverse.StructuredData;
43  
44 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45  
46 namespace OpenSim.Services.Connectors.SimianGrid
47 {
48 /// <summary>
49 /// Connects region registration and neighbor lookups to the SimianGrid
50 /// backend
51 /// </summary>
52 public class SimianGridServiceConnector : IGridService
53 {
54 private static readonly ILog m_log =
55 LogManager.GetLogger(
56 MethodBase.GetCurrentMethod().DeclaringType);
57  
58 private string m_ServerURI = String.Empty;
59 // private bool m_Enabled = false;
60  
61 public SimianGridServiceConnector() { }
62 public SimianGridServiceConnector(string serverURI)
63 {
64 m_ServerURI = serverURI.TrimEnd('/');
65 }
66  
67 public SimianGridServiceConnector(IConfigSource source)
68 {
69 CommonInit(source);
70 }
71  
72 public void Initialise(IConfigSource source)
73 {
74 CommonInit(source);
75 }
76  
77 private void CommonInit(IConfigSource source)
78 {
79 IConfig gridConfig = source.Configs["GridService"];
80 if (gridConfig == null)
81 {
82 m_log.Error("[SIMIAN GRID CONNECTOR]: GridService missing from OpenSim.ini");
83 throw new Exception("Grid connector init error");
84 }
85  
86 string serviceUrl = gridConfig.GetString("GridServerURI");
87 if (String.IsNullOrEmpty(serviceUrl))
88 {
89 m_log.Error("[SIMIAN GRID CONNECTOR]: No Server URI named in section GridService");
90 throw new Exception("Grid connector init error");
91 }
92  
93 if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("="))
94 serviceUrl = serviceUrl + '/';
95 m_ServerURI = serviceUrl;
96 // m_Enabled = true;
97 }
98  
99 #region IGridService
100  
101 public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
102 {
103 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0);
104 Vector3d maxPosition = minPosition + new Vector3d(regionInfo.RegionSizeX, regionInfo.RegionSizeY, Constants.RegionHeight);
105  
106 OSDMap extraData = new OSDMap
107 {
108 { "ServerURI", OSD.FromString(regionInfo.ServerURI) },
109 { "InternalAddress", OSD.FromString(regionInfo.InternalEndPoint.Address.ToString()) },
110 { "InternalPort", OSD.FromInteger(regionInfo.InternalEndPoint.Port) },
111 { "ExternalAddress", OSD.FromString(regionInfo.ExternalEndPoint.Address.ToString()) },
112 { "ExternalPort", OSD.FromInteger(regionInfo.ExternalEndPoint.Port) },
113 { "MapTexture", OSD.FromUUID(regionInfo.TerrainImage) },
114 { "Access", OSD.FromInteger(regionInfo.Access) },
115 { "RegionSecret", OSD.FromString(regionInfo.RegionSecret) },
116 { "EstateOwner", OSD.FromUUID(regionInfo.EstateOwner) },
117 { "Token", OSD.FromString(regionInfo.Token) }
118 };
119  
120 NameValueCollection requestArgs = new NameValueCollection
121 {
122 { "RequestMethod", "AddScene" },
123 { "SceneID", regionInfo.RegionID.ToString() },
124 { "Name", regionInfo.RegionName },
125 { "MinPosition", minPosition.ToString() },
126 { "MaxPosition", maxPosition.ToString() },
127 { "Address", regionInfo.ServerURI },
128 { "Enabled", "1" },
129 { "ExtraData", OSDParser.SerializeJsonString(extraData) }
130 };
131  
132 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
133 if (response["Success"].AsBoolean())
134 return String.Empty;
135 else
136 return "Region registration for " + regionInfo.RegionName + " failed: " + response["Message"].AsString();
137 }
138  
139 public bool DeregisterRegion(UUID regionID)
140 {
141 NameValueCollection requestArgs = new NameValueCollection
142 {
143 { "RequestMethod", "AddScene" },
144 { "SceneID", regionID.ToString() },
145 { "Enabled", "0" }
146 };
147  
148 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
149 bool success = response["Success"].AsBoolean();
150  
151 if (!success)
152 m_log.Warn("[SIMIAN GRID CONNECTOR]: Region deregistration for " + regionID + " failed: " + response["Message"].AsString());
153  
154 return success;
155 }
156  
157 public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID)
158 {
159 GridRegion region = GetRegionByUUID(scopeID, regionID);
160  
161 int NEIGHBOR_RADIUS = Math.Max(region.RegionSizeX, region.RegionSizeY) / 2;
162  
163 if (region != null)
164 {
165 List<GridRegion> regions = GetRegionRange(scopeID,
166 region.RegionLocX - NEIGHBOR_RADIUS, region.RegionLocX + region.RegionSizeX + NEIGHBOR_RADIUS,
167 region.RegionLocY - NEIGHBOR_RADIUS, region.RegionLocY + region.RegionSizeY + NEIGHBOR_RADIUS);
168  
169 for (int i = 0; i < regions.Count; i++)
170 {
171 if (regions[i].RegionID == regionID)
172 {
173 regions.RemoveAt(i);
174 break;
175 }
176 }
177  
178 // m_log.Debug("[SIMIAN GRID CONNECTOR]: Found " + regions.Count + " neighbors for region " + regionID);
179 return regions;
180 }
181  
182 return new List<GridRegion>(0);
183 }
184  
185 public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
186 {
187 NameValueCollection requestArgs = new NameValueCollection
188 {
189 { "RequestMethod", "GetScene" },
190 { "SceneID", regionID.ToString() }
191 };
192  
193 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request region with uuid {0}",regionID.ToString());
194  
195 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
196 if (response["Success"].AsBoolean())
197 {
198 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] uuid request successful {0}",response["Name"].AsString());
199 return ResponseToGridRegion(response);
200 }
201 else
202 {
203 m_log.Warn("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region " + regionID);
204 return null;
205 }
206 }
207  
208 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
209 {
210 // Go one meter in from the requested x/y coords to avoid requesting a position
211 // that falls on the border of two sims
212 Vector3d position = new Vector3d(x + 1, y + 1, 0.0);
213  
214 NameValueCollection requestArgs = new NameValueCollection
215 {
216 { "RequestMethod", "GetScene" },
217 { "Position", position.ToString() },
218 { "Enabled", "1" }
219 };
220  
221 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request grid at {0}",position.ToString());
222  
223 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
224 if (response["Success"].AsBoolean())
225 {
226 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] position request successful {0}",response["Name"].AsString());
227 return ResponseToGridRegion(response);
228 }
229 else
230 {
231 // m_log.InfoFormat("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region at {0},{1}",
232 // Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y));
233 return null;
234 }
235 }
236  
237 public GridRegion GetRegionByName(UUID scopeID, string regionName)
238 {
239 List<GridRegion> regions = GetRegionsByName(scopeID, regionName, 1);
240  
241 m_log.Debug("[SIMIAN GRID CONNECTOR]: Got " + regions.Count + " matches for region name " + regionName);
242  
243 if (regions.Count > 0)
244 return regions[0];
245  
246 return null;
247 }
248  
249 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
250 {
251 List<GridRegion> foundRegions = new List<GridRegion>();
252  
253 NameValueCollection requestArgs = new NameValueCollection
254 {
255 { "RequestMethod", "GetScenes" },
256 { "NameQuery", name },
257 { "Enabled", "1" }
258 };
259 if (maxNumber > 0)
260 requestArgs["MaxNumber"] = maxNumber.ToString();
261  
262 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request regions with name {0}",name);
263  
264 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
265 if (response["Success"].AsBoolean())
266 {
267 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] found regions with name {0}",name);
268  
269 OSDArray array = response["Scenes"] as OSDArray;
270 if (array != null)
271 {
272 for (int i = 0; i < array.Count; i++)
273 {
274 GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
275 if (region != null)
276 foundRegions.Add(region);
277 }
278 }
279 }
280  
281 return foundRegions;
282 }
283  
284 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
285 {
286 List<GridRegion> foundRegions = new List<GridRegion>();
287  
288 Vector3d minPosition = new Vector3d(xmin, ymin, 0.0);
289 Vector3d maxPosition = new Vector3d(xmax, ymax, Constants.RegionHeight);
290  
291 NameValueCollection requestArgs = new NameValueCollection
292 {
293 { "RequestMethod", "GetScenes" },
294 { "MinPosition", minPosition.ToString() },
295 { "MaxPosition", maxPosition.ToString() },
296 { "Enabled", "1" }
297 };
298  
299 //m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request regions by range {0} to {1}",minPosition.ToString(),maxPosition.ToString());
300  
301  
302 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
303 if (response["Success"].AsBoolean())
304 {
305 OSDArray array = response["Scenes"] as OSDArray;
306 if (array != null)
307 {
308 for (int i = 0; i < array.Count; i++)
309 {
310 GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
311 if (region != null)
312 foundRegions.Add(region);
313 }
314 }
315 }
316  
317 return foundRegions;
318 }
319  
320 public List<GridRegion> GetDefaultRegions(UUID scopeID)
321 {
322 // TODO: Allow specifying the default grid location
323 const int DEFAULT_X = 1000 * 256;
324 const int DEFAULT_Y = 1000 * 256;
325  
326 GridRegion defRegion = GetNearestRegion(new Vector3d(DEFAULT_X, DEFAULT_Y, 0.0), true);
327 if (defRegion != null)
328 return new List<GridRegion>(1) { defRegion };
329 else
330 return new List<GridRegion>(0);
331 }
332  
333 public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
334 {
335 // TODO: Allow specifying the default grid location
336 return GetDefaultRegions(scopeID);
337 }
338  
339 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
340 {
341 GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true);
342 if (defRegion != null)
343 return new List<GridRegion>(1) { defRegion };
344 else
345 return new List<GridRegion>(0);
346 }
347  
348 public List<GridRegion> GetHyperlinks(UUID scopeID)
349 {
350 List<GridRegion> foundRegions = new List<GridRegion>();
351  
352 NameValueCollection requestArgs = new NameValueCollection
353 {
354 { "RequestMethod", "GetScenes" },
355 { "HyperGrid", "true" },
356 { "Enabled", "1" }
357 };
358  
359 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
360 if (response["Success"].AsBoolean())
361 {
362 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] found regions with name {0}",name);
363  
364 OSDArray array = response["Scenes"] as OSDArray;
365 if (array != null)
366 {
367 for (int i = 0; i < array.Count; i++)
368 {
369 GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
370 if (region != null)
371 foundRegions.Add(region);
372 }
373 }
374 }
375  
376 return foundRegions;
377 }
378  
379 public int GetRegionFlags(UUID scopeID, UUID regionID)
380 {
381 NameValueCollection requestArgs = new NameValueCollection
382 {
383 { "RequestMethod", "GetScene" },
384 { "SceneID", regionID.ToString() }
385 };
386  
387 m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request region flags for {0}",regionID.ToString());
388  
389 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
390 if (response["Success"].AsBoolean())
391 {
392 OSDMap extraData = response["ExtraData"] as OSDMap;
393 int enabled = response["Enabled"].AsBoolean() ? (int)OpenSim.Framework.RegionFlags.RegionOnline : 0;
394 int hypergrid = extraData["HyperGrid"].AsBoolean() ? (int)OpenSim.Framework.RegionFlags.Hyperlink : 0;
395 int flags = enabled | hypergrid;
396 m_log.DebugFormat("[SGGC] enabled - {0} hg - {1} flags - {2}", enabled, hypergrid, flags);
397 return flags;
398 }
399 else
400 {
401 m_log.Warn("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region " + regionID + " during region flags check");
402 return -1;
403 }
404 }
405  
406 #endregion IGridService
407  
408 private GridRegion GetNearestRegion(Vector3d position, bool onlyEnabled)
409 {
410 NameValueCollection requestArgs = new NameValueCollection
411 {
412 { "RequestMethod", "GetScene" },
413 { "Position", position.ToString() },
414 { "FindClosest", "1" }
415 };
416 if (onlyEnabled)
417 requestArgs["Enabled"] = "1";
418  
419 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
420 if (response["Success"].AsBoolean())
421 {
422 return ResponseToGridRegion(response);
423 }
424 else
425 {
426 m_log.Warn("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region at " + position);
427 return null;
428 }
429 }
430  
431 private GridRegion ResponseToGridRegion(OSDMap response)
432 {
433 if (response == null)
434 return null;
435  
436 OSDMap extraData = response["ExtraData"] as OSDMap;
437 if (extraData == null)
438 return null;
439  
440 GridRegion region = new GridRegion();
441  
442 region.RegionID = response["SceneID"].AsUUID();
443 region.RegionName = response["Name"].AsString();
444  
445 Vector3d minPosition = response["MinPosition"].AsVector3d();
446 Vector3d maxPosition = response["MaxPosition"].AsVector3d();
447 region.RegionLocX = (int)minPosition.X;
448 region.RegionLocY = (int)minPosition.Y;
449  
450 region.RegionSizeX = (int)maxPosition.X - (int)minPosition.X;
451 region.RegionSizeY = (int)maxPosition.Y - (int)minPosition.Y;
452  
453 if ( ! extraData["HyperGrid"] ) {
454 Uri httpAddress = response["Address"].AsUri();
455 region.ExternalHostName = httpAddress.Host;
456 region.HttpPort = (uint)httpAddress.Port;
457  
458 IPAddress internalAddress;
459 IPAddress.TryParse(extraData["InternalAddress"].AsString(), out internalAddress);
460 if (internalAddress == null)
461 internalAddress = IPAddress.Any;
462  
463 region.InternalEndPoint = new IPEndPoint(internalAddress, extraData["InternalPort"].AsInteger());
464 region.TerrainImage = extraData["MapTexture"].AsUUID();
465 region.Access = (byte)extraData["Access"].AsInteger();
466 region.RegionSecret = extraData["RegionSecret"].AsString();
467 region.EstateOwner = extraData["EstateOwner"].AsUUID();
468 region.Token = extraData["Token"].AsString();
469 region.ServerURI = extraData["ServerURI"].AsString();
470 } else {
471 region.ServerURI = response["Address"];
472 }
473  
474 return region;
475 }
476 }
477 }