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