aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs')
-rw-r--r--OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs900
1 files changed, 0 insertions, 900 deletions
diff --git a/OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs b/OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs
deleted file mode 100644
index 854e66a..0000000
--- a/OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs
+++ /dev/null
@@ -1,900 +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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Net;
33using System.Reflection;
34using System.Xml;
35using log4net;
36using Nwc.XmlRpc;
37using OpenMetaverse;
38using OpenSim.Data;
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using OpenSim.Grid.Framework;
44
45namespace OpenSim.Grid.GridServer.Modules
46{
47 public class GridXmlRpcModule
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private IRegionProfileService m_gridDBService;
52 private IGridServiceCore m_gridCore;
53
54 protected GridConfig m_config;
55
56 protected IMessagingServerDiscovery m_messagingServerMapper;
57 /// <value>
58 /// Used to notify old regions as to which OpenSim version to upgrade to
59 /// </value>
60 private string m_opensimVersion;
61
62 protected BaseHttpServer m_httpServer;
63
64 /// <summary>
65 /// Constructor
66 /// </summary>
67 /// <param name="opensimVersion">
68 /// Used to notify old regions as to which OpenSim version to upgrade to
69 /// </param>
70 public GridXmlRpcModule()
71 {
72 }
73
74 public void Initialise(string opensimVersion, IRegionProfileService gridDBService, IGridServiceCore gridCore, GridConfig config)
75 {
76 m_opensimVersion = opensimVersion;
77 m_gridDBService = gridDBService;
78 m_gridCore = gridCore;
79 m_config = config;
80 RegisterHandlers();
81 }
82
83 public void PostInitialise()
84 {
85 IMessagingServerDiscovery messagingModule;
86 if (m_gridCore.TryGet<IMessagingServerDiscovery>(out messagingModule))
87 {
88 m_messagingServerMapper = messagingModule;
89 }
90 }
91
92 public void RegisterHandlers()
93 {
94 //have these in separate method as some servers restart the http server and reregister all the handlers.
95 m_httpServer = m_gridCore.GetHttpServer();
96
97 m_httpServer.AddXmlRPCHandler("simulator_login", XmlRpcSimulatorLoginMethod);
98 m_httpServer.AddXmlRPCHandler("simulator_data_request", XmlRpcSimulatorDataRequestMethod);
99 m_httpServer.AddXmlRPCHandler("simulator_after_region_moved", XmlRpcDeleteRegionMethod);
100 m_httpServer.AddXmlRPCHandler("map_block", XmlRpcMapBlockMethod);
101 m_httpServer.AddXmlRPCHandler("search_for_region_by_name", XmlRpcSearchForRegionMethod);
102 }
103
104 /// <summary>
105 /// Returns a XML String containing a list of the neighbouring regions
106 /// </summary>
107 /// <param name="reqhandle">The regionhandle for the center sim</param>
108 /// <returns>An XML string containing neighbour entities</returns>
109 public string GetXMLNeighbours(ulong reqhandle)
110 {
111 string response = String.Empty;
112 RegionProfileData central_region = m_gridDBService.GetRegion(reqhandle);
113 RegionProfileData neighbour;
114 for (int x = -1; x < 2; x++)
115 {
116 for (int y = -1; y < 2; y++)
117 {
118 if (
119 m_gridDBService.GetRegion(
120 Util.UIntsToLong((uint)((central_region.regionLocX + x) * Constants.RegionSize),
121 (uint)(central_region.regionLocY + y) * Constants.RegionSize)) != null)
122 {
123 neighbour =
124 m_gridDBService.GetRegion(
125 Util.UIntsToLong((uint)((central_region.regionLocX + x) * Constants.RegionSize),
126 (uint)(central_region.regionLocY + y) * Constants.RegionSize));
127
128 response += "<neighbour>";
129 response += "<sim_ip>" + neighbour.serverIP + "</sim_ip>";
130 response += "<sim_port>" + neighbour.serverPort.ToString() + "</sim_port>";
131 response += "<locx>" + neighbour.regionLocX.ToString() + "</locx>";
132 response += "<locy>" + neighbour.regionLocY.ToString() + "</locy>";
133 response += "<regionhandle>" + neighbour.regionHandle.ToString() + "</regionhandle>";
134 response += "</neighbour>";
135 }
136 }
137 }
138 return response;
139 }
140
141 /// <summary>
142 /// Checks that it's valid to replace the existing region data with new data
143 ///
144 /// Currently, this means ensure that the keys passed in by the new region
145 /// match those in the original region. (XXX Is this correct? Shouldn't we simply check
146 /// against the keys in the current configuration?)
147 /// </summary>
148 /// <param name="sim"></param>
149 /// <returns></returns>
150 protected virtual void ValidateOverwriteKeys(RegionProfileData sim, RegionProfileData existingSim)
151 {
152 if (!(existingSim.regionRecvKey == sim.regionRecvKey && existingSim.regionSendKey == sim.regionSendKey))
153 {
154 throw new LoginException(
155 String.Format(
156 "Authentication failed when trying to login existing region {0} at location {1} {2} currently occupied by {3}"
157 + " with the region's send key {4} (expected {5}) and the region's receive key {6} (expected {7})",
158 sim.regionName, sim.regionLocX, sim.regionLocY, existingSim.regionName,
159 sim.regionSendKey, existingSim.regionSendKey, sim.regionRecvKey, existingSim.regionRecvKey),
160 "The keys required to login your region did not match the grid server keys. Please check your grid send and receive keys.");
161 }
162 }
163
164 /// <summary>
165 /// Checks that the new region data is valid.
166 ///
167 /// Currently, this means checking that the keys passed in by the new region
168 /// match those in the grid server's configuration.
169 /// </summary>
170 ///
171 /// <param name="sim"></param>
172 /// <exception cref="LoginException">Thrown if region login failed</exception>
173 protected virtual void ValidateNewRegionKeys(RegionProfileData sim)
174 {
175 if (!(sim.regionRecvKey == m_config.SimSendKey && sim.regionSendKey == m_config.SimRecvKey))
176 {
177 throw new LoginException(
178 String.Format(
179 "Authentication failed when trying to login new region {0} at location {1} {2}"
180 + " with the region's send key {3} (expected {4}) and the region's receive key {5} (expected {6})",
181 sim.regionName, sim.regionLocX, sim.regionLocY,
182 sim.regionSendKey, m_config.SimRecvKey, sim.regionRecvKey, m_config.SimSendKey),
183 "The keys required to login your region did not match your existing region keys. Please check your grid send and receive keys.");
184 }
185 }
186
187 /// <summary>
188 /// Check that a region's http uri is externally contactable.
189 /// </summary>
190 /// <param name="sim"></param>
191 /// <exception cref="LoginException">Thrown if the region is not contactable</exception>
192 protected virtual void ValidateRegionContactable(RegionProfileData sim)
193 {
194 string regionStatusUrl = String.Format("{0}{1}", sim.httpServerURI, "simstatus/");
195 string regionStatusResponse;
196
197 RestClient rc = new RestClient(regionStatusUrl);
198 rc.RequestMethod = "GET";
199
200 m_log.DebugFormat("[LOGIN]: Contacting {0} for status of region {1}", regionStatusUrl, sim.regionName);
201
202 try
203 {
204 Stream rs = rc.Request();
205 StreamReader sr = new StreamReader(rs);
206 regionStatusResponse = sr.ReadToEnd();
207 sr.Close();
208 }
209 catch (Exception e)
210 {
211 throw new LoginException(
212 String.Format("Region status request to {0} failed", regionStatusUrl),
213 String.Format(
214 "The grid service could not contact the http url {0} at your region. Please make sure this url is reachable by the grid service",
215 regionStatusUrl),
216 e);
217 }
218
219 if (!regionStatusResponse.Equals("OK"))
220 {
221 throw new LoginException(
222 String.Format(
223 "Region {0} at {1} returned status response {2} rather than {3}",
224 sim.regionName, regionStatusUrl, regionStatusResponse, "OK"),
225 String.Format(
226 "When the grid service asked for the status of your region, it received the response {0} rather than {1}. Please check your status",
227 regionStatusResponse, "OK"));
228 }
229 }
230
231 /// <summary>
232 /// Construct an XMLRPC error response
233 /// </summary>
234 /// <param name="error"></param>
235 /// <returns></returns>
236 public static XmlRpcResponse ErrorResponse(string error)
237 {
238 XmlRpcResponse errorResponse = new XmlRpcResponse();
239 Hashtable errorResponseData = new Hashtable();
240 errorResponse.Value = errorResponseData;
241 errorResponseData["error"] = error;
242 return errorResponse;
243 }
244
245 /// <summary>
246 /// Performed when a region connects to the grid server initially.
247 /// </summary>
248 /// <param name="request">The XML RPC Request</param>
249 /// <returns>Startup parameters</returns>
250 public XmlRpcResponse XmlRpcSimulatorLoginMethod(XmlRpcRequest request, IPEndPoint remoteClient)
251 {
252 RegionProfileData sim;
253 RegionProfileData existingSim;
254
255 Hashtable requestData = (Hashtable)request.Params[0];
256 UUID uuid;
257
258 if (!requestData.ContainsKey("UUID") || !UUID.TryParse((string)requestData["UUID"], out uuid))
259 {
260 m_log.Debug("[LOGIN PRELUDE]: Region connected without a UUID, sending back error response.");
261 return ErrorResponse("No UUID passed to grid server - unable to connect you");
262 }
263
264 try
265 {
266 sim = RegionFromRequest(requestData);
267 }
268 catch (FormatException e)
269 {
270 m_log.Debug("[LOGIN PRELUDE]: Invalid login parameters, sending back error response.");
271 return ErrorResponse("Wrong format in login parameters. Please verify parameters." + e.ToString());
272 }
273
274 m_log.InfoFormat("[LOGIN BEGIN]: Received login request from simulator: {0}", sim.regionName);
275
276 if (!m_config.AllowRegionRegistration)
277 {
278 m_log.DebugFormat(
279 "[LOGIN END]: Disabled region registration blocked login request from simulator: {0}",
280 sim.regionName);
281
282 return ErrorResponse("This grid is currently not accepting region registrations.");
283 }
284
285 int majorInterfaceVersion = 0;
286 if (requestData.ContainsKey("major_interface_version"))
287 int.TryParse((string)requestData["major_interface_version"], out majorInterfaceVersion);
288
289 if (majorInterfaceVersion != VersionInfo.MajorInterfaceVersion)
290 {
291 return ErrorResponse(
292 String.Format(
293 "Your region service implements OGS1 interface version {0}"
294 + " but this grid requires that the region implement OGS1 interface version {1} to connect."
295 + " Try changing to OpenSimulator {2}",
296 majorInterfaceVersion, VersionInfo.MajorInterfaceVersion, m_opensimVersion));
297 }
298
299 existingSim = m_gridDBService.GetRegion(sim.regionHandle);
300
301 if (existingSim == null || existingSim.UUID == sim.UUID || sim.UUID != sim.originUUID)
302 {
303 try
304 {
305 if (existingSim == null)
306 {
307 ValidateNewRegionKeys(sim);
308 }
309 else
310 {
311 ValidateOverwriteKeys(sim, existingSim);
312 }
313
314 ValidateRegionContactable(sim);
315 }
316 catch (LoginException e)
317 {
318 string logMsg = e.Message;
319 if (e.InnerException != null)
320 logMsg += ", " + e.InnerException.Message;
321
322 m_log.WarnFormat("[LOGIN END]: {0}", logMsg);
323
324 return e.XmlRpcErrorResponse;
325 }
326
327 DataResponse insertResponse = m_gridDBService.AddUpdateRegion(sim, existingSim);
328
329 switch (insertResponse)
330 {
331 case DataResponse.RESPONSE_OK:
332 m_log.Info("[LOGIN END]: " + (existingSim == null ? "New" : "Existing") + " sim login successful: " + sim.regionName);
333 break;
334 case DataResponse.RESPONSE_ERROR:
335 m_log.Warn("[LOGIN END]: Sim login failed (Error): " + sim.regionName);
336 break;
337 case DataResponse.RESPONSE_INVALIDCREDENTIALS:
338 m_log.Warn("[LOGIN END]: " +
339 "Sim login failed (Invalid Credentials): " + sim.regionName);
340 break;
341 case DataResponse.RESPONSE_AUTHREQUIRED:
342 m_log.Warn("[LOGIN END]: " +
343 "Sim login failed (Authentication Required): " +
344 sim.regionName);
345 break;
346 }
347
348 XmlRpcResponse response = CreateLoginResponse(sim);
349
350 return response;
351 }
352 else
353 {
354 m_log.Warn("[LOGIN END]: Failed to login region " + sim.regionName + " at location " + sim.regionLocX + " " + sim.regionLocY + " currently occupied by " + existingSim.regionName);
355 return ErrorResponse("Another region already exists at that location. Please try another.");
356 }
357 }
358
359 /// <summary>
360 /// Construct a successful response to a simulator's login attempt.
361 /// </summary>
362 /// <param name="sim"></param>
363 /// <returns></returns>
364 private XmlRpcResponse CreateLoginResponse(RegionProfileData sim)
365 {
366 XmlRpcResponse response = new XmlRpcResponse();
367 Hashtable responseData = new Hashtable();
368 response.Value = responseData;
369
370 ArrayList SimNeighboursData = GetSimNeighboursData(sim);
371
372 responseData["UUID"] = sim.UUID.ToString();
373 responseData["region_locx"] = sim.regionLocX.ToString();
374 responseData["region_locy"] = sim.regionLocY.ToString();
375 responseData["regionname"] = sim.regionName;
376 responseData["estate_id"] = "1";
377 responseData["neighbours"] = SimNeighboursData;
378
379 responseData["sim_ip"] = sim.serverIP;
380 responseData["sim_port"] = sim.serverPort.ToString();
381 responseData["asset_url"] = sim.regionAssetURI;
382 responseData["asset_sendkey"] = sim.regionAssetSendKey;
383 responseData["asset_recvkey"] = sim.regionAssetRecvKey;
384 responseData["user_url"] = sim.regionUserURI;
385 responseData["user_sendkey"] = sim.regionUserSendKey;
386 responseData["user_recvkey"] = sim.regionUserRecvKey;
387 responseData["authkey"] = sim.regionSecret;
388
389 // New! If set, use as URL to local sim storage (ie http://remotehost/region.Yap)
390 responseData["data_uri"] = sim.regionDataURI;
391
392 responseData["allow_forceful_banlines"] = m_config.AllowForcefulBanlines;
393
394 // Instead of sending a multitude of message servers to the registering sim
395 // we should probably be sending a single one and parhaps it's backup
396 // that has responsibility over routing it's messages.
397
398 // The Sim won't be contacting us again about any of the message server stuff during it's time up.
399
400 responseData["messageserver_count"] = 0;
401
402 // IGridMessagingModule messagingModule;
403 // if (m_gridCore.TryGet<IGridMessagingModule>(out messagingModule))
404 //{
405 if (m_messagingServerMapper != null)
406 {
407 List<MessageServerInfo> messageServers = m_messagingServerMapper.GetMessageServersList();
408 responseData["messageserver_count"] = messageServers.Count;
409
410 for (int i = 0; i < messageServers.Count; i++)
411 {
412 responseData["messageserver_uri" + i] = messageServers[i].URI;
413 responseData["messageserver_sendkey" + i] = messageServers[i].sendkey;
414 responseData["messageserver_recvkey" + i] = messageServers[i].recvkey;
415 }
416 }
417 return response;
418 }
419
420 private ArrayList GetSimNeighboursData(RegionProfileData sim)
421 {
422 ArrayList SimNeighboursData = new ArrayList();
423
424 RegionProfileData neighbour;
425 Hashtable NeighbourBlock;
426
427 //First use the fast method. (not implemented in SQLLite)
428 List<RegionProfileData> neighbours = m_gridDBService.GetRegions(sim.regionLocX - 1, sim.regionLocY - 1, sim.regionLocX + 1, sim.regionLocY + 1);
429
430 if (neighbours.Count > 0)
431 {
432 foreach (RegionProfileData aSim in neighbours)
433 {
434 NeighbourBlock = new Hashtable();
435 NeighbourBlock["sim_ip"] = aSim.serverIP;
436 NeighbourBlock["sim_port"] = aSim.serverPort.ToString();
437 NeighbourBlock["region_locx"] = aSim.regionLocX.ToString();
438 NeighbourBlock["region_locy"] = aSim.regionLocY.ToString();
439 NeighbourBlock["UUID"] = aSim.ToString();
440 NeighbourBlock["regionHandle"] = aSim.regionHandle.ToString();
441
442 if (aSim.UUID != sim.UUID)
443 {
444 SimNeighboursData.Add(NeighbourBlock);
445 }
446 }
447 }
448 else
449 {
450 for (int x = -1; x < 2; x++)
451 {
452 for (int y = -1; y < 2; y++)
453 {
454 if (
455 m_gridDBService.GetRegion(
456 Utils.UIntsToLong((uint)((sim.regionLocX + x) * Constants.RegionSize),
457 (uint)(sim.regionLocY + y) * Constants.RegionSize)) != null)
458 {
459 neighbour =
460 m_gridDBService.GetRegion(
461 Utils.UIntsToLong((uint)((sim.regionLocX + x) * Constants.RegionSize),
462 (uint)(sim.regionLocY + y) * Constants.RegionSize));
463
464 NeighbourBlock = new Hashtable();
465 NeighbourBlock["sim_ip"] = neighbour.serverIP;
466 NeighbourBlock["sim_port"] = neighbour.serverPort.ToString();
467 NeighbourBlock["region_locx"] = neighbour.regionLocX.ToString();
468 NeighbourBlock["region_locy"] = neighbour.regionLocY.ToString();
469 NeighbourBlock["UUID"] = neighbour.UUID.ToString();
470 NeighbourBlock["regionHandle"] = neighbour.regionHandle.ToString();
471
472 if (neighbour.UUID != sim.UUID) SimNeighboursData.Add(NeighbourBlock);
473 }
474 }
475 }
476 }
477 return SimNeighboursData;
478 }
479
480 /// <summary>
481 /// Loads the grid's own RegionProfileData object with data from the XMLRPC simulator_login request from a region
482 /// </summary>
483 /// <param name="requestData"></param>
484 /// <returns></returns>
485 private RegionProfileData RegionFromRequest(Hashtable requestData)
486 {
487 RegionProfileData sim;
488 sim = new RegionProfileData();
489
490 sim.UUID = new UUID((string)requestData["UUID"]);
491 sim.originUUID = new UUID((string)requestData["originUUID"]);
492
493 sim.regionRecvKey = String.Empty;
494 sim.regionSendKey = String.Empty;
495
496 if (requestData.ContainsKey("region_secret"))
497 {
498 string regionsecret = (string)requestData["region_secret"];
499 if (regionsecret.Length > 0)
500 sim.regionSecret = regionsecret;
501 else
502 sim.regionSecret = m_config.SimRecvKey;
503
504 }
505 else
506 {
507 sim.regionSecret = m_config.SimRecvKey;
508 }
509
510 sim.regionDataURI = String.Empty;
511 sim.regionAssetURI = m_config.DefaultAssetServer;
512 sim.regionAssetRecvKey = m_config.AssetRecvKey;
513 sim.regionAssetSendKey = m_config.AssetSendKey;
514 sim.regionUserURI = m_config.DefaultUserServer;
515 sim.regionUserSendKey = m_config.UserSendKey;
516 sim.regionUserRecvKey = m_config.UserRecvKey;
517
518 sim.serverIP = (string)requestData["sim_ip"];
519 sim.serverPort = Convert.ToUInt32((string)requestData["sim_port"]);
520 sim.httpPort = Convert.ToUInt32((string)requestData["http_port"]);
521 sim.remotingPort = Convert.ToUInt32((string)requestData["remoting_port"]);
522 sim.regionLocX = Convert.ToUInt32((string)requestData["region_locx"]);
523 sim.regionLocY = Convert.ToUInt32((string)requestData["region_locy"]);
524 sim.regionLocZ = 0;
525
526 UUID textureID;
527 if (UUID.TryParse((string)requestData["map-image-id"], out textureID))
528 {
529 sim.regionMapTextureID = textureID;
530 }
531
532 // part of an initial brutish effort to provide accurate information (as per the xml region spec)
533 // wrt the ownership of a given region
534 // the (very bad) assumption is that this value is being read and handled inconsistently or
535 // not at all. Current strategy is to put the code in place to support the validity of this information
536 // and to roll forward debugging any issues from that point
537 //
538 // this particular section of the mod attempts to receive a value from the region's xml file by way of
539 // OSG1GridServices for the region's owner
540 sim.owner_uuid = (UUID)(string)requestData["master_avatar_uuid"];
541
542 try
543 {
544 sim.regionRecvKey = (string)requestData["recvkey"];
545 sim.regionSendKey = (string)requestData["authkey"];
546 }
547 catch (KeyNotFoundException) { }
548
549 sim.regionHandle = Utils.UIntsToLong((sim.regionLocX * Constants.RegionSize), (sim.regionLocY * Constants.RegionSize));
550 sim.serverURI = (string)requestData["server_uri"];
551
552 sim.httpServerURI = "http://" + sim.serverIP + ":" + sim.httpPort + "/";
553
554 sim.regionName = (string)requestData["sim_name"];
555
556
557 try
558 {
559
560 sim.maturity = Convert.ToUInt32((string)requestData["maturity"]);
561 }
562 catch (KeyNotFoundException)
563 {
564 //older region not providing this key - so default to Mature
565 sim.maturity = 1;
566 }
567
568 return sim;
569 }
570
571 /// <summary>
572 /// Returns an XML RPC response to a simulator profile request
573 /// Performed after moving a region.
574 /// </summary>
575 /// <param name="request"></param>
576 /// <returns></returns>
577 /// <param name="request">The XMLRPC Request</param>
578 /// <returns>Processing parameters</returns>
579 public XmlRpcResponse XmlRpcDeleteRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient)
580 {
581 XmlRpcResponse response = new XmlRpcResponse();
582 Hashtable responseData = new Hashtable();
583 response.Value = responseData;
584
585 //RegionProfileData TheSim = null;
586 string uuid;
587 Hashtable requestData = (Hashtable)request.Params[0];
588
589 if (requestData.ContainsKey("UUID"))
590 {
591 //TheSim = GetRegion(new UUID((string) requestData["UUID"]));
592 uuid = requestData["UUID"].ToString();
593 m_log.InfoFormat("[LOGOUT]: Logging out region: {0}", uuid);
594 // logToDB((new LLUUID((string)requestData["UUID"])).ToString(),"XmlRpcDeleteRegionMethod","", 5,"Attempting delete with UUID.");
595 }
596 else
597 {
598 responseData["error"] = "No UUID or region_handle passed to grid server - unable to delete";
599 return response;
600 }
601
602 DataResponse insertResponse = m_gridDBService.DeleteRegion(uuid);
603
604 string insertResp = "";
605 switch (insertResponse)
606 {
607 case DataResponse.RESPONSE_OK:
608 //MainLog.Instance.Verbose("grid", "Deleting region successful: " + uuid);
609 insertResp = "Deleting region successful: " + uuid;
610 break;
611 case DataResponse.RESPONSE_ERROR:
612 //MainLog.Instance.Warn("storage", "Deleting region failed (Error): " + uuid);
613 insertResp = "Deleting region failed (Error): " + uuid;
614 break;
615 case DataResponse.RESPONSE_INVALIDCREDENTIALS:
616 //MainLog.Instance.Warn("storage", "Deleting region failed (Invalid Credentials): " + uuid);
617 insertResp = "Deleting region (Invalid Credentials): " + uuid;
618 break;
619 case DataResponse.RESPONSE_AUTHREQUIRED:
620 //MainLog.Instance.Warn("storage", "Deleting region failed (Authentication Required): " + uuid);
621 insertResp = "Deleting region (Authentication Required): " + uuid;
622 break;
623 }
624
625 responseData["status"] = insertResp;
626
627 return response;
628 }
629
630 /// <summary>
631 /// Returns an XML RPC response to a simulator profile request
632 /// </summary>
633 /// <param name="request"></param>
634 /// <returns></returns>
635 public XmlRpcResponse XmlRpcSimulatorDataRequestMethod(XmlRpcRequest request, IPEndPoint remoteClient)
636 {
637 Hashtable requestData = (Hashtable)request.Params[0];
638 Hashtable responseData = new Hashtable();
639 RegionProfileData simData = null;
640 if (requestData.ContainsKey("region_UUID"))
641 {
642 UUID regionID = new UUID((string)requestData["region_UUID"]);
643 simData = m_gridDBService.GetRegion(regionID);
644 if (simData == null)
645 {
646 m_log.WarnFormat("[DATA] didn't find region for regionID {0} from {1}",
647 regionID, request.Params.Count > 1 ? request.Params[1] : "unknwon source");
648 }
649 }
650 else if (requestData.ContainsKey("region_handle"))
651 {
652 //CFK: The if/else below this makes this message redundant.
653 //CFK: m_log.Info("requesting data for region " + (string) requestData["region_handle"]);
654 ulong regionHandle = Convert.ToUInt64((string)requestData["region_handle"]);
655 simData = m_gridDBService.GetRegion(regionHandle);
656 if (simData == null)
657 {
658 m_log.WarnFormat("[DATA] didn't find region for regionHandle {0} from {1}",
659 regionHandle, request.Params.Count > 1 ? request.Params[1] : "unknwon source");
660 }
661 }
662 else if (requestData.ContainsKey("region_name_search"))
663 {
664 string regionName = (string)requestData["region_name_search"];
665 simData = m_gridDBService.GetRegion(regionName);
666 if (simData == null)
667 {
668 m_log.WarnFormat("[DATA] didn't find region for regionName {0} from {1}",
669 regionName, request.Params.Count > 1 ? request.Params[1] : "unknwon source");
670 }
671 }
672 else m_log.Warn("[DATA] regionlookup without regionID, regionHandle or regionHame");
673
674 if (simData == null)
675 {
676 //Sim does not exist
677 responseData["error"] = "Sim does not exist";
678 }
679 else
680 {
681 m_log.Info("[DATA]: found " + (string)simData.regionName + " regionHandle = " +
682 (string)requestData["region_handle"]);
683 responseData["sim_ip"] = simData.serverIP;
684 responseData["sim_port"] = simData.serverPort.ToString();
685 responseData["server_uri"] = simData.serverURI;
686 responseData["http_port"] = simData.httpPort.ToString();
687 responseData["remoting_port"] = simData.remotingPort.ToString();
688 responseData["region_locx"] = simData.regionLocX.ToString();
689 responseData["region_locy"] = simData.regionLocY.ToString();
690 responseData["region_UUID"] = simData.UUID.Guid.ToString();
691 responseData["region_name"] = simData.regionName;
692 responseData["regionHandle"] = simData.regionHandle.ToString();
693 }
694
695 XmlRpcResponse response = new XmlRpcResponse();
696 response.Value = responseData;
697 return response;
698 }
699
700 public XmlRpcResponse XmlRpcMapBlockMethod(XmlRpcRequest request, IPEndPoint remoteClient)
701 {
702 int xmin = 980, ymin = 980, xmax = 1020, ymax = 1020;
703
704 Hashtable requestData = (Hashtable)request.Params[0];
705 if (requestData.ContainsKey("xmin"))
706 {
707 xmin = (Int32)requestData["xmin"];
708 }
709 if (requestData.ContainsKey("ymin"))
710 {
711 ymin = (Int32)requestData["ymin"];
712 }
713 if (requestData.ContainsKey("xmax"))
714 {
715 xmax = (Int32)requestData["xmax"];
716 }
717 if (requestData.ContainsKey("ymax"))
718 {
719 ymax = (Int32)requestData["ymax"];
720 }
721 //CFK: The second log is more meaningful and either standard or fast generally occurs.
722 //CFK: m_log.Info("[MAP]: World map request for range (" + xmin + "," + ymin + ")..(" + xmax + "," + ymax + ")");
723
724 XmlRpcResponse response = new XmlRpcResponse();
725 Hashtable responseData = new Hashtable();
726 response.Value = responseData;
727 IList simProfileList = new ArrayList();
728
729 bool fastMode = (m_config.DatabaseProvider == "OpenSim.Data.MySQL.dll" || m_config.DatabaseProvider == "OpenSim.Data.MSSQL.dll");
730
731 if (fastMode)
732 {
733 List<RegionProfileData> neighbours = m_gridDBService.GetRegions((uint)xmin, (uint)ymin, (uint)xmax, (uint)ymax);
734
735 foreach (RegionProfileData aSim in neighbours)
736 {
737 Hashtable simProfileBlock = new Hashtable();
738 simProfileBlock["x"] = aSim.regionLocX.ToString();
739 simProfileBlock["y"] = aSim.regionLocY.ToString();
740 //m_log.DebugFormat("[MAP]: Sending neighbour info for {0},{1}", aSim.regionLocX, aSim.regionLocY);
741 simProfileBlock["name"] = aSim.regionName;
742 simProfileBlock["access"] = aSim.AccessLevel.ToString();
743 simProfileBlock["region-flags"] = 512;
744 simProfileBlock["water-height"] = 0;
745 simProfileBlock["agents"] = 1;
746 simProfileBlock["map-image-id"] = aSim.regionMapTextureID.ToString();
747
748 // For Sugilite compatibility
749 simProfileBlock["regionhandle"] = aSim.regionHandle.ToString();
750 simProfileBlock["sim_ip"] = aSim.serverIP;
751 simProfileBlock["sim_port"] = aSim.serverPort.ToString();
752 simProfileBlock["sim_uri"] = aSim.serverURI.ToString();
753 simProfileBlock["uuid"] = aSim.UUID.ToString();
754 simProfileBlock["remoting_port"] = aSim.remotingPort.ToString();
755 simProfileBlock["http_port"] = aSim.httpPort.ToString();
756
757 simProfileList.Add(simProfileBlock);
758 }
759 m_log.Info("[MAP]: Fast map " + simProfileList.Count.ToString() +
760 " regions @ (" + xmin + "," + ymin + ")..(" + xmax + "," + ymax + ")");
761 }
762 else
763 {
764 RegionProfileData simProfile;
765 for (int x = xmin; x < xmax + 1; x++)
766 {
767 for (int y = ymin; y < ymax + 1; y++)
768 {
769 ulong regHandle = Utils.UIntsToLong((uint)(x * Constants.RegionSize), (uint)(y * Constants.RegionSize));
770 simProfile = m_gridDBService.GetRegion(regHandle);
771 if (simProfile != null)
772 {
773 Hashtable simProfileBlock = new Hashtable();
774 simProfileBlock["x"] = x;
775 simProfileBlock["y"] = y;
776 simProfileBlock["name"] = simProfile.regionName;
777 simProfileBlock["access"] = simProfile.AccessLevel.ToString();
778 simProfileBlock["region-flags"] = 0;
779 simProfileBlock["water-height"] = 20;
780 simProfileBlock["agents"] = 1;
781 simProfileBlock["map-image-id"] = simProfile.regionMapTextureID.ToString();
782
783 // For Sugilite compatibility
784 simProfileBlock["regionhandle"] = simProfile.regionHandle.ToString();
785 simProfileBlock["sim_ip"] = simProfile.serverIP.ToString();
786 simProfileBlock["sim_port"] = simProfile.serverPort.ToString();
787 simProfileBlock["sim_uri"] = simProfile.serverURI.ToString();
788 simProfileBlock["uuid"] = simProfile.UUID.ToString();
789 simProfileBlock["remoting_port"] = simProfile.remotingPort.ToString();
790 simProfileBlock["http_port"] = simProfile.httpPort;
791
792 simProfileList.Add(simProfileBlock);
793 }
794 }
795 }
796 m_log.Info("[MAP]: Std map " + simProfileList.Count.ToString() +
797 " regions @ (" + xmin + "," + ymin + ")..(" + xmax + "," + ymax + ")");
798 }
799
800 responseData["sim-profiles"] = simProfileList;
801
802 return response;
803 }
804
805 /// <summary>
806 /// Returns up to <code>maxNumber</code> profiles of regions that have a name starting with <code>name</code>
807 /// </summary>
808 /// <param name="request"></param>
809 /// <returns></returns>
810 public XmlRpcResponse XmlRpcSearchForRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient)
811 {
812 Hashtable requestData = (Hashtable)request.Params[0];
813
814 if (!requestData.ContainsKey("name") || !requestData.Contains("maxNumber"))
815 {
816 m_log.Warn("[DATA] Invalid region-search request; missing name or maxNumber");
817 return new XmlRpcResponse(500, "Missing name or maxNumber in region search request");
818 }
819
820 Hashtable responseData = new Hashtable();
821
822 string name = (string)requestData["name"];
823 int maxNumber = Convert.ToInt32((string)requestData["maxNumber"]);
824 if (maxNumber == 0 || name.Length < 3)
825 {
826 // either we didn't want any, or we were too unspecific
827 responseData["numFound"] = 0;
828 }
829 else
830 {
831 List<RegionProfileData> sims = m_gridDBService.GetRegions(name, maxNumber);
832
833 responseData["numFound"] = sims.Count;
834 for (int i = 0; i < sims.Count; ++i)
835 {
836 RegionProfileData sim = sims[i];
837 string prefix = "region" + i + ".";
838 responseData[prefix + "region_name"] = sim.regionName;
839 responseData[prefix + "region_UUID"] = sim.UUID.ToString();
840 responseData[prefix + "region_locx"] = sim.regionLocX.ToString();
841 responseData[prefix + "region_locy"] = sim.regionLocY.ToString();
842 responseData[prefix + "sim_ip"] = sim.serverIP.ToString();
843 responseData[prefix + "sim_port"] = sim.serverPort.ToString();
844 responseData[prefix + "remoting_port"] = sim.remotingPort.ToString();
845 responseData[prefix + "http_port"] = sim.httpPort.ToString();
846 responseData[prefix + "map_UUID"] = sim.regionMapTextureID.ToString();
847 }
848 }
849
850 XmlRpcResponse response = new XmlRpcResponse();
851 response.Value = responseData;
852 return response;
853 }
854
855 /// <summary>
856 /// Construct an XMLRPC registration disabled response
857 /// </summary>
858 /// <param name="error"></param>
859 /// <returns></returns>
860 public static XmlRpcResponse XmlRPCRegionRegistrationDisabledResponse(string error)
861 {
862 XmlRpcResponse errorResponse = new XmlRpcResponse();
863 Hashtable errorResponseData = new Hashtable();
864 errorResponse.Value = errorResponseData;
865 errorResponseData["restricted"] = error;
866 return errorResponse;
867 }
868 }
869
870 /// <summary>
871 /// Exception generated when a simulator fails to login to the grid
872 /// </summary>
873 public class LoginException : Exception
874 {
875 /// <summary>
876 /// Return an XmlRpcResponse version of the exception message suitable for sending to a client
877 /// </summary>
878 /// <param name="message"></param>
879 /// <param name="xmlRpcMessage"></param>
880 public XmlRpcResponse XmlRpcErrorResponse
881 {
882 get { return m_xmlRpcErrorResponse; }
883 }
884 private XmlRpcResponse m_xmlRpcErrorResponse;
885
886 public LoginException(string message, string xmlRpcMessage)
887 : base(message)
888 {
889 // FIXME: Might be neater to refactor and put the method inside here
890 m_xmlRpcErrorResponse = GridXmlRpcModule.ErrorResponse(xmlRpcMessage);
891 }
892
893 public LoginException(string message, string xmlRpcMessage, Exception e)
894 : base(message, e)
895 {
896 // FIXME: Might be neater to refactor and put the method inside here
897 m_xmlRpcErrorResponse = GridXmlRpcModule.ErrorResponse(xmlRpcMessage);
898 }
899 }
900}