diff options
Diffstat (limited to 'OpenSim/Region/Communications/OGS1/OGS1GridServices.cs')
-rw-r--r-- | OpenSim/Region/Communications/OGS1/OGS1GridServices.cs | 937 |
1 files changed, 0 insertions, 937 deletions
diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs deleted file mode 100644 index 47c7fe4..0000000 --- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs +++ /dev/null | |||
@@ -1,937 +0,0 @@ | |||
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; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Net; | ||
32 | using System.Net.Sockets; | ||
33 | using System.Reflection; | ||
34 | using log4net; | ||
35 | using Nwc.XmlRpc; | ||
36 | using OpenMetaverse; | ||
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Framework.Communications; | ||
39 | using OpenSim.Framework.Servers.HttpServer; | ||
40 | using OpenSim.Region.Communications.Local; | ||
41 | |||
42 | namespace OpenSim.Region.Communications.OGS1 | ||
43 | { | ||
44 | public class OGS1GridServices : IGridServices | ||
45 | { | ||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | private bool m_useRemoteRegionCache = true; | ||
49 | /// <summary> | ||
50 | /// Encapsulate local backend services for manipulation of local regions | ||
51 | /// </summary> | ||
52 | private LocalBackEndServices m_localBackend = new LocalBackEndServices(); | ||
53 | |||
54 | private Dictionary<ulong, RegionInfo> m_remoteRegionInfoCache = new Dictionary<ulong, RegionInfo>(); | ||
55 | // private List<SimpleRegionInfo> m_knownRegions = new List<SimpleRegionInfo>(); | ||
56 | private Dictionary<ulong, int> m_deadRegionCache = new Dictionary<ulong, int>(); | ||
57 | private Dictionary<string, string> m_queuedGridSettings = new Dictionary<string, string>(); | ||
58 | private List<RegionInfo> m_regionsOnInstance = new List<RegionInfo>(); | ||
59 | |||
60 | public BaseHttpServer httpListener; | ||
61 | public NetworkServersInfo serversInfo; | ||
62 | |||
63 | public string gdebugRegionName | ||
64 | { | ||
65 | get { return m_localBackend.gdebugRegionName; } | ||
66 | set { m_localBackend.gdebugRegionName = value; } | ||
67 | } | ||
68 | |||
69 | public string rdebugRegionName | ||
70 | { | ||
71 | get { return _rdebugRegionName; } | ||
72 | set { _rdebugRegionName = value; } | ||
73 | } | ||
74 | private string _rdebugRegionName = String.Empty; | ||
75 | |||
76 | public bool RegionLoginsEnabled | ||
77 | { | ||
78 | get { return m_localBackend.RegionLoginsEnabled; } | ||
79 | set { m_localBackend.RegionLoginsEnabled = value; } | ||
80 | } | ||
81 | |||
82 | /// <summary> | ||
83 | /// Contructor. Adds "expect_user" and "check" xmlrpc method handlers | ||
84 | /// </summary> | ||
85 | /// <param name="servers_info"></param> | ||
86 | /// <param name="httpServe"></param> | ||
87 | public OGS1GridServices(NetworkServersInfo servers_info) | ||
88 | { | ||
89 | serversInfo = servers_info; | ||
90 | |||
91 | //Respond to Grid Services requests | ||
92 | MainServer.Instance.AddXmlRPCHandler("check", PingCheckReply); | ||
93 | } | ||
94 | |||
95 | // see IGridServices | ||
96 | public RegionCommsListener RegisterRegion(RegionInfo regionInfo) | ||
97 | { | ||
98 | if (m_regionsOnInstance.Contains(regionInfo)) | ||
99 | { | ||
100 | m_log.Error("[OGS1 GRID SERVICES]: Foobar! Caller is confused, region already registered " + regionInfo.RegionName); | ||
101 | Exception e = new Exception(String.Format("Unable to register region")); | ||
102 | |||
103 | throw e; | ||
104 | } | ||
105 | |||
106 | m_log.InfoFormat( | ||
107 | "[OGS1 GRID SERVICES]: Registering region {0} with grid at {1}", | ||
108 | regionInfo.RegionName, serversInfo.GridURL); | ||
109 | |||
110 | m_regionsOnInstance.Add(regionInfo); | ||
111 | |||
112 | Hashtable GridParams = new Hashtable(); | ||
113 | // Login / Authentication | ||
114 | |||
115 | GridParams["authkey"] = serversInfo.GridSendKey; | ||
116 | GridParams["recvkey"] = serversInfo.GridRecvKey; | ||
117 | GridParams["UUID"] = regionInfo.RegionID.ToString(); | ||
118 | GridParams["sim_ip"] = regionInfo.ExternalHostName; | ||
119 | GridParams["sim_port"] = regionInfo.InternalEndPoint.Port.ToString(); | ||
120 | GridParams["region_locx"] = regionInfo.RegionLocX.ToString(); | ||
121 | GridParams["region_locy"] = regionInfo.RegionLocY.ToString(); | ||
122 | GridParams["sim_name"] = regionInfo.RegionName; | ||
123 | GridParams["http_port"] = serversInfo.HttpListenerPort.ToString(); | ||
124 | GridParams["remoting_port"] = ConfigSettings.DefaultRegionRemotingPort.ToString(); | ||
125 | GridParams["map-image-id"] = regionInfo.RegionSettings.TerrainImageID.ToString(); | ||
126 | GridParams["originUUID"] = regionInfo.originRegionID.ToString(); | ||
127 | GridParams["server_uri"] = regionInfo.ServerURI; | ||
128 | GridParams["region_secret"] = regionInfo.regionSecret; | ||
129 | GridParams["major_interface_version"] = VersionInfo.MajorInterfaceVersion.ToString(); | ||
130 | |||
131 | if (regionInfo.MasterAvatarAssignedUUID != UUID.Zero) | ||
132 | GridParams["master_avatar_uuid"] = regionInfo.MasterAvatarAssignedUUID.ToString(); | ||
133 | else | ||
134 | GridParams["master_avatar_uuid"] = regionInfo.EstateSettings.EstateOwner.ToString(); | ||
135 | |||
136 | GridParams["maturity"] = regionInfo.RegionSettings.Maturity.ToString(); | ||
137 | |||
138 | // Package into an XMLRPC Request | ||
139 | ArrayList SendParams = new ArrayList(); | ||
140 | SendParams.Add(GridParams); | ||
141 | |||
142 | // Send Request | ||
143 | XmlRpcRequest GridReq = new XmlRpcRequest("simulator_login", SendParams); | ||
144 | XmlRpcResponse GridResp; | ||
145 | |||
146 | try | ||
147 | { | ||
148 | // The timeout should always be significantly larger than the timeout for the grid server to request | ||
149 | // the initial status of the region before confirming registration. | ||
150 | GridResp = GridReq.Send(serversInfo.GridURL, 9999999); | ||
151 | } | ||
152 | catch (Exception e) | ||
153 | { | ||
154 | Exception e2 | ||
155 | = new Exception( | ||
156 | String.Format( | ||
157 | "Unable to register region with grid at {0}. Grid service not running?", | ||
158 | serversInfo.GridURL), | ||
159 | e); | ||
160 | |||
161 | throw e2; | ||
162 | } | ||
163 | |||
164 | Hashtable GridRespData = (Hashtable)GridResp.Value; | ||
165 | // Hashtable griddatahash = GridRespData; | ||
166 | |||
167 | // Process Response | ||
168 | if (GridRespData.ContainsKey("error")) | ||
169 | { | ||
170 | string errorstring = (string) GridRespData["error"]; | ||
171 | |||
172 | Exception e = new Exception( | ||
173 | String.Format("Unable to connect to grid at {0}: {1}", serversInfo.GridURL, errorstring)); | ||
174 | |||
175 | throw e; | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | // m_knownRegions = RequestNeighbours(regionInfo.RegionLocX, regionInfo.RegionLocY); | ||
180 | if (GridRespData.ContainsKey("allow_forceful_banlines")) | ||
181 | { | ||
182 | if ((string) GridRespData["allow_forceful_banlines"] != "TRUE") | ||
183 | { | ||
184 | //m_localBackend.SetForcefulBanlistsDisallowed(regionInfo.RegionHandle); | ||
185 | if (!m_queuedGridSettings.ContainsKey("allow_forceful_banlines")) | ||
186 | m_queuedGridSettings.Add("allow_forceful_banlines", "FALSE"); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | m_log.InfoFormat( | ||
191 | "[OGS1 GRID SERVICES]: Region {0} successfully registered with grid at {1}", | ||
192 | regionInfo.RegionName, serversInfo.GridURL); | ||
193 | } | ||
194 | |||
195 | return m_localBackend.RegisterRegion(regionInfo); | ||
196 | } | ||
197 | |||
198 | // see IGridServices | ||
199 | public bool DeregisterRegion(RegionInfo regionInfo) | ||
200 | { | ||
201 | Hashtable GridParams = new Hashtable(); | ||
202 | |||
203 | GridParams["UUID"] = regionInfo.RegionID.ToString(); | ||
204 | |||
205 | // Package into an XMLRPC Request | ||
206 | ArrayList SendParams = new ArrayList(); | ||
207 | SendParams.Add(GridParams); | ||
208 | |||
209 | // Send Request | ||
210 | XmlRpcRequest GridReq = new XmlRpcRequest("simulator_after_region_moved", SendParams); | ||
211 | XmlRpcResponse GridResp = null; | ||
212 | |||
213 | try | ||
214 | { | ||
215 | GridResp = GridReq.Send(serversInfo.GridURL, 10000); | ||
216 | } | ||
217 | catch (Exception e) | ||
218 | { | ||
219 | Exception e2 | ||
220 | = new Exception( | ||
221 | String.Format( | ||
222 | "Unable to deregister region with grid at {0}. Grid service not running?", | ||
223 | serversInfo.GridURL), | ||
224 | e); | ||
225 | |||
226 | throw e2; | ||
227 | } | ||
228 | |||
229 | Hashtable GridRespData = (Hashtable) GridResp.Value; | ||
230 | |||
231 | // Hashtable griddatahash = GridRespData; | ||
232 | |||
233 | // Process Response | ||
234 | if (GridRespData != null && GridRespData.ContainsKey("error")) | ||
235 | { | ||
236 | string errorstring = (string)GridRespData["error"]; | ||
237 | m_log.Error("Unable to connect to grid: " + errorstring); | ||
238 | return false; | ||
239 | } | ||
240 | |||
241 | return m_localBackend.DeregisterRegion(regionInfo); | ||
242 | } | ||
243 | |||
244 | public virtual Dictionary<string, string> GetGridSettings() | ||
245 | { | ||
246 | Dictionary<string, string> returnGridSettings = new Dictionary<string, string>(); | ||
247 | lock (m_queuedGridSettings) | ||
248 | { | ||
249 | foreach (string Dictkey in m_queuedGridSettings.Keys) | ||
250 | { | ||
251 | returnGridSettings.Add(Dictkey, m_queuedGridSettings[Dictkey]); | ||
252 | } | ||
253 | |||
254 | m_queuedGridSettings.Clear(); | ||
255 | } | ||
256 | |||
257 | return returnGridSettings; | ||
258 | } | ||
259 | |||
260 | // see IGridServices | ||
261 | public List<SimpleRegionInfo> RequestNeighbours(uint x, uint y) | ||
262 | { | ||
263 | Hashtable respData = MapBlockQuery((int) x - 1, (int) y - 1, (int) x + 1, (int) y + 1); | ||
264 | |||
265 | List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>(); | ||
266 | |||
267 | foreach (ArrayList neighboursList in respData.Values) | ||
268 | { | ||
269 | foreach (Hashtable neighbourData in neighboursList) | ||
270 | { | ||
271 | uint regX = Convert.ToUInt32(neighbourData["x"]); | ||
272 | uint regY = Convert.ToUInt32(neighbourData["y"]); | ||
273 | if ((x != regX) || (y != regY)) | ||
274 | { | ||
275 | string simIp = (string) neighbourData["sim_ip"]; | ||
276 | |||
277 | uint port = Convert.ToUInt32(neighbourData["sim_port"]); | ||
278 | // string externalUri = (string) neighbourData["sim_uri"]; | ||
279 | |||
280 | // string externalIpStr = String.Empty; | ||
281 | try | ||
282 | { | ||
283 | // externalIpStr = Util.GetHostFromDNS(simIp).ToString(); | ||
284 | Util.GetHostFromDNS(simIp).ToString(); | ||
285 | } | ||
286 | catch (SocketException e) | ||
287 | { | ||
288 | m_log.WarnFormat( | ||
289 | "[OGS1 GRID SERVICES]: RequestNeighbours(): Lookup of neighbour {0} failed! Not including in neighbours list. {1}", | ||
290 | simIp, e); | ||
291 | |||
292 | continue; | ||
293 | } | ||
294 | |||
295 | SimpleRegionInfo sri = new SimpleRegionInfo(regX, regY, simIp, port); | ||
296 | |||
297 | sri.RemotingPort = Convert.ToUInt32(neighbourData["remoting_port"]); | ||
298 | |||
299 | if (neighbourData.ContainsKey("http_port")) | ||
300 | { | ||
301 | sri.HttpPort = Convert.ToUInt32(neighbourData["http_port"]); | ||
302 | } | ||
303 | else | ||
304 | { | ||
305 | m_log.Error("[OGS1 GRID SERVICES]: Couldn't find httpPort, using default 9000; please upgrade your grid-server to r7621 or later"); | ||
306 | sri.HttpPort = 9000; // that's the default and will probably be wrong | ||
307 | } | ||
308 | |||
309 | sri.RegionID = new UUID((string) neighbourData["uuid"]); | ||
310 | |||
311 | neighbours.Add(sri); | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | return neighbours; | ||
317 | } | ||
318 | |||
319 | /// <summary> | ||
320 | /// Request information about a region. | ||
321 | /// </summary> | ||
322 | /// <param name="regionHandle"></param> | ||
323 | /// <returns> | ||
324 | /// null on a failure to contact or get a response from the grid server | ||
325 | /// FIXME: Might be nicer to return a proper exception here since we could inform the client more about the | ||
326 | /// nature of the faiulre. | ||
327 | /// </returns> | ||
328 | public RegionInfo RequestNeighbourInfo(UUID Region_UUID) | ||
329 | { | ||
330 | // don't ask the gridserver about regions on this instance... | ||
331 | foreach (RegionInfo info in m_regionsOnInstance) | ||
332 | { | ||
333 | if (info.RegionID == Region_UUID) return info; | ||
334 | } | ||
335 | |||
336 | // didn't find it so far, we have to go the long way | ||
337 | RegionInfo regionInfo; | ||
338 | Hashtable requestData = new Hashtable(); | ||
339 | requestData["region_UUID"] = Region_UUID.ToString(); | ||
340 | requestData["authkey"] = serversInfo.GridSendKey; | ||
341 | ArrayList SendParams = new ArrayList(); | ||
342 | SendParams.Add(requestData); | ||
343 | XmlRpcRequest gridReq = new XmlRpcRequest("simulator_data_request", SendParams); | ||
344 | XmlRpcResponse gridResp = null; | ||
345 | |||
346 | try | ||
347 | { | ||
348 | gridResp = gridReq.Send(serversInfo.GridURL, 3000); | ||
349 | } | ||
350 | catch (Exception e) | ||
351 | { | ||
352 | m_log.ErrorFormat( | ||
353 | "[OGS1 GRID SERVICES]: Communication with the grid server at {0} failed, {1}", | ||
354 | serversInfo.GridURL, e); | ||
355 | |||
356 | return null; | ||
357 | } | ||
358 | |||
359 | Hashtable responseData = (Hashtable)gridResp.Value; | ||
360 | |||
361 | if (responseData.ContainsKey("error")) | ||
362 | { | ||
363 | m_log.WarnFormat("[OGS1 GRID SERVICES]: Error received from grid server: {0}", responseData["error"]); | ||
364 | return null; | ||
365 | } | ||
366 | |||
367 | regionInfo = buildRegionInfo(responseData, String.Empty); | ||
368 | if ((m_useRemoteRegionCache) && (requestData.ContainsKey("regionHandle"))) | ||
369 | { | ||
370 | m_remoteRegionInfoCache.Add(Convert.ToUInt64((string) requestData["regionHandle"]), regionInfo); | ||
371 | } | ||
372 | |||
373 | return regionInfo; | ||
374 | } | ||
375 | |||
376 | /// <summary> | ||
377 | /// Request information about a region. | ||
378 | /// </summary> | ||
379 | /// <param name="regionHandle"></param> | ||
380 | /// <returns></returns> | ||
381 | public RegionInfo RequestNeighbourInfo(ulong regionHandle) | ||
382 | { | ||
383 | RegionInfo regionInfo = m_localBackend.RequestNeighbourInfo(regionHandle); | ||
384 | |||
385 | if (regionInfo != null) | ||
386 | { | ||
387 | return regionInfo; | ||
388 | } | ||
389 | |||
390 | if ((!m_useRemoteRegionCache) || (!m_remoteRegionInfoCache.TryGetValue(regionHandle, out regionInfo))) | ||
391 | { | ||
392 | try | ||
393 | { | ||
394 | Hashtable requestData = new Hashtable(); | ||
395 | requestData["region_handle"] = regionHandle.ToString(); | ||
396 | requestData["authkey"] = serversInfo.GridSendKey; | ||
397 | ArrayList SendParams = new ArrayList(); | ||
398 | SendParams.Add(requestData); | ||
399 | XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); | ||
400 | XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000); | ||
401 | |||
402 | Hashtable responseData = (Hashtable) GridResp.Value; | ||
403 | |||
404 | if (responseData.ContainsKey("error")) | ||
405 | { | ||
406 | m_log.Error("[OGS1 GRID SERVICES]: Error received from grid server: " + responseData["error"]); | ||
407 | return null; | ||
408 | } | ||
409 | |||
410 | uint regX = Convert.ToUInt32((string) responseData["region_locx"]); | ||
411 | uint regY = Convert.ToUInt32((string) responseData["region_locy"]); | ||
412 | string externalHostName = (string) responseData["sim_ip"]; | ||
413 | uint simPort = Convert.ToUInt32(responseData["sim_port"]); | ||
414 | string regionName = (string)responseData["region_name"]; | ||
415 | UUID regionID = new UUID((string)responseData["region_UUID"]); | ||
416 | uint remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); | ||
417 | |||
418 | uint httpPort = 9000; | ||
419 | if (responseData.ContainsKey("http_port")) | ||
420 | { | ||
421 | httpPort = Convert.ToUInt32((string)responseData["http_port"]); | ||
422 | } | ||
423 | |||
424 | // Ok, so this is definitively the wrong place to do this, way too hard coded, but it doesn't seem we GET this info? | ||
425 | |||
426 | string simURI = "http://" + externalHostName + ":" + simPort; | ||
427 | |||
428 | // string externalUri = (string) responseData["sim_uri"]; | ||
429 | |||
430 | //IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int) port); | ||
431 | regionInfo = RegionInfo.Create(regionID, regionName, regX, regY, externalHostName, httpPort, simPort, remotingPort, simURI); | ||
432 | |||
433 | if (m_useRemoteRegionCache) | ||
434 | { | ||
435 | lock (m_remoteRegionInfoCache) | ||
436 | { | ||
437 | if (!m_remoteRegionInfoCache.ContainsKey(regionHandle)) | ||
438 | { | ||
439 | m_remoteRegionInfoCache.Add(regionHandle, regionInfo); | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | catch (Exception e) | ||
445 | { | ||
446 | m_log.Error("[OGS1 GRID SERVICES]: " + | ||
447 | "Region lookup failed for: " + regionHandle.ToString() + | ||
448 | " - Is the GridServer down?" + e.ToString()); | ||
449 | return null; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | return regionInfo; | ||
454 | } | ||
455 | |||
456 | /// <summary> | ||
457 | /// Get information about a neighbouring region | ||
458 | /// </summary> | ||
459 | /// <param name="regionHandle"></param> | ||
460 | /// <returns></returns> | ||
461 | public RegionInfo RequestNeighbourInfo(string name) | ||
462 | { | ||
463 | // Not implemented yet | ||
464 | return null; | ||
465 | } | ||
466 | |||
467 | /// <summary> | ||
468 | /// Get information about a neighbouring region | ||
469 | /// </summary> | ||
470 | /// <param name="regionHandle"></param> | ||
471 | /// <returns></returns> | ||
472 | public RegionInfo RequestNeighbourInfo(string host, uint port) | ||
473 | { | ||
474 | // Not implemented yet | ||
475 | return null; | ||
476 | } | ||
477 | |||
478 | public RegionInfo RequestClosestRegion(string regionName) | ||
479 | { | ||
480 | if (m_useRemoteRegionCache) | ||
481 | { | ||
482 | foreach (RegionInfo ri in m_remoteRegionInfoCache.Values) | ||
483 | { | ||
484 | if (ri.RegionName == regionName) | ||
485 | return ri; | ||
486 | } | ||
487 | } | ||
488 | |||
489 | RegionInfo regionInfo = null; | ||
490 | try | ||
491 | { | ||
492 | Hashtable requestData = new Hashtable(); | ||
493 | requestData["region_name_search"] = regionName; | ||
494 | requestData["authkey"] = serversInfo.GridSendKey; | ||
495 | ArrayList SendParams = new ArrayList(); | ||
496 | SendParams.Add(requestData); | ||
497 | XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); | ||
498 | XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000); | ||
499 | |||
500 | Hashtable responseData = (Hashtable) GridResp.Value; | ||
501 | |||
502 | if (responseData.ContainsKey("error")) | ||
503 | { | ||
504 | m_log.ErrorFormat("[OGS1 GRID SERVICES]: Error received from grid server: ", responseData["error"]); | ||
505 | return null; | ||
506 | } | ||
507 | |||
508 | regionInfo = buildRegionInfo(responseData, ""); | ||
509 | |||
510 | if ((m_useRemoteRegionCache) && (!m_remoteRegionInfoCache.ContainsKey(regionInfo.RegionHandle))) | ||
511 | m_remoteRegionInfoCache.Add(regionInfo.RegionHandle, regionInfo); | ||
512 | } | ||
513 | catch | ||
514 | { | ||
515 | m_log.Error("[OGS1 GRID SERVICES]: " + | ||
516 | "Region lookup failed for: " + regionName + | ||
517 | " - Is the GridServer down?"); | ||
518 | } | ||
519 | |||
520 | return regionInfo; | ||
521 | } | ||
522 | |||
523 | /// <summary> | ||
524 | /// | ||
525 | /// </summary> | ||
526 | /// <param name="minX"></param> | ||
527 | /// <param name="minY"></param> | ||
528 | /// <param name="maxX"></param> | ||
529 | /// <param name="maxY"></param> | ||
530 | /// <returns></returns> | ||
531 | public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) | ||
532 | { | ||
533 | int temp = 0; | ||
534 | |||
535 | if (minX > maxX) | ||
536 | { | ||
537 | temp = minX; | ||
538 | minX = maxX; | ||
539 | maxX = temp; | ||
540 | } | ||
541 | if (minY > maxY) | ||
542 | { | ||
543 | temp = minY; | ||
544 | minY = maxY; | ||
545 | maxY = temp; | ||
546 | } | ||
547 | |||
548 | Hashtable respData = MapBlockQuery(minX, minY, maxX, maxY); | ||
549 | |||
550 | List<MapBlockData> neighbours = new List<MapBlockData>(); | ||
551 | |||
552 | foreach (ArrayList a in respData.Values) | ||
553 | { | ||
554 | foreach (Hashtable n in a) | ||
555 | { | ||
556 | MapBlockData neighbour = new MapBlockData(); | ||
557 | |||
558 | neighbour.X = Convert.ToUInt16(n["x"]); | ||
559 | neighbour.Y = Convert.ToUInt16(n["y"]); | ||
560 | |||
561 | neighbour.Name = (string) n["name"]; | ||
562 | neighbour.Access = Convert.ToByte(n["access"]); | ||
563 | neighbour.RegionFlags = Convert.ToUInt32(n["region-flags"]); | ||
564 | neighbour.WaterHeight = Convert.ToByte(n["water-height"]); | ||
565 | neighbour.MapImageId = new UUID((string) n["map-image-id"]); | ||
566 | |||
567 | neighbours.Add(neighbour); | ||
568 | } | ||
569 | } | ||
570 | |||
571 | return neighbours; | ||
572 | } | ||
573 | |||
574 | /// <summary> | ||
575 | /// Performs a XML-RPC query against the grid server returning mapblock information in the specified coordinates | ||
576 | /// </summary> | ||
577 | /// <remarks>REDUNDANT - OGS1 is to be phased out in favour of OGS2</remarks> | ||
578 | /// <param name="minX">Minimum X value</param> | ||
579 | /// <param name="minY">Minimum Y value</param> | ||
580 | /// <param name="maxX">Maximum X value</param> | ||
581 | /// <param name="maxY">Maximum Y value</param> | ||
582 | /// <returns>Hashtable of hashtables containing map data elements</returns> | ||
583 | private Hashtable MapBlockQuery(int minX, int minY, int maxX, int maxY) | ||
584 | { | ||
585 | Hashtable param = new Hashtable(); | ||
586 | param["xmin"] = minX; | ||
587 | param["ymin"] = minY; | ||
588 | param["xmax"] = maxX; | ||
589 | param["ymax"] = maxY; | ||
590 | IList parameters = new ArrayList(); | ||
591 | parameters.Add(param); | ||
592 | |||
593 | try | ||
594 | { | ||
595 | XmlRpcRequest req = new XmlRpcRequest("map_block", parameters); | ||
596 | XmlRpcResponse resp = req.Send(serversInfo.GridURL, 10000); | ||
597 | Hashtable respData = (Hashtable) resp.Value; | ||
598 | return respData; | ||
599 | } | ||
600 | catch (Exception e) | ||
601 | { | ||
602 | m_log.Error("MapBlockQuery XMLRPC failure: " + e); | ||
603 | return new Hashtable(); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | /// <summary> | ||
608 | /// A ping / version check | ||
609 | /// </summary> | ||
610 | /// <param name="request"></param> | ||
611 | /// <returns></returns> | ||
612 | public XmlRpcResponse PingCheckReply(XmlRpcRequest request, IPEndPoint remoteClient) | ||
613 | { | ||
614 | XmlRpcResponse response = new XmlRpcResponse(); | ||
615 | |||
616 | Hashtable respData = new Hashtable(); | ||
617 | respData["online"] = "true"; | ||
618 | |||
619 | m_localBackend.PingCheckReply(respData); | ||
620 | |||
621 | response.Value = respData; | ||
622 | |||
623 | return response; | ||
624 | } | ||
625 | |||
626 | /// <summary> | ||
627 | /// Received from the user server when a user starts logging in. This call allows | ||
628 | /// the region to prepare for direct communication from the client. Sends back an empty | ||
629 | /// xmlrpc response on completion. | ||
630 | /// </summary> | ||
631 | /// <param name="request"></param> | ||
632 | /// <returns></returns> | ||
633 | public XmlRpcResponse ExpectUser(XmlRpcRequest request) | ||
634 | { | ||
635 | Hashtable requestData = (Hashtable) request.Params[0]; | ||
636 | AgentCircuitData agentData = new AgentCircuitData(); | ||
637 | agentData.SessionID = new UUID((string) requestData["session_id"]); | ||
638 | agentData.SecureSessionID = new UUID((string) requestData["secure_session_id"]); | ||
639 | agentData.firstname = (string) requestData["firstname"]; | ||
640 | agentData.lastname = (string) requestData["lastname"]; | ||
641 | agentData.AgentID = new UUID((string) requestData["agent_id"]); | ||
642 | agentData.circuitcode = Convert.ToUInt32(requestData["circuit_code"]); | ||
643 | agentData.CapsPath = (string)requestData["caps_path"]; | ||
644 | ulong regionHandle = Convert.ToUInt64((string) requestData["regionhandle"]); | ||
645 | |||
646 | // Appearance | ||
647 | if (requestData["appearance"] != null) | ||
648 | agentData.Appearance = new AvatarAppearance((Hashtable)requestData["appearance"]); | ||
649 | |||
650 | m_log.DebugFormat( | ||
651 | "[CLIENT]: Told by user service to prepare for a connection from {0} {1} {2}, circuit {3}", | ||
652 | agentData.firstname, agentData.lastname, agentData.AgentID, agentData.circuitcode); | ||
653 | |||
654 | if (requestData.ContainsKey("child_agent") && requestData["child_agent"].Equals("1")) | ||
655 | { | ||
656 | //m_log.Debug("[CLIENT]: Child agent detected"); | ||
657 | agentData.child = true; | ||
658 | } | ||
659 | else | ||
660 | { | ||
661 | //m_log.Debug("[CLIENT]: Main agent detected"); | ||
662 | agentData.startpos = | ||
663 | new Vector3((float)Convert.ToDecimal((string)requestData["startpos_x"]), | ||
664 | (float)Convert.ToDecimal((string)requestData["startpos_y"]), | ||
665 | (float)Convert.ToDecimal((string)requestData["startpos_z"])); | ||
666 | agentData.child = false; | ||
667 | } | ||
668 | |||
669 | XmlRpcResponse resp = new XmlRpcResponse(); | ||
670 | |||
671 | if (!RegionLoginsEnabled) | ||
672 | { | ||
673 | m_log.InfoFormat( | ||
674 | "[CLIENT]: Denying access for user {0} {1} because region login is currently disabled", | ||
675 | agentData.firstname, agentData.lastname); | ||
676 | |||
677 | Hashtable respdata = new Hashtable(); | ||
678 | respdata["success"] = "FALSE"; | ||
679 | respdata["reason"] = "region login currently disabled"; | ||
680 | resp.Value = respdata; | ||
681 | } | ||
682 | else | ||
683 | { | ||
684 | RegionInfo[] regions = m_regionsOnInstance.ToArray(); | ||
685 | bool banned = false; | ||
686 | |||
687 | for (int i = 0; i < regions.Length; i++) | ||
688 | { | ||
689 | if (regions[i] != null) | ||
690 | { | ||
691 | if (regions[i].RegionHandle == regionHandle) | ||
692 | { | ||
693 | if (regions[i].EstateSettings.IsBanned(agentData.AgentID)) | ||
694 | { | ||
695 | banned = true; | ||
696 | break; | ||
697 | } | ||
698 | } | ||
699 | } | ||
700 | } | ||
701 | |||
702 | if (banned) | ||
703 | { | ||
704 | m_log.InfoFormat( | ||
705 | "[CLIENT]: Denying access for user {0} {1} because user is banned", | ||
706 | agentData.firstname, agentData.lastname); | ||
707 | |||
708 | Hashtable respdata = new Hashtable(); | ||
709 | respdata["success"] = "FALSE"; | ||
710 | respdata["reason"] = "banned"; | ||
711 | resp.Value = respdata; | ||
712 | } | ||
713 | else | ||
714 | { | ||
715 | m_localBackend.TriggerExpectUser(regionHandle, agentData); | ||
716 | Hashtable respdata = new Hashtable(); | ||
717 | respdata["success"] = "TRUE"; | ||
718 | resp.Value = respdata; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | return resp; | ||
723 | } | ||
724 | |||
725 | // Grid Request Processing | ||
726 | /// <summary> | ||
727 | /// Ooops, our Agent must be dead if we're getting this request! | ||
728 | /// </summary> | ||
729 | /// <param name="request"></param> | ||
730 | /// <returns></returns> | ||
731 | public XmlRpcResponse LogOffUser(XmlRpcRequest request) | ||
732 | { | ||
733 | m_log.Debug("[CONNECTION DEBUGGING]: LogOff User Called"); | ||
734 | |||
735 | Hashtable requestData = (Hashtable)request.Params[0]; | ||
736 | string message = (string)requestData["message"]; | ||
737 | UUID agentID = UUID.Zero; | ||
738 | UUID RegionSecret = UUID.Zero; | ||
739 | UUID.TryParse((string)requestData["agent_id"], out agentID); | ||
740 | UUID.TryParse((string)requestData["region_secret"], out RegionSecret); | ||
741 | |||
742 | ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); | ||
743 | |||
744 | m_localBackend.TriggerLogOffUser(regionHandle, agentID, RegionSecret,message); | ||
745 | |||
746 | return new XmlRpcResponse(); | ||
747 | } | ||
748 | |||
749 | public void NoteDeadRegion(ulong regionhandle) | ||
750 | { | ||
751 | lock (m_deadRegionCache) | ||
752 | { | ||
753 | if (m_deadRegionCache.ContainsKey(regionhandle)) | ||
754 | { | ||
755 | m_deadRegionCache[regionhandle] = m_deadRegionCache[regionhandle] + 1; | ||
756 | } | ||
757 | else | ||
758 | { | ||
759 | m_deadRegionCache.Add(regionhandle, 1); | ||
760 | } | ||
761 | } | ||
762 | } | ||
763 | |||
764 | public LandData RequestLandData (ulong regionHandle, uint x, uint y) | ||
765 | { | ||
766 | m_log.DebugFormat("[OGS1 GRID SERVICES] requests land data in {0}, at {1}, {2}", | ||
767 | regionHandle, x, y); | ||
768 | LandData landData = m_localBackend.RequestLandData(regionHandle, x, y); | ||
769 | if (landData == null) | ||
770 | { | ||
771 | Hashtable hash = new Hashtable(); | ||
772 | hash["region_handle"] = regionHandle.ToString(); | ||
773 | hash["x"] = x.ToString(); | ||
774 | hash["y"] = y.ToString(); | ||
775 | |||
776 | IList paramList = new ArrayList(); | ||
777 | paramList.Add(hash); | ||
778 | |||
779 | try | ||
780 | { | ||
781 | // this might be cached, as we probably requested it just a moment ago... | ||
782 | RegionInfo info = RequestNeighbourInfo(regionHandle); | ||
783 | if (info != null) // just to be sure | ||
784 | { | ||
785 | XmlRpcRequest request = new XmlRpcRequest("land_data", paramList); | ||
786 | string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/"; | ||
787 | XmlRpcResponse response = request.Send(uri, 10000); | ||
788 | if (response.IsFault) | ||
789 | { | ||
790 | m_log.ErrorFormat("[OGS1 GRID SERVICES] remote call returned an error: {0}", response.FaultString); | ||
791 | } | ||
792 | else | ||
793 | { | ||
794 | hash = (Hashtable)response.Value; | ||
795 | try | ||
796 | { | ||
797 | landData = new LandData(); | ||
798 | landData.AABBMax = Vector3.Parse((string)hash["AABBMax"]); | ||
799 | landData.AABBMin = Vector3.Parse((string)hash["AABBMin"]); | ||
800 | landData.Area = Convert.ToInt32(hash["Area"]); | ||
801 | landData.AuctionID = Convert.ToUInt32(hash["AuctionID"]); | ||
802 | landData.Description = (string)hash["Description"]; | ||
803 | landData.Flags = Convert.ToUInt32(hash["Flags"]); | ||
804 | landData.GlobalID = new UUID((string)hash["GlobalID"]); | ||
805 | landData.Name = (string)hash["Name"]; | ||
806 | landData.OwnerID = new UUID((string)hash["OwnerID"]); | ||
807 | landData.SalePrice = Convert.ToInt32(hash["SalePrice"]); | ||
808 | landData.SnapshotID = new UUID((string)hash["SnapshotID"]); | ||
809 | landData.UserLocation = Vector3.Parse((string)hash["UserLocation"]); | ||
810 | m_log.DebugFormat("[OGS1 GRID SERVICES] Got land data for parcel {0}", landData.Name); | ||
811 | } | ||
812 | catch (Exception e) | ||
813 | { | ||
814 | m_log.Error("[OGS1 GRID SERVICES] Got exception while parsing land-data:", e); | ||
815 | } | ||
816 | } | ||
817 | } | ||
818 | else m_log.WarnFormat("[OGS1 GRID SERVICES] Couldn't find region with handle {0}", regionHandle); | ||
819 | } | ||
820 | catch (Exception e) | ||
821 | { | ||
822 | m_log.ErrorFormat("[OGS1 GRID SERVICES] Couldn't contact region {0}: {1}", regionHandle, e); | ||
823 | } | ||
824 | } | ||
825 | return landData; | ||
826 | } | ||
827 | |||
828 | // Grid Request Processing | ||
829 | /// <summary> | ||
830 | /// Someone asked us about parcel-information | ||
831 | /// </summary> | ||
832 | /// <param name="request"></param> | ||
833 | /// <returns></returns> | ||
834 | public XmlRpcResponse LandData(XmlRpcRequest request, IPEndPoint remoteClient) | ||
835 | { | ||
836 | Hashtable requestData = (Hashtable)request.Params[0]; | ||
837 | ulong regionHandle = Convert.ToUInt64(requestData["region_handle"]); | ||
838 | uint x = Convert.ToUInt32(requestData["x"]); | ||
839 | uint y = Convert.ToUInt32(requestData["y"]); | ||
840 | m_log.DebugFormat("[OGS1 GRID SERVICES]: Got XML reqeuest for land data at {0}, {1} in region {2}", x, y, regionHandle); | ||
841 | |||
842 | LandData landData = m_localBackend.RequestLandData(regionHandle, x, y); | ||
843 | Hashtable hash = new Hashtable(); | ||
844 | if (landData != null) | ||
845 | { | ||
846 | // for now, only push out the data we need for answering a ParcelInfoReqeust | ||
847 | hash["AABBMax"] = landData.AABBMax.ToString(); | ||
848 | hash["AABBMin"] = landData.AABBMin.ToString(); | ||
849 | hash["Area"] = landData.Area.ToString(); | ||
850 | hash["AuctionID"] = landData.AuctionID.ToString(); | ||
851 | hash["Description"] = landData.Description; | ||
852 | hash["Flags"] = landData.Flags.ToString(); | ||
853 | hash["GlobalID"] = landData.GlobalID.ToString(); | ||
854 | hash["Name"] = landData.Name; | ||
855 | hash["OwnerID"] = landData.OwnerID.ToString(); | ||
856 | hash["SalePrice"] = landData.SalePrice.ToString(); | ||
857 | hash["SnapshotID"] = landData.SnapshotID.ToString(); | ||
858 | hash["UserLocation"] = landData.UserLocation.ToString(); | ||
859 | } | ||
860 | |||
861 | XmlRpcResponse response = new XmlRpcResponse(); | ||
862 | response.Value = hash; | ||
863 | return response; | ||
864 | } | ||
865 | |||
866 | public List<RegionInfo> RequestNamedRegions (string name, int maxNumber) | ||
867 | { | ||
868 | // no asking of the local backend first, here, as we have to ask the gridserver anyway. | ||
869 | Hashtable hash = new Hashtable(); | ||
870 | hash["name"] = name; | ||
871 | hash["maxNumber"] = maxNumber.ToString(); | ||
872 | |||
873 | IList paramList = new ArrayList(); | ||
874 | paramList.Add(hash); | ||
875 | |||
876 | Hashtable result = XmlRpcSearchForRegionByName(paramList); | ||
877 | if (result == null) return null; | ||
878 | |||
879 | uint numberFound = Convert.ToUInt32(result["numFound"]); | ||
880 | List<RegionInfo> infos = new List<RegionInfo>(); | ||
881 | for (int i = 0; i < numberFound; ++i) | ||
882 | { | ||
883 | string prefix = "region" + i + "."; | ||
884 | RegionInfo info = buildRegionInfo(result, prefix); | ||
885 | infos.Add(info); | ||
886 | } | ||
887 | return infos; | ||
888 | } | ||
889 | |||
890 | private RegionInfo buildRegionInfo(Hashtable responseData, string prefix) | ||
891 | { | ||
892 | uint regX = Convert.ToUInt32((string) responseData[prefix + "region_locx"]); | ||
893 | uint regY = Convert.ToUInt32((string) responseData[prefix + "region_locy"]); | ||
894 | string internalIpStr = (string) responseData[prefix + "sim_ip"]; | ||
895 | uint port = Convert.ToUInt32(responseData[prefix + "sim_port"]); | ||
896 | |||
897 | IPEndPoint neighbourInternalEndPoint = new IPEndPoint(Util.GetHostFromDNS(internalIpStr), (int) port); | ||
898 | |||
899 | RegionInfo regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr); | ||
900 | regionInfo.RemotingPort = Convert.ToUInt32((string) responseData[prefix + "remoting_port"]); | ||
901 | regionInfo.RemotingAddress = internalIpStr; | ||
902 | |||
903 | if (responseData.ContainsKey(prefix + "http_port")) | ||
904 | { | ||
905 | regionInfo.HttpPort = Convert.ToUInt32((string) responseData[prefix + "http_port"]); | ||
906 | } | ||
907 | |||
908 | regionInfo.RegionID = new UUID((string) responseData[prefix + "region_UUID"]); | ||
909 | regionInfo.RegionName = (string) responseData[prefix + "region_name"]; | ||
910 | |||
911 | regionInfo.RegionSettings.TerrainImageID = new UUID((string) responseData[prefix + "map_UUID"]); | ||
912 | return regionInfo; | ||
913 | } | ||
914 | |||
915 | private Hashtable XmlRpcSearchForRegionByName(IList parameters) | ||
916 | { | ||
917 | try | ||
918 | { | ||
919 | XmlRpcRequest request = new XmlRpcRequest("search_for_region_by_name", parameters); | ||
920 | XmlRpcResponse resp = request.Send(serversInfo.GridURL, 10000); | ||
921 | Hashtable respData = (Hashtable) resp.Value; | ||
922 | if (respData != null && respData.Contains("faultCode")) | ||
923 | { | ||
924 | m_log.WarnFormat("[OGS1 GRID SERVICES]: Got an error while contacting GridServer: {0}", respData["faultString"]); | ||
925 | return null; | ||
926 | } | ||
927 | |||
928 | return respData; | ||
929 | } | ||
930 | catch (Exception e) | ||
931 | { | ||
932 | m_log.Error("[OGS1 GRID SERVICES]: MapBlockQuery XMLRPC failure: ", e); | ||
933 | return null; | ||
934 | } | ||
935 | } | ||
936 | } | ||
937 | } | ||