OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
RemoteAdminPlugin.cs
Go to the documentation of this file.
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.Globalization;
32 using System.IO;
33 using System.Xml;
34 using System.Net;
35 using System.Reflection;
36 using System.Timers;
37 using System.Threading;
38 using log4net;
39 using Nini.Config;
40 using Nwc.XmlRpc;
41 using OpenMetaverse;
42 using Mono.Addins;
43 using OpenSim;
44 using OpenSim.Framework;
45 using OpenSim.Framework.Console;
46 using OpenSim.Framework.Servers;
47 using OpenSim.Framework.Servers.HttpServer;
48 using OpenSim.Region.CoreModules.World.Terrain;
49 using OpenSim.Region.Framework.Interfaces;
50 using OpenSim.Region.Framework.Scenes;
51 using OpenSim.Services.Interfaces;
56 
57 namespace OpenSim.ApplicationPlugins.RemoteController
58 {
59  [Extension(Path = "/OpenSim/Startup", Id = "LoadRegions", NodeName = "Plugin")]
61  {
62  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63 
64  private static bool m_defaultAvatarsLoaded = false;
65  private static Object m_requestLock = new Object();
66  private static Object m_saveOarLock = new Object();
67 
68  private OpenSimBase m_application;
69  private IHttpServer m_httpServer;
70  private IConfig m_config;
71  private IConfigSource m_configSource;
72  private string m_requiredPassword = String.Empty;
73  private HashSet<string> m_accessIP;
74 
75  private string m_name = "RemoteAdminPlugin";
76  private string m_version = "0.0";
77  private string m_openSimVersion;
78 
79  public string Version
80  {
81  get { return m_version; }
82  }
83 
84  public string Name
85  {
86  get { return m_name; }
87  }
88 
89  public void Initialise()
90  {
91  m_log.Error("[RADMIN]: " + Name + " cannot be default-initialized!");
92  throw new PluginNotInitialisedException(Name);
93  }
94 
95  public void Initialise(OpenSimBase openSim)
96  {
97  m_openSimVersion = openSim.GetVersionText();
98 
99  m_configSource = openSim.ConfigSource.Source;
100  try
101  {
102  if (m_configSource.Configs["RemoteAdmin"] == null ||
103  !m_configSource.Configs["RemoteAdmin"].GetBoolean("enabled", false))
104  {
105  // No config or disabled
106  }
107  else
108  {
109  m_config = m_configSource.Configs["RemoteAdmin"];
110  m_log.Debug("[RADMIN]: Remote Admin Plugin Enabled");
111  m_requiredPassword = m_config.GetString("access_password", String.Empty);
112  int port = m_config.GetInt("port", 0);
113 
114  string accessIP = m_config.GetString("access_ip_addresses", String.Empty);
115  m_accessIP = new HashSet<string>();
116  if (accessIP != String.Empty)
117  {
118  string[] ips = accessIP.Split(new char[] { ',' });
119  foreach (string ip in ips)
120  {
121  string current = ip.Trim();
122 
123  if (current != String.Empty)
124  m_accessIP.Add(current);
125  }
126  }
127 
128  m_application = openSim;
129  string bind_ip_address = m_config.GetString("bind_ip_address", "0.0.0.0");
130  IPAddress ipaddr = IPAddress.Parse(bind_ip_address);
131  m_httpServer = MainServer.GetHttpServer((uint)port,ipaddr);
132 
133  Dictionary<string, XmlRpcMethod> availableMethods = new Dictionary<string, XmlRpcMethod>();
134  availableMethods["admin_create_region"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCreateRegionMethod);
135  availableMethods["admin_delete_region"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDeleteRegionMethod);
136  availableMethods["admin_close_region"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCloseRegionMethod);
137  availableMethods["admin_modify_region"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcModifyRegionMethod);
138  availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
139  availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
140  availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod);
141  availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod);
142  availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
143  availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
144  availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
145 
146  availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
147 
148  // Agent management
149  availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod);
150  availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod);
151 
152  // User management
153  availableMethods["admin_create_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCreateUserMethod);
154  availableMethods["admin_create_user_email"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCreateUserMethod);
155  availableMethods["admin_exists_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUserExistsMethod);
156  availableMethods["admin_update_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUpdateUserAccountMethod);
157  availableMethods["admin_authenticate_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAuthenticateUserMethod);
158 
159  // Region state management
160  availableMethods["admin_load_xml"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadXMLMethod);
161  availableMethods["admin_save_xml"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveXMLMethod);
162  availableMethods["admin_load_oar"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadOARMethod);
163  availableMethods["admin_save_oar"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveOARMethod);
164 
165  // Estate access list management
166  availableMethods["admin_acl_clear"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListClear);
167  availableMethods["admin_acl_add"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListAdd);
168  availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove);
169  availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
170  availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
171 
172  // Misc
173  availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch);
174  availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap);
175  availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion);
176  availableMethods["admin_get_agent_count"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentCount);
177 
178  // Either enable full remote functionality or just selected features
179  string enabledMethods = m_config.GetString("enabled_methods", "all");
180 
181  // To get this, you must explicitly specify "all" or
182  // mention it in a whitelist. It won't be available
183  // If you just leave the option out!
184  //
185  if (!String.IsNullOrEmpty(enabledMethods))
186  availableMethods["admin_console_command"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcConsoleCommandMethod);
187 
188  // The assumption here is that simply enabling Remote Admin as before will produce the same
189  // behavior - enable all methods unless the whitelist is in place for backward-compatibility.
190  if (enabledMethods.ToLower() == "all" || String.IsNullOrEmpty(enabledMethods))
191  {
192  foreach (string method in availableMethods.Keys)
193  {
194  m_httpServer.AddXmlRPCHandler(method, availableMethods[method], false);
195  }
196  }
197  else
198  {
199  foreach (string enabledMethod in enabledMethods.Split('|'))
200  {
201  m_httpServer.AddXmlRPCHandler(enabledMethod, availableMethods[enabledMethod], false);
202  }
203  }
204  }
205  }
206  catch (NullReferenceException)
207  {
208  // Ignore.
209  }
210  }
211 
212  public void PostInitialise()
213  {
214  if (!CreateDefaultAvatars())
215  {
216  m_log.Info("[RADMIN]: Default avatars not loaded");
217  }
218  }
219 
224  private XmlRpcResponse InvokeXmlRpcMethod(
225  XmlRpcRequest request, IPEndPoint remoteClient, Action<XmlRpcRequest, XmlRpcResponse, IPEndPoint> method)
226  {
227  XmlRpcResponse response = new XmlRpcResponse();
228  Hashtable responseData = new Hashtable();
229  response.Value = responseData;
230 
231  try
232  {
233  Hashtable requestData = (Hashtable) request.Params[0];
234 
235  CheckStringParameters(requestData, responseData, new string[] {"password"});
236 
237  FailIfRemoteAdminNotAllowed((string)requestData["password"], responseData, remoteClient.Address.ToString());
238 
239  method(request, response, remoteClient);
240  }
241  catch (Exception e)
242  {
243  m_log.ErrorFormat(
244  "[RADMIN]: Method {0} failed. Exception {1}{2}", request.MethodName, e.Message, e.StackTrace);
245 
246  responseData["success"] = false;
247  responseData["error"] = e.Message;
248  }
249 
250  return response;
251  }
252 
253  private void FailIfRemoteAdminNotAllowed(string password, Hashtable responseData, string check_ip_address)
254  {
255  if (m_accessIP.Count > 0 && !m_accessIP.Contains(check_ip_address))
256  {
257  m_log.WarnFormat("[RADMIN]: Unauthorized access blocked from IP {0}", check_ip_address);
258  responseData["accepted"] = false;
259  throw new Exception("not authorized");
260  }
261 
262  if (m_requiredPassword != String.Empty && password != m_requiredPassword)
263  {
264  m_log.WarnFormat("[RADMIN]: Wrong password, blocked access from IP {0}", check_ip_address);
265  responseData["accepted"] = false;
266  throw new Exception("wrong password");
267  }
268  }
269 
270  private void XmlRpcRestartMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
271  {
272  Hashtable responseData = (Hashtable)response.Value;
273  Hashtable requestData = (Hashtable)request.Params[0];
274 
275  try
276  {
277  Scene rebootedScene = null;
278  bool restartAll = false;
279 
280  IConfig startupConfig = m_configSource.Configs["Startup"];
281  if (startupConfig != null)
282  {
283  if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
284  {
285  rebootedScene = m_application.SceneManager.CurrentOrFirstScene;
286  restartAll = true;
287  }
288  }
289 
290  if (rebootedScene == null)
291  {
292  CheckRegionParams(requestData, responseData);
293 
294  GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
295  }
296 
297  IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
298 
299  responseData["success"] = false;
300  responseData["accepted"] = true;
301  responseData["rebooting"] = true;
302 
303  string message;
304  List<int> times = new List<int>();
305 
306  if (requestData.ContainsKey("alerts"))
307  {
308  string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','});
309  if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1)
310  {
311  m_log.Info("[RADMIN]: Request to cancel restart.");
312 
313  if (restartModule != null)
314  {
315  message = "Restart has been cancelled";
316 
317  if (requestData.ContainsKey("message"))
318  message = requestData["message"].ToString();
319 
320  restartModule.AbortRestart(message);
321 
322  responseData["success"] = true;
323  responseData["rebooting"] = false;
324 
325  return;
326  }
327  }
328  foreach (string a in alertTimes)
329  times.Add(Convert.ToInt32(a));
330  }
331  else
332  {
333  int timeout = 30;
334  if (requestData.ContainsKey("milliseconds"))
335  timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000;
336  while (timeout > 0)
337  {
338  times.Add(timeout);
339  if (timeout > 300)
340  timeout -= 120;
341  else if (timeout > 30)
342  timeout -= 30;
343  else
344  timeout -= 15;
345  }
346  }
347 
348  m_log.Info("[RADMIN]: Request to restart Region.");
349 
350  message = "Region is restarting in {0}. Please save what you are doing and log out.";
351 
352  if (requestData.ContainsKey("message"))
353  message = requestData["message"].ToString();
354 
355  bool notice = true;
356  if (requestData.ContainsKey("noticetype")
357  && ((string)requestData["noticetype"] == "dialog"))
358  {
359  notice = false;
360  }
361 
362  List<Scene> restartList;
363 
364  if (restartAll)
365  restartList = m_application.SceneManager.Scenes;
366  else
367  restartList = new List<Scene>() { rebootedScene };
368 
369  foreach (Scene s in m_application.SceneManager.Scenes)
370  {
371  restartModule = s.RequestModuleInterface<IRestartModule>();
372  if (restartModule != null)
373  restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice);
374  }
375  responseData["success"] = true;
376  }
377  catch (Exception e)
378  {
379 // m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
380  responseData["rebooting"] = false;
381 
382  throw e;
383  }
384 
385  m_log.Info("[RADMIN]: Restart Region request complete");
386  }
387 
388  private void XmlRpcAlertMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
389  {
390  m_log.Info("[RADMIN]: Alert request started");
391 
392  Hashtable responseData = (Hashtable)response.Value;
393  Hashtable requestData = (Hashtable)request.Params[0];
394 
395  string message = (string) requestData["message"];
396  m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
397 
398  responseData["accepted"] = true;
399  responseData["success"] = true;
400 
401  m_application.SceneManager.ForEachScene(
402  delegate(Scene scene)
403  {
404  IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
405  if (dialogModule != null)
406  dialogModule.SendGeneralAlert(message);
407  });
408 
409  m_log.Info("[RADMIN]: Alert request complete");
410  }
411 
412  public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
413  {
414  Hashtable responseData = (Hashtable)response.Value;
415 
416  m_log.Info("[RADMIN]: Dialog request started");
417 
418  Hashtable requestData = (Hashtable)request.Params[0];
419 
420  string message = (string)requestData["message"];
421  string fromuuid = (string)requestData["from"];
422  m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
423 
424  responseData["accepted"] = true;
425  responseData["success"] = true;
426 
427  m_application.SceneManager.ForEachScene(
428  delegate(Scene scene)
429  {
430  IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
431  if (dialogModule != null)
432  dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
433  });
434 
435  m_log.Info("[RADMIN]: Dialog request complete");
436  }
437 
438  private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
439  {
440  m_log.Info("[RADMIN]: Load height maps request started");
441 
442  Hashtable responseData = (Hashtable)response.Value;
443  Hashtable requestData = (Hashtable)request.Params[0];
444 
445 // m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}", request);
446  // foreach (string k in requestData.Keys)
447  // {
448  // m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}: >{1}< {2}",
449  // k, (string)requestData[k], ((string)requestData[k]).Length);
450  // }
451 
452  CheckStringParameters(requestData, responseData, new string[] { "filename" });
453  CheckRegionParams(requestData, responseData);
454 
455  Scene scene = null;
456  GetSceneFromRegionParams(requestData, responseData, out scene);
457 
458  if (scene != null)
459  {
460  string file = (string)requestData["filename"];
461 
462  responseData["accepted"] = true;
463 
464  LoadHeightmap(file, scene.RegionInfo.RegionID);
465 
466  responseData["success"] = true;
467  }
468  else
469  {
470  responseData["success"] = false;
471  }
472 
473  m_log.Info("[RADMIN]: Load height maps request complete");
474  }
475 
476  private void XmlRpcSaveHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
477  {
478  m_log.Info("[RADMIN]: Save height maps request started");
479 
480  Hashtable responseData = (Hashtable)response.Value;
481  Hashtable requestData = (Hashtable)request.Params[0];
482 
483 // m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString());
484 
485  CheckStringParameters(requestData, responseData, new string[] { "filename" });
486  CheckRegionParams(requestData, responseData);
487 
488  Scene scene = null;
489  GetSceneFromRegionParams(requestData, responseData, out scene);
490 
491  if (scene != null)
492  {
493  string file = (string)requestData["filename"];
494  m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file);
495 
496  responseData["accepted"] = true;
497 
498  ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
499  if (null == terrainModule) throw new Exception("terrain module not available");
500 
501  terrainModule.SaveToFile(file);
502 
503  responseData["success"] = true;
504  }
505  else
506  {
507  responseData["success"] = false;
508  }
509 
510  m_log.Info("[RADMIN]: Save height maps request complete");
511  }
512 
513  private void XmlRpcShutdownMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
514  {
515  m_log.Info("[RADMIN]: Received Shutdown Administrator Request");
516 
517  Hashtable responseData = (Hashtable)response.Value;
518  Hashtable requestData = (Hashtable)request.Params[0];
519 
520  responseData["accepted"] = true;
521  response.Value = responseData;
522 
523  int timeout = 2000;
524  string message;
525 
526  if (requestData.ContainsKey("shutdown")
527  && ((string) requestData["shutdown"] == "delayed")
528  && requestData.ContainsKey("milliseconds"))
529  {
530  timeout = Int32.Parse(requestData["milliseconds"].ToString());
531 
532  message
533  = "Region is going down in " + ((int) (timeout/1000)).ToString()
534  + " second(s). Please save what you are doing and log out.";
535  }
536  else
537  {
538  message = "Region is going down now.";
539  }
540 
541  if (requestData.ContainsKey("noticetype")
542  && ((string) requestData["noticetype"] == "dialog"))
543  {
544  m_application.SceneManager.ForEachScene(
545 
546  delegate(Scene scene)
547  {
548  IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
549  if (dialogModule != null)
550  dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
551  });
552  }
553  else
554  {
555  if (!requestData.ContainsKey("noticetype")
556  || ((string)requestData["noticetype"] != "none"))
557  {
558  m_application.SceneManager.ForEachScene(
559  delegate(Scene scene)
560  {
561  IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
562  if (dialogModule != null)
563  dialogModule.SendGeneralAlert(message);
564  });
565  }
566  }
567 
568  // Perform shutdown
569  System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
570  shutdownTimer.AutoReset = false;
571  shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed);
572  lock (shutdownTimer)
573  {
574  shutdownTimer.Start();
575  }
576 
577  responseData["success"] = true;
578 
579  m_log.Info("[RADMIN]: Shutdown Administrator Request complete");
580  }
581 
582  private void shutdownTimer_Elapsed(object sender, ElapsedEventArgs e)
583  {
584  m_application.Shutdown();
585  }
586 
650  private void XmlRpcCreateRegionMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
651  {
652  m_log.Info("[RADMIN]: CreateRegion: new request");
653 
654  Hashtable responseData = (Hashtable)response.Value;
655  Hashtable requestData = (Hashtable)request.Params[0];
656 
657  lock (m_requestLock)
658  {
659  int m_regionLimit = m_config.GetInt("region_limit", 0);
660  bool m_enableVoiceForNewRegions = m_config.GetBoolean("create_region_enable_voice", false);
661  bool m_publicAccess = m_config.GetBoolean("create_region_public", true);
662 
663  CheckStringParameters(requestData, responseData, new string[]
664  {
665  "region_name",
666  "listen_ip", "external_address",
667  "estate_name"
668  });
669  CheckIntegerParams(requestData, responseData, new string[] {"region_x", "region_y", "listen_port"});
670 
671  // check whether we still have space left (iff we are using limits)
672  if (m_regionLimit != 0 && m_application.SceneManager.Scenes.Count >= m_regionLimit)
673  throw new Exception(String.Format("cannot instantiate new region, server capacity {0} already reached; delete regions first",
674  m_regionLimit));
675  // extract or generate region ID now
676  Scene scene = null;
677  UUID regionID = UUID.Zero;
678  if (requestData.ContainsKey("region_id") &&
679  !String.IsNullOrEmpty((string) requestData["region_id"]))
680  {
681  regionID = (UUID) (string) requestData["region_id"];
682  if (m_application.SceneManager.TryGetScene(regionID, out scene))
683  throw new Exception(
684  String.Format("region UUID already in use by region {0}, UUID {1}, <{2},{3}>",
685  scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
686  scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY));
687  }
688  else
689  {
690  regionID = UUID.Random();
691  m_log.DebugFormat("[RADMIN] CreateRegion: new region UUID {0}", regionID);
692  }
693 
694  // create volatile or persistent region info
695  RegionInfo region = new RegionInfo();
696 
697  region.RegionID = regionID;
698  region.originRegionID = regionID;
699  region.RegionName = (string) requestData["region_name"];
700  region.RegionLocX = Convert.ToUInt32(requestData["region_x"]);
701  region.RegionLocY = Convert.ToUInt32(requestData["region_y"]);
702 
703  // check for collisions: region name, region UUID,
704  // region location
705  if (m_application.SceneManager.TryGetScene(region.RegionName, out scene))
706  throw new Exception(
707  String.Format("region name already in use by region {0}, UUID {1}, <{2},{3}>",
708  scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
709  scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY));
710 
711  if (m_application.SceneManager.TryGetScene(region.RegionLocX, region.RegionLocY, out scene))
712  throw new Exception(
713  String.Format("region location <{0},{1}> already in use by region {2}, UUID {3}, <{4},{5}>",
714  region.RegionLocX, region.RegionLocY,
715  scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
716  scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY));
717 
718  region.InternalEndPoint =
719  new IPEndPoint(IPAddress.Parse((string) requestData["listen_ip"]), 0);
720 
721  region.InternalEndPoint.Port = Convert.ToInt32(requestData["listen_port"]);
722  if (0 == region.InternalEndPoint.Port) throw new Exception("listen_port is 0");
723  if (m_application.SceneManager.TryGetScene(region.InternalEndPoint, out scene))
724  throw new Exception(
725  String.Format(
726  "region internal IP {0} and port {1} already in use by region {2}, UUID {3}, <{4},{5}>",
727  region.InternalEndPoint.Address,
728  region.InternalEndPoint.Port,
729  scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
730  scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY));
731 
732  region.ExternalHostName = (string) requestData["external_address"];
733 
734  bool persist = Convert.ToBoolean(requestData["persist"]);
735  if (persist)
736  {
737  // default place for region configuration files is in the
738  // Regions directory of the config dir (aka /bin)
739  string regionConfigPath = Path.Combine(Util.configDir(), "Regions");
740  try
741  {
742  // OpenSim.ini can specify a different regions dir
743  IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"];
744  regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim();
745  }
746  catch (Exception)
747  {
748  // No INI setting recorded.
749  }
750 
751  string regionIniPath;
752 
753  if (requestData.Contains("region_file"))
754  {
755  // Make sure that the file to be created is in a subdirectory of the region storage directory.
756  string requestedFilePath = Path.Combine(regionConfigPath, (string) requestData["region_file"]);
757  string requestedDirectory = Path.GetDirectoryName(Path.GetFullPath(requestedFilePath));
758  if (requestedDirectory.StartsWith(Path.GetFullPath(regionConfigPath)))
759  regionIniPath = requestedFilePath;
760  else
761  throw new Exception("Invalid location for region file.");
762  }
763  else
764  {
765  regionIniPath = Path.Combine(regionConfigPath,
766  String.Format(
767  m_config.GetString("region_file_template",
768  "{0}x{1}-{2}.ini"),
769  region.RegionLocX.ToString(),
770  region.RegionLocY.ToString(),
771  regionID.ToString(),
772  region.InternalEndPoint.Port.ToString(),
773  region.RegionName.Replace(" ", "_").Replace(":", "_").
774  Replace("/", "_")));
775  }
776 
777  m_log.DebugFormat("[RADMIN] CreateRegion: persisting region {0} to {1}",
778  region.RegionID, regionIniPath);
779  region.SaveRegionToFile("dynamic region", regionIniPath);
780  }
781  else
782  {
783  region.Persistent = false;
784  }
785 
786  // Set the estate
787 
788  // Check for an existing estate
789  List<int> estateIDs = m_application.EstateDataService.GetEstates((string) requestData["estate_name"]);
790  if (estateIDs.Count < 1)
791  {
792  UUID userID = UUID.Zero;
793  if (requestData.ContainsKey("estate_owner_uuid"))
794  {
795  // ok, client wants us to use an explicit UUID
796  // regardless of what the avatar name provided
797  userID = new UUID((string) requestData["estate_owner_uuid"]);
798 
799  // Check that the specified user exists
800  Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
801  IUserAccountService accountService = currentOrFirst.UserAccountService;
802  UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID);
803 
804  if (user == null)
805  throw new Exception("Specified user was not found.");
806  }
807  else if (requestData.ContainsKey("estate_owner_first") & requestData.ContainsKey("estate_owner_last"))
808  {
809  // We need to look up the UUID for the avatar with the provided name.
810  string ownerFirst = (string) requestData["estate_owner_first"];
811  string ownerLast = (string) requestData["estate_owner_last"];
812 
813  Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
814  IUserAccountService accountService = currentOrFirst.UserAccountService;
815  UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
816  ownerFirst, ownerLast);
817 
818  // Check that the specified user exists
819  if (user == null)
820  throw new Exception("Specified user was not found.");
821 
822  userID = user.PrincipalID;
823  }
824  else
825  {
826  throw new Exception("Estate owner details not provided.");
827  }
828 
829  // Create a new estate with the name provided
830  region.EstateSettings = m_application.EstateDataService.CreateNewEstate();
831 
832  region.EstateSettings.EstateName = (string) requestData["estate_name"];
833  region.EstateSettings.EstateOwner = userID;
834  // Persistence does not seem to effect the need to save a new estate
835  m_application.EstateDataService.StoreEstateSettings(region.EstateSettings);
836 
837  if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID))
838  throw new Exception("Failed to join estate.");
839  }
840  else
841  {
842  int estateID = estateIDs[0];
843 
844  region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false);
845 
846  if (region.EstateSettings.EstateID != estateID)
847  {
848  // The region is already part of an estate, but not the one we want.
849  region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID);
850 
851  if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID))
852  throw new Exception("Failed to join estate.");
853  }
854  }
855 
856  // Create the region and perform any initial initialization
857 
858  IScene newScene;
859  m_application.CreateRegion(region, out newScene);
860  newScene.Start();
861 
862  // If an access specification was provided, use it.
863  // Otherwise accept the default.
864  newScene.RegionInfo.EstateSettings.PublicAccess = GetBoolean(requestData, "public", m_publicAccess);
865  m_application.EstateDataService.StoreEstateSettings(newScene.RegionInfo.EstateSettings);
866 
867  // enable voice on newly created region if
868  // requested by either the XmlRpc request or the
869  // configuration
870  if (GetBoolean(requestData, "enable_voice", m_enableVoiceForNewRegions))
871  {
872  List<ILandObject> parcels = ((Scene)newScene).LandChannel.AllParcels();
873 
874  foreach (ILandObject parcel in parcels)
875  {
876  parcel.LandData.Flags |= (uint) ParcelFlags.AllowVoiceChat;
877  parcel.LandData.Flags |= (uint) ParcelFlags.UseEstateVoiceChan;
878  ((Scene)newScene).LandChannel.UpdateLandObject(parcel.LandData.LocalID, parcel.LandData);
879  }
880  }
881 
882  //Load Heightmap if specified to new region
883  if (requestData.Contains("heightmap_file"))
884  {
885  LoadHeightmap((string)requestData["heightmap_file"], region.RegionID);
886  }
887 
888  responseData["success"] = true;
889  responseData["region_name"] = region.RegionName;
890  responseData["region_id"] = region.RegionID.ToString();
891 
892  m_log.Info("[RADMIN]: CreateRegion: request complete");
893  }
894  }
895 
922  private void XmlRpcDeleteRegionMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
923  {
924  m_log.Info("[RADMIN]: DeleteRegion: new request");
925 
926  Hashtable responseData = (Hashtable)response.Value;
927  Hashtable requestData = (Hashtable)request.Params[0];
928 
929  lock (m_requestLock)
930  {
931  CheckStringParameters(requestData, responseData, new string[] {"region_name"});
932  CheckRegionParams(requestData, responseData);
933 
934  Scene scene = null;
935  GetSceneFromRegionParams(requestData, responseData, out scene);
936 
937  m_application.RemoveRegion(scene, true);
938 
939  responseData["success"] = true;
940  responseData["region_name"] = scene.RegionInfo.RegionName;
941  responseData["region_id"] = scene.RegionInfo.RegionID;
942 
943  m_log.Info("[RADMIN]: DeleteRegion: request complete");
944  }
945  }
946 
975  private void XmlRpcCloseRegionMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
976  {
977  m_log.Info("[RADMIN]: CloseRegion: new request");
978 
979  Hashtable responseData = (Hashtable)response.Value;
980  Hashtable requestData = (Hashtable)request.Params[0];
981 
982  lock (m_requestLock)
983  {
984  CheckRegionParams(requestData, responseData);
985 
986  Scene scene = null;
987  GetSceneFromRegionParams(requestData, responseData, out scene);
988 
989  m_application.CloseRegion(scene);
990 
991  responseData["success"] = true;
992  responseData["region_name"] = scene.RegionInfo.RegionName;
993  responseData["region_id"] = scene.RegionInfo.RegionID;
994 
995  response.Value = responseData;
996 
997  m_log.Info("[RADMIN]: CloseRegion: request complete");
998  }
999  }
1000 
1033  private void XmlRpcModifyRegionMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1034  {
1035  m_log.Info("[RADMIN]: ModifyRegion: new request");
1036 
1037  Hashtable responseData = (Hashtable)response.Value;
1038  Hashtable requestData = (Hashtable)request.Params[0];
1039 
1040  lock (m_requestLock)
1041  {
1042  CheckRegionParams(requestData, responseData);
1043 
1044  Scene scene = null;
1045  GetSceneFromRegionParams(requestData, responseData, out scene);
1046 
1047  // Modify access
1048  scene.RegionInfo.EstateSettings.PublicAccess =
1049  GetBoolean(requestData,"public", scene.RegionInfo.EstateSettings.PublicAccess);
1050  if (scene.RegionInfo.Persistent)
1051  m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
1052 
1053  if (requestData.ContainsKey("enable_voice"))
1054  {
1055  bool enableVoice = GetBoolean(requestData, "enable_voice", true);
1056  List<ILandObject> parcels = ((Scene)scene).LandChannel.AllParcels();
1057 
1058  foreach (ILandObject parcel in parcels)
1059  {
1060  if (enableVoice)
1061  {
1062  parcel.LandData.Flags |= (uint)ParcelFlags.AllowVoiceChat;
1063  parcel.LandData.Flags |= (uint)ParcelFlags.UseEstateVoiceChan;
1064  }
1065  else
1066  {
1067  parcel.LandData.Flags &= ~(uint)ParcelFlags.AllowVoiceChat;
1068  parcel.LandData.Flags &= ~(uint)ParcelFlags.UseEstateVoiceChan;
1069  }
1070  scene.LandChannel.UpdateLandObject(parcel.LandData.LocalID, parcel.LandData);
1071  }
1072  }
1073 
1074  responseData["success"] = true;
1075  responseData["region_name"] = scene.RegionInfo.RegionName;
1076  responseData["region_id"] = scene.RegionInfo.RegionID;
1077 
1078  m_log.Info("[RADMIN]: ModifyRegion: request complete");
1079  }
1080  }
1081 
1120  private void XmlRpcCreateUserMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1121  {
1122  m_log.Info("[RADMIN]: CreateUser: new request");
1123 
1124  Hashtable responseData = (Hashtable)response.Value;
1125  Hashtable requestData = (Hashtable)request.Params[0];
1126 
1127  lock (m_requestLock)
1128  {
1129  try
1130  {
1131  // check completeness
1132  CheckStringParameters(requestData, responseData, new string[]
1133  {
1134  "user_firstname",
1135  "user_lastname", "user_password",
1136  });
1137  CheckIntegerParams(requestData, responseData, new string[] {"start_region_x", "start_region_y"});
1138 
1139  // do the job
1140  string firstName = (string) requestData["user_firstname"];
1141  string lastName = (string) requestData["user_lastname"];
1142  string password = (string) requestData["user_password"];
1143 
1144  uint regionXLocation = Convert.ToUInt32(requestData["start_region_x"]);
1145  uint regionYLocation = Convert.ToUInt32(requestData["start_region_y"]);
1146 
1147  string email = ""; // empty string for email
1148  if (requestData.Contains("user_email"))
1149  email = (string)requestData["user_email"];
1150 
1151  Scene scene = m_application.SceneManager.CurrentOrFirstScene;
1152  UUID scopeID = scene.RegionInfo.ScopeID;
1153 
1154  UserAccount account = CreateUser(scopeID, firstName, lastName, password, email);
1155 
1156  if (null == account)
1157  throw new Exception(String.Format("failed to create new user {0} {1}",
1158  firstName, lastName));
1159 
1160  // Set home position
1161 
1162  GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
1163  (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
1164  if (null == home)
1165  {
1166  m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName);
1167  }
1168  else
1169  {
1170  scene.GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
1171  m_log.DebugFormat("[RADMIN]: Set home region {0} for updated user account {1} {2}", home.RegionID, firstName, lastName);
1172  }
1173 
1174  // Establish the avatar's initial appearance
1175 
1176  UpdateUserAppearance(responseData, requestData, account.PrincipalID);
1177 
1178  responseData["success"] = true;
1179  responseData["avatar_uuid"] = account.PrincipalID.ToString();
1180 
1181  m_log.InfoFormat("[RADMIN]: CreateUser: User {0} {1} created, UUID {2}", firstName, lastName, account.PrincipalID);
1182  }
1183  catch (Exception e)
1184  {
1185  responseData["avatar_uuid"] = UUID.Zero.ToString();
1186 
1187  throw e;
1188  }
1189 
1190  m_log.Info("[RADMIN]: CreateUser: request complete");
1191  }
1192  }
1193 
1226  private void XmlRpcUserExistsMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1227  {
1228  m_log.Info("[RADMIN]: UserExists: new request");
1229 
1230  Hashtable responseData = (Hashtable)response.Value;
1231  Hashtable requestData = (Hashtable)request.Params[0];
1232 
1233  // check completeness
1234  CheckStringParameters(requestData, responseData, new string[] {"user_firstname", "user_lastname"});
1235 
1236  string firstName = (string) requestData["user_firstname"];
1237  string lastName = (string) requestData["user_lastname"];
1238 
1239  responseData["user_firstname"] = firstName;
1240  responseData["user_lastname"] = lastName;
1241 
1242  UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID;
1243 
1244  UserAccount account = m_application.SceneManager.CurrentOrFirstScene.UserAccountService.GetUserAccount(scopeID, firstName, lastName);
1245 
1246  if (null == account)
1247  {
1248  responseData["success"] = false;
1249  responseData["lastlogin"] = 0;
1250  }
1251  else
1252  {
1253  GridUserInfo userInfo = m_application.SceneManager.CurrentOrFirstScene.GridUserService.GetGridUserInfo(account.PrincipalID.ToString());
1254  if (userInfo != null)
1255  responseData["lastlogin"] = Util.ToUnixTime(userInfo.Login);
1256  else
1257  responseData["lastlogin"] = 0;
1258 
1259  responseData["success"] = true;
1260  }
1261 
1262  m_log.Info("[RADMIN]: UserExists: request complete");
1263  }
1264 
1307  private void XmlRpcUpdateUserAccountMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1308  {
1309  m_log.Info("[RADMIN]: UpdateUserAccount: new request");
1310  m_log.Warn("[RADMIN]: This method needs update for 0.7");
1311 
1312  Hashtable responseData = (Hashtable)response.Value;
1313  Hashtable requestData = (Hashtable)request.Params[0];
1314 
1315  lock (m_requestLock)
1316  {
1317  try
1318  {
1319  // check completeness
1320  CheckStringParameters(requestData, responseData, new string[] {
1321  "user_firstname",
1322  "user_lastname"});
1323 
1324  // do the job
1325  string firstName = (string) requestData["user_firstname"];
1326  string lastName = (string) requestData["user_lastname"];
1327 
1328  string password = String.Empty;
1329  uint? regionXLocation = null;
1330  uint? regionYLocation = null;
1331  // uint? ulaX = null;
1332  // uint? ulaY = null;
1333  // uint? ulaZ = null;
1334  // uint? usaX = null;
1335  // uint? usaY = null;
1336  // uint? usaZ = null;
1337  // string aboutFirstLive = String.Empty;
1338  // string aboutAvatar = String.Empty;
1339 
1340  if (requestData.ContainsKey("user_password")) password = (string) requestData["user_password"];
1341  if (requestData.ContainsKey("start_region_x"))
1342  regionXLocation = Convert.ToUInt32(requestData["start_region_x"]);
1343  if (requestData.ContainsKey("start_region_y"))
1344  regionYLocation = Convert.ToUInt32(requestData["start_region_y"]);
1345 
1346  // if (requestData.ContainsKey("start_lookat_x"))
1347  // ulaX = Convert.ToUInt32((Int32) requestData["start_lookat_x"]);
1348  // if (requestData.ContainsKey("start_lookat_y"))
1349  // ulaY = Convert.ToUInt32((Int32) requestData["start_lookat_y"]);
1350  // if (requestData.ContainsKey("start_lookat_z"))
1351  // ulaZ = Convert.ToUInt32((Int32) requestData["start_lookat_z"]);
1352 
1353  // if (requestData.ContainsKey("start_standat_x"))
1354  // usaX = Convert.ToUInt32((Int32) requestData["start_standat_x"]);
1355  // if (requestData.ContainsKey("start_standat_y"))
1356  // usaY = Convert.ToUInt32((Int32) requestData["start_standat_y"]);
1357  // if (requestData.ContainsKey("start_standat_z"))
1358  // usaZ = Convert.ToUInt32((Int32) requestData["start_standat_z"]);
1359  // if (requestData.ContainsKey("about_real_world"))
1360  // aboutFirstLive = (string)requestData["about_real_world"];
1361  // if (requestData.ContainsKey("about_virtual_world"))
1362  // aboutAvatar = (string)requestData["about_virtual_world"];
1363 
1364  Scene scene = m_application.SceneManager.CurrentOrFirstScene;
1365  UUID scopeID = scene.RegionInfo.ScopeID;
1366  UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, firstName, lastName);
1367 
1368  if (null == account)
1369  throw new Exception(String.Format("avatar {0} {1} does not exist", firstName, lastName));
1370 
1371  if (!String.IsNullOrEmpty(password))
1372  {
1373  m_log.DebugFormat("[RADMIN]: UpdateUserAccount: updating password for avatar {0} {1}", firstName, lastName);
1374  ChangeUserPassword(firstName, lastName, password);
1375  }
1376 
1377  // if (null != usaX) userProfile.HomeLocationX = (uint) usaX;
1378  // if (null != usaY) userProfile.HomeLocationY = (uint) usaY;
1379  // if (null != usaZ) userProfile.HomeLocationZ = (uint) usaZ;
1380 
1381  // if (null != ulaX) userProfile.HomeLookAtX = (uint) ulaX;
1382  // if (null != ulaY) userProfile.HomeLookAtY = (uint) ulaY;
1383  // if (null != ulaZ) userProfile.HomeLookAtZ = (uint) ulaZ;
1384 
1385  // if (String.Empty != aboutFirstLive) userProfile.FirstLifeAboutText = aboutFirstLive;
1386  // if (String.Empty != aboutAvatar) userProfile.AboutText = aboutAvatar;
1387 
1388  // Set home position
1389 
1390  if ((null != regionXLocation) && (null != regionYLocation))
1391  {
1392  GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
1393  (int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
1394  if (null == home) {
1395  m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
1396  } else {
1397  scene.GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
1398  m_log.DebugFormat("[RADMIN]: Set home region {0} for updated user account {1} {2}", home.RegionID, firstName, lastName);
1399  }
1400  }
1401 
1402  // User has been created. Now establish gender and appearance.
1403 
1404  UpdateUserAppearance(responseData, requestData, account.PrincipalID);
1405 
1406  responseData["success"] = true;
1407  responseData["avatar_uuid"] = account.PrincipalID.ToString();
1408 
1409  m_log.InfoFormat("[RADMIN]: UpdateUserAccount: account for user {0} {1} updated, UUID {2}",
1410  firstName, lastName,
1411  account.PrincipalID);
1412  }
1413  catch (Exception e)
1414  {
1415  responseData["avatar_uuid"] = UUID.Zero.ToString();
1416 
1417  throw e;
1418  }
1419 
1420  m_log.Info("[RADMIN]: UpdateUserAccount: request complete");
1421  }
1422  }
1423 
1456  private void XmlRpcAuthenticateUserMethod(XmlRpcRequest request, XmlRpcResponse response,
1457  IPEndPoint remoteClient)
1458  {
1459  m_log.Info("[RADMIN]: AuthenticateUser: new request");
1460 
1461  var responseData = (Hashtable)response.Value;
1462  var requestData = (Hashtable)request.Params[0];
1463 
1464  lock (m_requestLock)
1465  {
1466  try
1467  {
1468  CheckStringParameters(requestData, responseData, new[]
1469  {
1470  "user_firstname",
1471  "user_lastname",
1472  "user_password",
1473  "token_lifetime"
1474  });
1475 
1476  var firstName = (string)requestData["user_firstname"];
1477  var lastName = (string)requestData["user_lastname"];
1478  var password = (string)requestData["user_password"];
1479 
1480  var scene = m_application.SceneManager.CurrentOrFirstScene;
1481 
1482  if (scene.Equals(null))
1483  {
1484  m_log.Debug("scene does not exist");
1485  throw new Exception("Scene does not exist.");
1486  }
1487 
1488  var scopeID = scene.RegionInfo.ScopeID;
1489  var account = scene.UserAccountService.GetUserAccount(scopeID, firstName, lastName);
1490 
1491  if (account.Equals(null) || account.PrincipalID.Equals(UUID.Zero))
1492  {
1493  m_log.DebugFormat("avatar {0} {1} does not exist", firstName, lastName);
1494  throw new Exception(String.Format("avatar {0} {1} does not exist", firstName, lastName));
1495  }
1496 
1497  if (String.IsNullOrEmpty(password))
1498  {
1499  m_log.DebugFormat("[RADMIN]: AuthenticateUser: no password provided for {0} {1}", firstName,
1500  lastName);
1501  throw new Exception(String.Format("no password provided for {0} {1}", firstName,
1502  lastName));
1503  }
1504 
1505  int lifetime;
1506  if (int.TryParse((string)requestData["token_lifetime"], NumberStyles.Integer, CultureInfo.InvariantCulture, out lifetime) == false)
1507  {
1508  m_log.DebugFormat("[RADMIN]: AuthenticateUser: no token lifetime provided for {0} {1}", firstName,
1509  lastName);
1510  throw new Exception(String.Format("no token lifetime provided for {0} {1}", firstName,
1511  lastName));
1512  }
1513 
1514  // Upper bound on lifetime set to 30s.
1515  if (lifetime > 30)
1516  {
1517  m_log.DebugFormat("[RADMIN]: AuthenticateUser: token lifetime longer than 30s for {0} {1}", firstName,
1518  lastName);
1519  throw new Exception(String.Format("token lifetime longer than 30s for {0} {1}", firstName,
1520  lastName));
1521  }
1522 
1523  var authModule = scene.RequestModuleInterface<IAuthenticationService>();
1524  if (authModule == null)
1525  {
1526  m_log.Debug("[RADMIN]: AuthenticateUser: no authentication module loded");
1527  throw new Exception("no authentication module loaded");
1528  }
1529 
1530  var token = authModule.Authenticate(account.PrincipalID, password, lifetime);
1531  if (String.IsNullOrEmpty(token))
1532  {
1533  m_log.DebugFormat("[RADMIN]: AuthenticateUser: authentication failed for {0} {1}", firstName,
1534  lastName);
1535  throw new Exception(String.Format("authentication failed for {0} {1}", firstName,
1536  lastName));
1537  }
1538 
1539  m_log.DebugFormat("[RADMIN]: AuthenticateUser: account for user {0} {1} identified with token {2}",
1540  firstName, lastName, token);
1541 
1542  responseData["token"] = token;
1543  responseData["success"] = true;
1544 
1545  }
1546  catch (Exception e)
1547  {
1548  responseData["success"] = false;
1549  responseData["error"] = e.Message;
1550  throw e;
1551  }
1552 
1553  m_log.Info("[RADMIN]: AuthenticateUser: request complete");
1554  }
1555  }
1556 
1593  private void XmlRpcLoadOARMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1594  {
1595  m_log.Info("[RADMIN]: Received Load OAR Administrator Request");
1596 
1597  Hashtable responseData = (Hashtable)response.Value;
1598  Hashtable requestData = (Hashtable)request.Params[0];
1599 
1600  lock (m_requestLock)
1601  {
1602  try
1603  {
1604  CheckStringParameters(requestData, responseData, new string[] {"filename"});
1605  CheckRegionParams(requestData, responseData);
1606 
1607  Scene scene = null;
1608  GetSceneFromRegionParams(requestData, responseData, out scene);
1609 
1610  string filename = (string) requestData["filename"];
1611 
1612  bool mergeOar = false;
1613  bool skipAssets = false;
1614 
1615  if ((string)requestData["merge"] == "true")
1616  {
1617  mergeOar = true;
1618  }
1619  if ((string)requestData["skip-assets"] == "true")
1620  {
1621  skipAssets = true;
1622  }
1623 
1624  IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
1625  Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
1626  if (mergeOar) archiveOptions.Add("merge", null);
1627  if (skipAssets) archiveOptions.Add("skipAssets", null);
1628  if (archiver != null)
1629  archiver.DearchiveRegion(filename, Guid.Empty, archiveOptions);
1630  else
1631  throw new Exception("Archiver module not present for scene");
1632 
1633  responseData["loaded"] = true;
1634  }
1635  catch (Exception e)
1636  {
1637  responseData["loaded"] = false;
1638 
1639  throw e;
1640  }
1641 
1642  m_log.Info("[RADMIN]: Load OAR Administrator Request complete");
1643  }
1644  }
1645 
1686  private void XmlRpcSaveOARMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1687  {
1688  m_log.Info("[RADMIN]: Received Save OAR Request");
1689 
1690  Hashtable responseData = (Hashtable)response.Value;
1691  Hashtable requestData = (Hashtable)request.Params[0];
1692 
1693  try
1694  {
1695  CheckStringParameters(requestData, responseData, new string[] {"filename"});
1696  CheckRegionParams(requestData, responseData);
1697 
1698  Scene scene = null;
1699  GetSceneFromRegionParams(requestData, responseData, out scene);
1700 
1701  string filename = (string)requestData["filename"];
1702 
1703  Dictionary<string, object> options = new Dictionary<string, object>();
1704 
1705  //if (requestData.Contains("version"))
1706  //{
1707  // options["version"] = (string)requestData["version"];
1708  //}
1709 
1710  if (requestData.Contains("home"))
1711  {
1712  options["home"] = (string)requestData["home"];
1713  }
1714 
1715  if ((string)requestData["noassets"] == "true")
1716  {
1717  options["noassets"] = (string)requestData["noassets"] ;
1718  }
1719 
1720  if (requestData.Contains("perm"))
1721  {
1722  options["checkPermissions"] = (string)requestData["perm"];
1723  }
1724 
1725  if ((string)requestData["all"] == "true")
1726  {
1727  options["all"] = (string)requestData["all"];
1728  }
1729 
1730  IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
1731 
1732  if (archiver != null)
1733  {
1734  Guid requestId = Guid.NewGuid();
1735  scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted;
1736 
1737  m_log.InfoFormat(
1738  "[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}",
1739  scene.Name, filename, requestId);
1740 
1741  archiver.ArchiveRegion(filename, requestId, options);
1742 
1743  lock (m_saveOarLock)
1744  Monitor.Wait(m_saveOarLock,5000);
1745 
1746  scene.EventManager.OnOarFileSaved -= RemoteAdminOarSaveCompleted;
1747  }
1748  else
1749  {
1750  throw new Exception("Archiver module not present for scene");
1751  }
1752 
1753  responseData["saved"] = true;
1754  }
1755  catch (Exception e)
1756  {
1757  responseData["saved"] = false;
1758 
1759  throw e;
1760  }
1761 
1762  m_log.Info("[RADMIN]: Save OAR Request complete");
1763  }
1764 
1765  private void RemoteAdminOarSaveCompleted(Guid uuid, string name)
1766  {
1767  if (name != "")
1768  m_log.ErrorFormat("[RADMIN]: Saving of OAR file with request ID {0} failed with message {1}", uuid, name);
1769  else
1770  m_log.DebugFormat("[RADMIN]: Saved OAR file for request {0}", uuid);
1771 
1772  lock (m_saveOarLock)
1773  Monitor.Pulse(m_saveOarLock);
1774  }
1775 
1776  private void XmlRpcLoadXMLMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1777  {
1778  m_log.Info("[RADMIN]: Received Load XML Administrator Request");
1779 
1780  Hashtable responseData = (Hashtable)response.Value;
1781  Hashtable requestData = (Hashtable)request.Params[0];
1782 
1783  lock (m_requestLock)
1784  {
1785  try
1786  {
1787  CheckStringParameters(requestData, responseData, new string[] {"filename"});
1788  CheckRegionParams(requestData, responseData);
1789 
1790  Scene scene = null;
1791  GetSceneFromRegionParams(requestData, responseData, out scene);
1792 
1793  string filename = (string) requestData["filename"];
1794 
1795  responseData["switched"] = true;
1796 
1797  string xml_version = "1";
1798  if (requestData.Contains("xml_version"))
1799  {
1800  xml_version = (string) requestData["xml_version"];
1801  }
1802 
1803  switch (xml_version)
1804  {
1805  case "1":
1806  m_application.SceneManager.LoadCurrentSceneFromXml(filename, true, new Vector3(0, 0, 0));
1807  break;
1808 
1809  case "2":
1810  m_application.SceneManager.LoadCurrentSceneFromXml2(filename);
1811  break;
1812 
1813  default:
1814  throw new Exception(String.Format("unknown Xml{0} format", xml_version));
1815  }
1816 
1817  responseData["loaded"] = true;
1818  }
1819  catch (Exception e)
1820  {
1821  responseData["loaded"] = false;
1822  responseData["switched"] = false;
1823 
1824  throw e;
1825  }
1826 
1827  m_log.Info("[RADMIN]: Load XML Administrator Request complete");
1828  }
1829  }
1830 
1831  private void XmlRpcSaveXMLMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1832  {
1833  m_log.Info("[RADMIN]: Received Save XML Administrator Request");
1834 
1835  Hashtable responseData = (Hashtable)response.Value;
1836  Hashtable requestData = (Hashtable)request.Params[0];
1837 
1838  try
1839  {
1840  CheckStringParameters(requestData, responseData, new string[] {"filename"});
1841  CheckRegionParams(requestData, responseData);
1842 
1843  Scene scene = null;
1844  GetSceneFromRegionParams(requestData, responseData, out scene);
1845 
1846  string filename = (string) requestData["filename"];
1847 
1848  responseData["switched"] = true;
1849 
1850  string xml_version = "1";
1851  if (requestData.Contains("xml_version"))
1852  {
1853  xml_version = (string) requestData["xml_version"];
1854  }
1855 
1856  switch (xml_version)
1857  {
1858  case "1":
1859  m_application.SceneManager.SaveCurrentSceneToXml(filename);
1860  break;
1861 
1862  case "2":
1863  m_application.SceneManager.SaveCurrentSceneToXml2(filename);
1864  break;
1865 
1866  default:
1867  throw new Exception(String.Format("unknown Xml{0} format", xml_version));
1868  }
1869 
1870  responseData["saved"] = true;
1871  }
1872  catch (Exception e)
1873  {
1874  responseData["saved"] = false;
1875  responseData["switched"] = false;
1876 
1877  throw e;
1878  }
1879 
1880  m_log.Info("[RADMIN]: Save XML Administrator Request complete");
1881  }
1882 
1883  private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1884  {
1885  Hashtable responseData = (Hashtable)response.Value;
1886  Hashtable requestData = (Hashtable)request.Params[0];
1887 
1888  int flags = 0;
1889  string text = String.Empty;
1890  int health = 0;
1891  responseData["success"] = true;
1892 
1893  CheckRegionParams(requestData, responseData);
1894 
1895  Scene scene = null;
1896  try
1897  {
1898  GetSceneFromRegionParams(requestData, responseData, out scene);
1899  health = scene.GetHealth(out flags, out text);
1900  }
1901  catch (Exception e)
1902  {
1903  responseData["error"] = null;
1904  }
1905 
1906  responseData["success"] = true;
1907  responseData["health"] = health;
1908  responseData["flags"] = flags;
1909  responseData["message"] = text;
1910  }
1911 
1912  private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1913  {
1914  m_log.Info("[RADMIN]: Received Command XML Administrator Request");
1915 
1916  Hashtable responseData = (Hashtable)response.Value;
1917  Hashtable requestData = (Hashtable)request.Params[0];
1918 
1919  CheckStringParameters(requestData, responseData, new string[] {"command"});
1920 
1921  MainConsole.Instance.RunCommand(requestData["command"].ToString());
1922 
1923  m_log.Info("[RADMIN]: Command XML Administrator Request complete");
1924  }
1925 
1926  private void XmlRpcAccessListClear(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1927  {
1928  m_log.Info("[RADMIN]: Received Access List Clear Request");
1929 
1930  Hashtable responseData = (Hashtable)response.Value;
1931  Hashtable requestData = (Hashtable)request.Params[0];
1932 
1933  responseData["success"] = true;
1934 
1935  CheckRegionParams(requestData, responseData);
1936 
1937  Scene scene = null;
1938  GetSceneFromRegionParams(requestData, responseData, out scene);
1939 
1940  scene.RegionInfo.EstateSettings.EstateAccess = new UUID[]{};
1941 
1942  if (scene.RegionInfo.Persistent)
1943  m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
1944 
1945  m_log.Info("[RADMIN]: Access List Clear Request complete");
1946  }
1947 
1948  private void XmlRpcAccessListAdd(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1949  {
1950  m_log.Info("[RADMIN]: Received Access List Add Request");
1951 
1952  Hashtable responseData = (Hashtable)response.Value;
1953  Hashtable requestData = (Hashtable)request.Params[0];
1954 
1955  CheckRegionParams(requestData, responseData);
1956 
1957  Scene scene = null;
1958  GetSceneFromRegionParams(requestData, responseData, out scene);
1959 
1960  int addedUsers = 0;
1961 
1962  if (requestData.Contains("users"))
1963  {
1964  UUID scopeID = scene.RegionInfo.ScopeID;
1965  IUserAccountService userService = scene.UserAccountService;
1966  Hashtable users = (Hashtable) requestData["users"];
1967  List<UUID> uuids = new List<UUID>();
1968  foreach (string name in users.Values)
1969  {
1970  string[] parts = name.Split();
1971  UserAccount account = userService.GetUserAccount(scopeID, parts[0], parts[1]);
1972  if (account != null)
1973  {
1974  uuids.Add(account.PrincipalID);
1975  m_log.DebugFormat("[RADMIN]: adding \"{0}\" to ACL for \"{1}\"", name, scene.RegionInfo.RegionName);
1976  }
1977  }
1978  List<UUID> accessControlList = new List<UUID>(scene.RegionInfo.EstateSettings.EstateAccess);
1979  foreach (UUID uuid in uuids)
1980  {
1981  if (!accessControlList.Contains(uuid))
1982  {
1983  accessControlList.Add(uuid);
1984  addedUsers++;
1985  }
1986  }
1987  scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray();
1988  if (scene.RegionInfo.Persistent)
1989  m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
1990  }
1991 
1992  responseData["added"] = addedUsers;
1993 
1994  m_log.Info("[RADMIN]: Access List Add Request complete");
1995  }
1996 
1997  private void XmlRpcAccessListRemove(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
1998  {
1999  m_log.Info("[RADMIN]: Received Access List Remove Request");
2000 
2001  Hashtable responseData = (Hashtable)response.Value;
2002  Hashtable requestData = (Hashtable)request.Params[0];
2003 
2004  CheckRegionParams(requestData, responseData);
2005 
2006  Scene scene = null;
2007  GetSceneFromRegionParams(requestData, responseData, out scene);
2008 
2009  int removedUsers = 0;
2010 
2011  if (requestData.Contains("users"))
2012  {
2013  UUID scopeID = scene.RegionInfo.ScopeID;
2014  IUserAccountService userService = scene.UserAccountService;
2015  //UserProfileCacheService ups = m_application.CommunicationsManager.UserProfileCacheService;
2016  Hashtable users = (Hashtable) requestData["users"];
2017  List<UUID> uuids = new List<UUID>();
2018  foreach (string name in users.Values)
2019  {
2020  string[] parts = name.Split();
2021  UserAccount account = userService.GetUserAccount(scopeID, parts[0], parts[1]);
2022  if (account != null)
2023  {
2024  uuids.Add(account.PrincipalID);
2025  }
2026  }
2027  List<UUID> accessControlList = new List<UUID>(scene.RegionInfo.EstateSettings.EstateAccess);
2028  foreach (UUID uuid in uuids)
2029  {
2030  if (accessControlList.Contains(uuid))
2031  {
2032  accessControlList.Remove(uuid);
2033  removedUsers++;
2034  }
2035  }
2036  scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray();
2037  if (scene.RegionInfo.Persistent)
2038  m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
2039  }
2040 
2041  responseData["removed"] = removedUsers;
2042  responseData["success"] = true;
2043 
2044  m_log.Info("[RADMIN]: Access List Remove Request complete");
2045  }
2046 
2047  private void XmlRpcAccessListList(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2048  {
2049  m_log.Info("[RADMIN]: Received Access List List Request");
2050 
2051  Hashtable responseData = (Hashtable)response.Value;
2052  Hashtable requestData = (Hashtable)request.Params[0];
2053 
2054  CheckRegionParams(requestData, responseData);
2055 
2056  Scene scene = null;
2057  GetSceneFromRegionParams(requestData, responseData, out scene);
2058 
2059  UUID[] accessControlList = scene.RegionInfo.EstateSettings.EstateAccess;
2060  Hashtable users = new Hashtable();
2061 
2062  foreach (UUID user in accessControlList)
2063  {
2064  UUID scopeID = scene.RegionInfo.ScopeID;
2065  UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, user);
2066  if (account != null)
2067  {
2068  users[user.ToString()] = account.FirstName + " " + account.LastName;
2069  }
2070  }
2071 
2072  responseData["users"] = users;
2073  responseData["success"] = true;
2074 
2075  m_log.Info("[RADMIN]: Access List List Request complete");
2076  }
2077 
2078  private void XmlRpcEstateReload(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2079  {
2080  m_log.Info("[RADMIN]: Received Estate Reload Request");
2081 
2082  Hashtable responseData = (Hashtable)response.Value;
2083 // Hashtable requestData = (Hashtable)request.Params[0];
2084 
2085  m_application.SceneManager.ForEachScene(s =>
2086  s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false)
2087  );
2088 
2089  responseData["success"] = true;
2090 
2091  m_log.Info("[RADMIN]: Estate Reload Request complete");
2092  }
2093 
2094  private void XmlRpcGetAgentsMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2095  {
2096  Hashtable responseData = (Hashtable)response.Value;
2097  Hashtable requestData = (Hashtable)request.Params[0];
2098 
2099  bool includeChildren = false;
2100 
2101  if (requestData.Contains("include_children"))
2102  bool.TryParse((string)requestData["include_children"], out includeChildren);
2103 
2104  Scene scene;
2105  GetSceneFromRegionParams(requestData, responseData, out scene);
2106 
2107  ArrayList xmlRpcRegions = new ArrayList();
2108  responseData["regions"] = xmlRpcRegions;
2109 
2110  Hashtable xmlRpcRegion = new Hashtable();
2111  xmlRpcRegions.Add(xmlRpcRegion);
2112 
2113  xmlRpcRegion["name"] = scene.Name;
2114  xmlRpcRegion["id"] = scene.RegionInfo.RegionID.ToString();
2115 
2116  List<ScenePresence> agents = scene.GetScenePresences();
2117  ArrayList xmlrpcAgents = new ArrayList();
2118 
2119  foreach (ScenePresence agent in agents)
2120  {
2121  if (agent.IsChildAgent && !includeChildren)
2122  continue;
2123 
2124  Hashtable xmlRpcAgent = new Hashtable();
2125  xmlRpcAgent.Add("name", agent.Name);
2126  xmlRpcAgent.Add("id", agent.UUID.ToString());
2127  xmlRpcAgent.Add("type", agent.PresenceType.ToString());
2128  xmlRpcAgent.Add("current_parcel_id", agent.currentParcelUUID.ToString());
2129 
2130  Vector3 pos = agent.AbsolutePosition;
2131  xmlRpcAgent.Add("pos_x", pos.X.ToString());
2132  xmlRpcAgent.Add("pos_y", pos.Y.ToString());
2133  xmlRpcAgent.Add("pos_z", pos.Z.ToString());
2134 
2135  Vector3 lookAt = agent.Lookat;
2136  xmlRpcAgent.Add("lookat_x", lookAt.X.ToString());
2137  xmlRpcAgent.Add("lookat_y", lookAt.Y.ToString());
2138  xmlRpcAgent.Add("lookat_z", lookAt.Z.ToString());
2139 
2140  Vector3 vel = agent.Velocity;
2141  xmlRpcAgent.Add("vel_x", vel.X.ToString());
2142  xmlRpcAgent.Add("vel_y", vel.Y.ToString());
2143  xmlRpcAgent.Add("vel_z", vel.Z.ToString());
2144 
2145  xmlRpcAgent.Add("is_flying", agent.Flying.ToString());
2146  xmlRpcAgent.Add("is_sat_on_ground", agent.SitGround.ToString());
2147  xmlRpcAgent.Add("is_sat_on_object", agent.IsSatOnObject.ToString());
2148 
2149  xmlrpcAgents.Add(xmlRpcAgent);
2150  }
2151 
2152  m_log.DebugFormat(
2153  "[REMOTE ADMIN]: XmlRpcGetAgents found {0} agents in {1}", xmlrpcAgents.Count, scene.Name);
2154 
2155  xmlRpcRegion["agents"] = xmlrpcAgents;
2156  responseData["success"] = true;
2157  }
2158 
2159  private void XmlRpcTeleportAgentMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2160  {
2161  Hashtable responseData = (Hashtable)response.Value;
2162  Hashtable requestData = (Hashtable)request.Params[0];
2163 
2164  UUID agentId;
2165  string regionName = null;
2166  Vector3 pos, lookAt;
2167  ScenePresence sp = null;
2168 
2169  if (requestData.Contains("agent_first_name") && requestData.Contains("agent_last_name"))
2170  {
2171  string firstName = requestData["agent_first_name"].ToString();
2172  string lastName = requestData["agent_last_name"].ToString();
2173  m_application.SceneManager.TryGetRootScenePresenceByName(firstName, lastName, out sp);
2174 
2175  if (sp == null)
2176  throw new Exception(
2177  string.Format(
2178  "No agent found with agent_first_name {0} and agent_last_name {1}", firstName, lastName));
2179  }
2180  else if (requestData.Contains("agent_id"))
2181  {
2182  string rawAgentId = (string)requestData["agent_id"];
2183 
2184  if (!UUID.TryParse(rawAgentId, out agentId))
2185  throw new Exception(string.Format("agent_id {0} does not have the correct id format", rawAgentId));
2186 
2187  m_application.SceneManager.TryGetRootScenePresence(agentId, out sp);
2188 
2189  if (sp == null)
2190  throw new Exception(string.Format("No agent with agent_id {0} found in this simulator", agentId));
2191  }
2192  else
2193  {
2194  throw new Exception("No agent_id or agent_first_name and agent_last_name parameters specified");
2195  }
2196 
2197  if (requestData.Contains("region_name"))
2198  regionName = (string)requestData["region_name"];
2199 
2200  pos.X = ParseFloat(requestData, "pos_x", sp.AbsolutePosition.X);
2201  pos.Y = ParseFloat(requestData, "pos_y", sp.AbsolutePosition.Y);
2202  pos.Z = ParseFloat(requestData, "pos_z", sp.AbsolutePosition.Z);
2203  lookAt.X = ParseFloat(requestData, "lookat_x", sp.Lookat.X);
2204  lookAt.Y = ParseFloat(requestData, "lookat_y", sp.Lookat.Y);
2205  lookAt.Z = ParseFloat(requestData, "lookat_z", sp.Lookat.Z);
2206 
2207  sp.Scene.RequestTeleportLocation(
2208  sp.ControllingClient, regionName, pos, lookAt, (uint)Constants.TeleportFlags.ViaLocation);
2209 
2210  // We have no way of telling the failure of the actual teleport
2211  responseData["success"] = true;
2212  }
2213 
2214  private void XmlRpcResetLand(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2215  {
2216  Hashtable requestData = (Hashtable)request.Params[0];
2217  Hashtable responseData = (Hashtable)response.Value;
2218  string musicURL = string.Empty;
2219  UUID groupID = UUID.Zero;
2220  uint flags = 0;
2221  bool set_group = false, set_music = false, set_flags = false;
2222 
2223  if (requestData.Contains("group") && requestData["group"] != null)
2224  set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
2225  if (requestData.Contains("music") && requestData["music"] != null)
2226  {
2227 
2228  musicURL = requestData["music"].ToString();
2229  set_music = true;
2230  }
2231 
2232  if (requestData.Contains("flags") && requestData["flags"] != null)
2233  set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
2234 
2235  m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
2236  (set_group ? groupID.ToString() : "unchanged"),
2237  (set_music ? musicURL : "unchanged"),
2238  (set_flags ? flags.ToString() : "unchanged"));
2239 
2240  m_application.SceneManager.ForEachScene(delegate (Scene s)
2241  {
2242  List<ILandObject> parcels = s.LandChannel.AllParcels();
2243  foreach (ILandObject p in parcels)
2244  {
2245  if (set_music)
2246  p.LandData.MusicURL = musicURL;
2247  if (set_group)
2248  p.LandData.GroupID = groupID;
2249  if (set_flags)
2250  p.LandData.Flags = flags;
2251  s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
2252  }
2253  }
2254  );
2255  responseData["success"] = true;
2256  m_log.Info("[RADMIN]: Reset Land Request complete");
2257  }
2258 
2259  private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2260  {
2261  m_log.Info("[RADMIN]: Received Refresh Search Request");
2262 
2263  Hashtable responseData = (Hashtable)response.Value;
2264  Hashtable requestData = (Hashtable)request.Params[0];
2265 
2266  CheckRegionParams(requestData, responseData);
2267 
2268  Scene scene = null;
2269  GetSceneFromRegionParams(requestData, responseData, out scene);
2270 
2271  ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
2272  if (searchModule != null)
2273  {
2274  searchModule.Refresh();
2275  responseData["success"] = true;
2276  }
2277  else
2278  {
2279  responseData["success"] = false;
2280  }
2281 
2282  m_log.Info("[RADMIN]: Refresh Search Request complete");
2283  }
2284 
2285  private void XmlRpcRefreshMap(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2286  {
2287  m_log.Info("[RADMIN]: Received Refresh Map Request");
2288 
2289  Hashtable responseData = (Hashtable)response.Value;
2290  Hashtable requestData = (Hashtable)request.Params[0];
2291 
2292  CheckRegionParams(requestData, responseData);
2293 
2294  Scene scene = null;
2295  GetSceneFromRegionParams(requestData, responseData, out scene);
2296 
2297  IMapImageUploadModule mapTileModule = scene.RequestModuleInterface<IMapImageUploadModule>();
2298  if (mapTileModule != null)
2299  {
2300  Util.FireAndForget((x) =>
2301  {
2302  mapTileModule.UploadMapTile(scene);
2303  });
2304  responseData["success"] = true;
2305  }
2306  else
2307  {
2308  responseData["success"] = false;
2309  }
2310 
2311  m_log.Info("[RADMIN]: Refresh Map Request complete");
2312  }
2313 
2314  private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2315  {
2316  m_log.Info("[RADMIN]: Received Get OpenSim Version Request");
2317 
2318  Hashtable responseData = (Hashtable)response.Value;
2319 
2320  responseData["version"] = m_openSimVersion;
2321  responseData["success"] = true;
2322 
2323  m_log.Info("[RADMIN]: Get OpenSim Version Request complete");
2324  }
2325 
2326  private void XmlRpcGetAgentCount(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
2327  {
2328  m_log.Info("[RADMIN]: Received Get Agent Count Request");
2329 
2330  Hashtable responseData = (Hashtable)response.Value;
2331  Hashtable requestData = (Hashtable)request.Params[0];
2332 
2333  CheckRegionParams(requestData, responseData);
2334 
2335  Scene scene = null;
2336  GetSceneFromRegionParams(requestData, responseData, out scene);
2337 
2338  if (scene == null)
2339  {
2340  responseData["success"] = false;
2341  }
2342  else
2343  {
2344  responseData["count"] = scene.GetRootAgentCount();
2345  responseData["success"] = true;
2346  }
2347 
2348  m_log.Info("[RADMIN]: Get Agent Count Request complete");
2349  }
2350 
2362  private static float ParseFloat(Hashtable requestData, string paramName, float defaultVal)
2363  {
2364  if (requestData.Contains(paramName))
2365  {
2366  string rawVal = (string)requestData[paramName];
2367  float val;
2368 
2369  if (!float.TryParse(rawVal, out val))
2370  throw new Exception(string.Format("{0} {1} is not a valid float", paramName, rawVal));
2371  else
2372  return val;
2373  }
2374  else
2375  {
2376  return defaultVal;
2377  }
2378  }
2379 
2380  private static void CheckStringParameters(Hashtable requestData, Hashtable responseData, string[] param)
2381  {
2382  foreach (string parameter in param)
2383  {
2384  if (!requestData.Contains(parameter))
2385  {
2386  responseData["accepted"] = false;
2387  throw new Exception(String.Format("missing string parameter {0}", parameter));
2388  }
2389  if (String.IsNullOrEmpty((string) requestData[parameter]))
2390  {
2391  responseData["accepted"] = false;
2392  throw new Exception(String.Format("parameter {0} is empty", parameter));
2393  }
2394  }
2395  }
2396 
2397  private static void CheckIntegerParams(Hashtable requestData, Hashtable responseData, string[] param)
2398  {
2399  foreach (string parameter in param)
2400  {
2401  if (!requestData.Contains(parameter))
2402  {
2403  responseData["accepted"] = false;
2404  throw new Exception(String.Format("missing integer parameter {0}", parameter));
2405  }
2406  }
2407  }
2408 
2409  private void CheckRegionParams(Hashtable requestData, Hashtable responseData)
2410  {
2411  //Checks if region parameters exist and gives exeption if no parameters are given
2412  if ((requestData.ContainsKey("region_id") && !String.IsNullOrEmpty((string)requestData["region_id"])) ||
2413  (requestData.ContainsKey("region_name") && !String.IsNullOrEmpty((string)requestData["region_name"])))
2414  {
2415  return;
2416  }
2417  else
2418  {
2419  responseData["accepted"] = false;
2420  throw new Exception("no region_name or region_id given");
2421  }
2422  }
2423 
2424  private void GetSceneFromRegionParams(Hashtable requestData, Hashtable responseData, out Scene scene)
2425  {
2426  scene = null;
2427 
2428  if (requestData.ContainsKey("region_id") &&
2429  !String.IsNullOrEmpty((string)requestData["region_id"]))
2430  {
2431  UUID regionID = (UUID)(string)requestData["region_id"];
2432  if (!m_application.SceneManager.TryGetScene(regionID, out scene))
2433  {
2434  responseData["error"] = String.Format("Region ID {0} not found", regionID);
2435  throw new Exception(String.Format("Region ID {0} not found", regionID));
2436  }
2437  }
2438  else if (requestData.ContainsKey("region_name") &&
2439  !String.IsNullOrEmpty((string)requestData["region_name"]))
2440  {
2441  string regionName = (string)requestData["region_name"];
2442  if (!m_application.SceneManager.TryGetScene(regionName, out scene))
2443  {
2444  responseData["error"] = String.Format("Region {0} not found", regionName);
2445  throw new Exception(String.Format("Region {0} not found", regionName));
2446  }
2447  }
2448  else
2449  {
2450  responseData["error"] = "no region_name or region_id given";
2451  throw new Exception("no region_name or region_id given");
2452  }
2453  return;
2454  }
2455 
2456  private bool GetBoolean(Hashtable requestData, string tag, bool defaultValue)
2457  {
2458  // If an access value has been provided, apply it.
2459  if (requestData.Contains(tag))
2460  {
2461  switch (((string)requestData[tag]).ToLower())
2462  {
2463  case "true" :
2464  case "t" :
2465  case "1" :
2466  return true;
2467  case "false" :
2468  case "f" :
2469  case "0" :
2470  return false;
2471  default :
2472  return defaultValue;
2473  }
2474  }
2475  else
2476  return defaultValue;
2477  }
2478 
2479  private int GetIntegerAttribute(XmlNode node, string attribute, int defaultValue)
2480  {
2481  try { return Convert.ToInt32(node.Attributes[attribute].Value); } catch{}
2482  return defaultValue;
2483  }
2484 
2485  private uint GetUnsignedAttribute(XmlNode node, string attribute, uint defaultValue)
2486  {
2487  try { return Convert.ToUInt32(node.Attributes[attribute].Value); } catch{}
2488  return defaultValue;
2489  }
2490 
2491  private string GetStringAttribute(XmlNode node, string attribute, string defaultValue)
2492  {
2493  try { return node.Attributes[attribute].Value; } catch{}
2494  return defaultValue;
2495  }
2496 
2497  public void Dispose()
2498  {
2499  }
2500 
2509  private UserAccount CreateUser(UUID scopeID, string firstName, string lastName, string password, string email)
2510  {
2511  Scene scene = m_application.SceneManager.CurrentOrFirstScene;
2512  IUserAccountService userAccountService = scene.UserAccountService;
2513  IGridService gridService = scene.GridService;
2514  IAuthenticationService authenticationService = scene.AuthenticationService;
2515  IGridUserService gridUserService = scene.GridUserService;
2516  IInventoryService inventoryService = scene.InventoryService;
2517 
2518  UserAccount account = userAccountService.GetUserAccount(scopeID, firstName, lastName);
2519  if (null == account)
2520  {
2521  account = new UserAccount(scopeID, UUID.Random(), firstName, lastName, email);
2522  if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0))
2523  {
2524  account.ServiceURLs = new Dictionary<string, object>();
2525  account.ServiceURLs["HomeURI"] = string.Empty;
2526  account.ServiceURLs["InventoryServerURI"] = string.Empty;
2527  account.ServiceURLs["AssetServerURI"] = string.Empty;
2528  }
2529 
2530  if (userAccountService.StoreUserAccount(account))
2531  {
2532  bool success;
2533  if (authenticationService != null)
2534  {
2535  success = authenticationService.SetPassword(account.PrincipalID, password);
2536  if (!success)
2537  m_log.WarnFormat("[RADMIN]: Unable to set password for account {0} {1}.",
2538  firstName, lastName);
2539  }
2540 
2541  GridRegion home = null;
2542  if (gridService != null)
2543  {
2544  List<GridRegion> defaultRegions = gridService.GetDefaultRegions(UUID.Zero);
2545  if (defaultRegions != null && defaultRegions.Count >= 1)
2546  home = defaultRegions[0];
2547 
2548  if (gridUserService != null && home != null)
2549  gridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
2550  else
2551  m_log.WarnFormat("[RADMIN]: Unable to set home for account {0} {1}.",
2552  firstName, lastName);
2553  }
2554  else
2555  m_log.WarnFormat("[RADMIN]: Unable to retrieve home region for account {0} {1}.",
2556  firstName, lastName);
2557 
2558  if (inventoryService != null)
2559  {
2560  success = inventoryService.CreateUserInventory(account.PrincipalID);
2561  if (!success)
2562  m_log.WarnFormat("[RADMIN]: Unable to create inventory for account {0} {1}.",
2563  firstName, lastName);
2564  }
2565 
2566  m_log.InfoFormat("[RADMIN]: Account {0} {1} created successfully", firstName, lastName);
2567  return account;
2568  } else {
2569  m_log.ErrorFormat("[RADMIN]: Account creation failed for account {0} {1}", firstName, lastName);
2570  }
2571  }
2572  else
2573  {
2574  m_log.ErrorFormat("[RADMIN]: A user with the name {0} {1} already exists!", firstName, lastName);
2575  }
2576  return null;
2577  }
2578 
2585  private bool ChangeUserPassword(string firstName, string lastName, string password)
2586  {
2587  Scene scene = m_application.SceneManager.CurrentOrFirstScene;
2588  IUserAccountService userAccountService = scene.UserAccountService;
2589  IAuthenticationService authenticationService = scene.AuthenticationService;
2590 
2591  UserAccount account = userAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
2592  if (null != account)
2593  {
2594  bool success = false;
2595  if (authenticationService != null)
2596  success = authenticationService.SetPassword(account.PrincipalID, password);
2597 
2598  if (!success)
2599  {
2600  m_log.WarnFormat("[RADMIN]: Unable to set password for account {0} {1}.",
2601  firstName, lastName);
2602  return false;
2603  }
2604  return true;
2605  }
2606  else
2607  {
2608  m_log.ErrorFormat("[RADMIN]: No such user");
2609  return false;
2610  }
2611  }
2612 
2613  private bool LoadHeightmap(string file, UUID regionID)
2614  {
2615  m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file);
2616 
2617  Scene region = null;
2618 
2619  if (!m_application.SceneManager.TryGetScene(regionID, out region))
2620  {
2621  m_log.InfoFormat("[RADMIN]: unable to get a scene with that name: {0}", regionID.ToString());
2622  return false;
2623  }
2624 
2625  ITerrainModule terrainModule = region.RequestModuleInterface<ITerrainModule>();
2626  if (null == terrainModule) throw new Exception("terrain module not available");
2627  if (Uri.IsWellFormedUriString(file, UriKind.Absolute))
2628  {
2629  m_log.Info("[RADMIN]: Terrain path is URL");
2630  Uri result;
2631  if (Uri.TryCreate(file, UriKind.RelativeOrAbsolute, out result))
2632  {
2633  // the url is valid
2634  string fileType = file.Substring(file.LastIndexOf('/') + 1);
2635  terrainModule.LoadFromStream(fileType, result);
2636  }
2637  }
2638  else
2639  {
2640  terrainModule.LoadFromFile(file);
2641  }
2642 
2643  m_log.Info("[RADMIN]: Load height maps request complete");
2644 
2645  return true;
2646  }
2647 
2648 
2656  private void UpdateUserAppearance(Hashtable responseData, Hashtable requestData, UUID userid)
2657  {
2658  m_log.DebugFormat("[RADMIN]: updateUserAppearance");
2659 
2660  string defaultMale = m_config.GetString("default_male", "Default Male");
2661  string defaultFemale = m_config.GetString("default_female", "Default Female");
2662  string defaultNeutral = m_config.GetString("default_female", "Default Default");
2663  string model = String.Empty;
2664 
2665  // Has a gender preference been supplied?
2666 
2667  if (requestData.Contains("gender"))
2668  {
2669  switch ((string)requestData["gender"])
2670  {
2671  case "m" :
2672  case "male" :
2673  model = defaultMale;
2674  break;
2675  case "f" :
2676  case "female" :
2677  model = defaultFemale;
2678  break;
2679  case "n" :
2680  case "neutral" :
2681  default :
2682  model = defaultNeutral;
2683  break;
2684  }
2685  }
2686 
2687  // Has an explicit model been specified?
2688 
2689  if (requestData.Contains("model") && (String.IsNullOrEmpty((string)requestData["gender"])))
2690  {
2691  model = (string)requestData["model"];
2692  }
2693 
2694  // No appearance attributes were set
2695 
2696  if (String.IsNullOrEmpty(model))
2697  {
2698  m_log.DebugFormat("[RADMIN]: Appearance update not requested");
2699  return;
2700  }
2701 
2702  m_log.DebugFormat("[RADMIN]: Setting appearance for avatar {0}, using model <{1}>", userid, model);
2703 
2704  string[] modelSpecifiers = model.Split();
2705  if (modelSpecifiers.Length != 2)
2706  {
2707  m_log.WarnFormat("[RADMIN]: User appearance not set for {0}. Invalid model name : <{1}>", userid, model);
2708  // modelSpecifiers = dmodel.Split();
2709  return;
2710  }
2711 
2712  Scene scene = m_application.SceneManager.CurrentOrFirstScene;
2713  UUID scopeID = scene.RegionInfo.ScopeID;
2714  UserAccount modelProfile = scene.UserAccountService.GetUserAccount(scopeID, modelSpecifiers[0], modelSpecifiers[1]);
2715 
2716  if (modelProfile == null)
2717  {
2718  m_log.WarnFormat("[RADMIN]: Requested model ({0}) not found. Appearance unchanged", model);
2719  return;
2720  }
2721 
2722  // Set current user's appearance. This bit is easy. The appearance structure is populated with
2723  // actual asset ids, however to complete the magic we need to populate the inventory with the
2724  // assets in question.
2725 
2726  EstablishAppearance(userid, modelProfile.PrincipalID);
2727 
2728  m_log.DebugFormat("[RADMIN]: Finished setting appearance for avatar {0}, using model {1}",
2729  userid, model);
2730  }
2731 
2737  private void EstablishAppearance(UUID destination, UUID source)
2738  {
2739  m_log.DebugFormat("[RADMIN]: Initializing inventory for {0} from {1}", destination, source);
2740  Scene scene = m_application.SceneManager.CurrentOrFirstScene;
2741 
2742  // If the model has no associated appearance we're done.
2743  AvatarAppearance avatarAppearance = scene.AvatarService.GetAppearance(source);
2744  if (avatarAppearance == null)
2745  return;
2746 
2747  // Simple appearance copy or copy Clothing and Bodyparts folders?
2748  bool copyFolders = m_config.GetBoolean("copy_folders", false);
2749 
2750  if (!copyFolders)
2751  {
2752  // Simple copy of wearables and appearance update
2753  try
2754  {
2755  CopyWearablesAndAttachments(destination, source, avatarAppearance);
2756 
2757  scene.AvatarService.SetAppearance(destination, avatarAppearance);
2758  }
2759  catch (Exception e)
2760  {
2761  m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}",
2762  destination, e.Message);
2763  }
2764 
2765  return;
2766  }
2767 
2768  // Copy Clothing and Bodypart folders and appearance update
2769  try
2770  {
2771  Dictionary<UUID,UUID> inventoryMap = new Dictionary<UUID,UUID>();
2772  CopyInventoryFolders(destination, source, FolderType.Clothing, inventoryMap, avatarAppearance);
2773  CopyInventoryFolders(destination, source, FolderType.BodyPart, inventoryMap, avatarAppearance);
2774 
2775  AvatarWearable[] wearables = avatarAppearance.Wearables;
2776 
2777  for (int i=0; i<wearables.Length; i++)
2778  {
2779  if (inventoryMap.ContainsKey(wearables[i][0].ItemID))
2780  {
2781  AvatarWearable wearable = new AvatarWearable();
2782  wearable.Wear(inventoryMap[wearables[i][0].ItemID],
2783  wearables[i][0].AssetID);
2784  avatarAppearance.SetWearable(i, wearable);
2785  }
2786  }
2787 
2788  scene.AvatarService.SetAppearance(destination, avatarAppearance);
2789  }
2790  catch (Exception e)
2791  {
2792  m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}",
2793  destination, e.Message);
2794  }
2795 
2796  return;
2797  }
2798 
2804  private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance)
2805  {
2806  IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
2807 
2808  // Get Clothing folder of receiver
2809  InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, FolderType.Clothing);
2810 
2811  if (destinationFolder == null)
2812  throw new Exception("Cannot locate folder(s)");
2813 
2814  // Missing destination folder? This should *never* be the case
2815  if (destinationFolder.Type != (short)FolderType.Clothing)
2816  {
2817  destinationFolder = new InventoryFolderBase();
2818 
2819  destinationFolder.ID = UUID.Random();
2820  destinationFolder.Name = "Clothing";
2821  destinationFolder.Owner = destination;
2822  destinationFolder.Type = (short)FolderType.Clothing;
2823  destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID;
2824  destinationFolder.Version = 1;
2825  inventoryService.AddFolder(destinationFolder); // store base record
2826  m_log.ErrorFormat("[RADMIN]: Created folder for destination {0}", source);
2827  }
2828 
2829  // Wearables
2830  AvatarWearable[] wearables = avatarAppearance.Wearables;
2831  AvatarWearable wearable;
2832 
2833  for (int i = 0; i<wearables.Length; i++)
2834  {
2835  wearable = wearables[i];
2836  if (wearable[0].ItemID != UUID.Zero)
2837  {
2838  // Get inventory item and copy it
2839  InventoryItemBase item = new InventoryItemBase(wearable[0].ItemID, source);
2840  item = inventoryService.GetItem(item);
2841 
2842  if (item != null)
2843  {
2844  InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
2845  destinationItem.Name = item.Name;
2846  destinationItem.Owner = destination;
2847  destinationItem.Description = item.Description;
2848  destinationItem.InvType = item.InvType;
2849  destinationItem.CreatorId = item.CreatorId;
2850  destinationItem.CreatorData = item.CreatorData;
2851  destinationItem.NextPermissions = item.NextPermissions;
2852  destinationItem.CurrentPermissions = item.CurrentPermissions;
2853  destinationItem.BasePermissions = item.BasePermissions;
2854  destinationItem.EveryOnePermissions = item.EveryOnePermissions;
2855  destinationItem.GroupPermissions = item.GroupPermissions;
2856  destinationItem.AssetType = item.AssetType;
2857  destinationItem.AssetID = item.AssetID;
2858  destinationItem.GroupID = item.GroupID;
2859  destinationItem.GroupOwned = item.GroupOwned;
2860  destinationItem.SalePrice = item.SalePrice;
2861  destinationItem.SaleType = item.SaleType;
2862  destinationItem.Flags = item.Flags;
2863  destinationItem.CreationDate = item.CreationDate;
2864  destinationItem.Folder = destinationFolder.ID;
2865  ApplyNextOwnerPermissions(destinationItem);
2866 
2867  m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem);
2868  m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);
2869 
2870  // Wear item
2871  AvatarWearable newWearable = new AvatarWearable();
2872  newWearable.Wear(destinationItem.ID, wearable[0].AssetID);
2873  avatarAppearance.SetWearable(i, newWearable);
2874  }
2875  else
2876  {
2877  m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", wearable[0].ItemID, destinationFolder.ID);
2878  }
2879  }
2880  }
2881 
2882  // Attachments
2883  List<AvatarAttachment> attachments = avatarAppearance.GetAttachments();
2884 
2885  foreach (AvatarAttachment attachment in attachments)
2886  {
2887  int attachpoint = attachment.AttachPoint;
2888  UUID itemID = attachment.ItemID;
2889 
2890  if (itemID != UUID.Zero)
2891  {
2892  // Get inventory item and copy it
2893  InventoryItemBase item = new InventoryItemBase(itemID, source);
2894  item = inventoryService.GetItem(item);
2895 
2896  if (item != null)
2897  {
2898  InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
2899  destinationItem.Name = item.Name;
2900  destinationItem.Owner = destination;
2901  destinationItem.Description = item.Description;
2902  destinationItem.InvType = item.InvType;
2903  destinationItem.CreatorId = item.CreatorId;
2904  destinationItem.CreatorData = item.CreatorData;
2905  destinationItem.NextPermissions = item.NextPermissions;
2906  destinationItem.CurrentPermissions = item.CurrentPermissions;
2907  destinationItem.BasePermissions = item.BasePermissions;
2908  destinationItem.EveryOnePermissions = item.EveryOnePermissions;
2909  destinationItem.GroupPermissions = item.GroupPermissions;
2910  destinationItem.AssetType = item.AssetType;
2911  destinationItem.AssetID = item.AssetID;
2912  destinationItem.GroupID = item.GroupID;
2913  destinationItem.GroupOwned = item.GroupOwned;
2914  destinationItem.SalePrice = item.SalePrice;
2915  destinationItem.SaleType = item.SaleType;
2916  destinationItem.Flags = item.Flags;
2917  destinationItem.CreationDate = item.CreationDate;
2918  destinationItem.Folder = destinationFolder.ID;
2919  ApplyNextOwnerPermissions(destinationItem);
2920 
2921  m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem);
2922  m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);
2923 
2924  // Attach item
2925  avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID);
2926  m_log.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID);
2927  }
2928  else
2929  {
2930  m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID);
2931  }
2932  }
2933  }
2934  }
2935 
2940  private void CopyInventoryFolders(UUID destination, UUID source, FolderType assetType, Dictionary<UUID, UUID> inventoryMap,
2941  AvatarAppearance avatarAppearance)
2942  {
2943  IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
2944 
2945  InventoryFolderBase sourceFolder = inventoryService.GetFolderForType(source, assetType);
2946  InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, assetType);
2947 
2948  if (sourceFolder == null || destinationFolder == null)
2949  throw new Exception("Cannot locate folder(s)");
2950 
2951  // Missing source folder? This should *never* be the case
2952  if (sourceFolder.Type != (short)assetType)
2953  {
2954  sourceFolder = new InventoryFolderBase();
2955  sourceFolder.ID = UUID.Random();
2956  if (assetType == FolderType.Clothing)
2957  {
2958  sourceFolder.Name = "Clothing";
2959  }
2960  else
2961  {
2962  sourceFolder.Name = "Body Parts";
2963  }
2964  sourceFolder.Owner = source;
2965  sourceFolder.Type = (short)assetType;
2966  sourceFolder.ParentID = inventoryService.GetRootFolder(source).ID;
2967  sourceFolder.Version = 1;
2968  inventoryService.AddFolder(sourceFolder); // store base record
2969  m_log.ErrorFormat("[RADMIN] Created folder for source {0}", source);
2970  }
2971 
2972  // Missing destination folder? This should *never* be the case
2973  if (destinationFolder.Type != (short)assetType)
2974  {
2975  destinationFolder = new InventoryFolderBase();
2976  destinationFolder.ID = UUID.Random();
2977  if (assetType == FolderType.Clothing)
2978  {
2979  destinationFolder.Name = "Clothing";
2980  }
2981  else
2982  {
2983  destinationFolder.Name = "Body Parts";
2984  }
2985  destinationFolder.Owner = destination;
2986  destinationFolder.Type = (short)assetType;
2987  destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID;
2988  destinationFolder.Version = 1;
2989  inventoryService.AddFolder(destinationFolder); // store base record
2990  m_log.ErrorFormat("[RADMIN]: Created folder for destination {0}", source);
2991  }
2992 
2993  InventoryFolderBase extraFolder;
2994  List<InventoryFolderBase> folders = inventoryService.GetFolderContent(source, sourceFolder.ID).Folders;
2995 
2996  foreach (InventoryFolderBase folder in folders)
2997  {
2998  extraFolder = new InventoryFolderBase();
2999  extraFolder.ID = UUID.Random();
3000  extraFolder.Name = folder.Name;
3001  extraFolder.Owner = destination;
3002  extraFolder.Type = folder.Type;
3003  extraFolder.Version = folder.Version;
3004  extraFolder.ParentID = destinationFolder.ID;
3005  inventoryService.AddFolder(extraFolder);
3006 
3007  m_log.DebugFormat("[RADMIN]: Added folder {0} to folder {1}", extraFolder.ID, sourceFolder.ID);
3008 
3009  List<InventoryItemBase> items = inventoryService.GetFolderContent(source, folder.ID).Items;
3010 
3011  foreach (InventoryItemBase item in items)
3012  {
3013  InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
3014  destinationItem.Name = item.Name;
3015  destinationItem.Owner = destination;
3016  destinationItem.Description = item.Description;
3017  destinationItem.InvType = item.InvType;
3018  destinationItem.CreatorId = item.CreatorId;
3019  destinationItem.CreatorData = item.CreatorData;
3020  destinationItem.NextPermissions = item.NextPermissions;
3021  destinationItem.CurrentPermissions = item.CurrentPermissions;
3022  destinationItem.BasePermissions = item.BasePermissions;
3023  destinationItem.EveryOnePermissions = item.EveryOnePermissions;
3024  destinationItem.GroupPermissions = item.GroupPermissions;
3025  destinationItem.AssetType = item.AssetType;
3026  destinationItem.AssetID = item.AssetID;
3027  destinationItem.GroupID = item.GroupID;
3028  destinationItem.GroupOwned = item.GroupOwned;
3029  destinationItem.SalePrice = item.SalePrice;
3030  destinationItem.SaleType = item.SaleType;
3031  destinationItem.Flags = item.Flags;
3032  destinationItem.CreationDate = item.CreationDate;
3033  destinationItem.Folder = extraFolder.ID;
3034  ApplyNextOwnerPermissions(destinationItem);
3035 
3036  m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem);
3037  inventoryMap.Add(item.ID, destinationItem.ID);
3038  m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, extraFolder.ID);
3039 
3040  // Attach item, if original is attached
3041  int attachpoint = avatarAppearance.GetAttachpoint(item.ID);
3042  if (attachpoint != 0)
3043  {
3044  avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID);
3045  m_log.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID);
3046  }
3047  }
3048  }
3049  }
3050 
3054  private void ApplyNextOwnerPermissions(InventoryItemBase item)
3055  {
3056  if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
3057  {
3058  uint perms = item.CurrentPermissions;
3059  PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);
3060  item.CurrentPermissions = perms;
3061  }
3062 
3063  item.CurrentPermissions &= item.NextPermissions;
3064  item.BasePermissions &= item.NextPermissions;
3065  item.EveryOnePermissions &= item.NextPermissions;
3066  // item.OwnerChanged = true;
3067  // item.PermsMask = 0;
3068  // item.PermsGranter = UUID.Zero;
3069  }
3070 
3080  private bool CreateDefaultAvatars()
3081  {
3082  // Only load once
3083  if (m_defaultAvatarsLoaded)
3084  {
3085  return false;
3086  }
3087 
3088  m_log.DebugFormat("[RADMIN]: Creating default avatar entries");
3089 
3090  m_defaultAvatarsLoaded = true;
3091 
3092  // Load processing starts here...
3093 
3094  try
3095  {
3096  string defaultAppearanceFileName = null;
3097 
3098  //m_config may be null if RemoteAdmin configuration secition is missing or disabled in OpenSim.ini
3099  if (m_config != null)
3100  {
3101  defaultAppearanceFileName = m_config.GetString("default_appearance", "default_appearance.xml");
3102  }
3103 
3104  if (File.Exists(defaultAppearanceFileName))
3105  {
3106  XmlDocument doc = new XmlDocument();
3107  string name = "*unknown*";
3108  string email = "anon@anon";
3109  uint regionXLocation = 1000;
3110  uint regionYLocation = 1000;
3111  string password = UUID.Random().ToString(); // No requirement to sign-in.
3112  UUID ID = UUID.Zero;
3113  AvatarAppearance avatarAppearance;
3114  XmlNodeList avatars;
3115  XmlNodeList assets;
3116  XmlNode perms = null;
3117  bool include = false;
3118  bool select = false;
3119 
3120  Scene scene = m_application.SceneManager.CurrentOrFirstScene;
3121  IInventoryService inventoryService = scene.InventoryService;
3122  IAssetService assetService = scene.AssetService;
3123 
3124  doc.LoadXml(File.ReadAllText(defaultAppearanceFileName));
3125 
3126  // Load up any included assets. Duplicates will be ignored
3127  assets = doc.GetElementsByTagName("RequiredAsset");
3128  foreach (XmlNode assetNode in assets)
3129  {
3130  AssetBase asset = new AssetBase(UUID.Random(), GetStringAttribute(assetNode, "name", ""), SByte.Parse(GetStringAttribute(assetNode, "type", "")), UUID.Zero.ToString());
3131  asset.Description = GetStringAttribute(assetNode,"desc","");
3132  asset.Local = Boolean.Parse(GetStringAttribute(assetNode,"local",""));
3133  asset.Temporary = Boolean.Parse(GetStringAttribute(assetNode,"temporary",""));
3134  asset.Data = Convert.FromBase64String(assetNode.InnerText);
3135  assetService.Store(asset);
3136  }
3137 
3138  avatars = doc.GetElementsByTagName("Avatar");
3139 
3140  // The document may contain multiple avatars
3141 
3142  foreach (XmlElement avatar in avatars)
3143  {
3144  m_log.DebugFormat("[RADMIN]: Loading appearance for {0}, gender = {1}",
3145  GetStringAttribute(avatar,"name","?"), GetStringAttribute(avatar,"gender","?"));
3146 
3147  // Create the user identified by the avatar entry
3148 
3149  try
3150  {
3151  // Only the name value is mandatory
3152  name = GetStringAttribute(avatar,"name",name);
3153  email = GetStringAttribute(avatar,"email",email);
3154  regionXLocation = GetUnsignedAttribute(avatar,"regx",regionXLocation);
3155  regionYLocation = GetUnsignedAttribute(avatar,"regy",regionYLocation);
3156  password = GetStringAttribute(avatar,"password",password);
3157 
3158  string[] names = name.Split();
3159  UUID scopeID = scene.RegionInfo.ScopeID;
3160  UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, names[0], names[1]);
3161  if (null == account)
3162  {
3163  account = CreateUser(scopeID, names[0], names[1], password, email);
3164  if (null == account)
3165  {
3166  m_log.ErrorFormat("[RADMIN]: Avatar {0} {1} was not created", names[0], names[1]);
3167  return false;
3168  }
3169  }
3170 
3171  // Set home position
3172 
3173  GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
3174  (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
3175  if (null == home) {
3176  m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);
3177  } else {
3178  scene.GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
3179  m_log.DebugFormat("[RADMIN]: Set home region {0} for updated user account {1} {2}", home.RegionID, names[0], names[1]);
3180  }
3181 
3182  ID = account.PrincipalID;
3183 
3184  m_log.DebugFormat("[RADMIN]: User {0}[{1}] created or retrieved", name, ID);
3185  include = true;
3186  }
3187  catch (Exception e)
3188  {
3189  m_log.DebugFormat("[RADMIN]: Error creating user {0} : {1}", name, e.Message);
3190  include = false;
3191  }
3192 
3193  // OK, User has been created OK, now we can install the inventory.
3194  // First retrieve the current inventory (the user may already exist)
3195  // Note that althought he inventory is retrieved, the hierarchy has
3196  // not been interpreted at all.
3197 
3198  if (include)
3199  {
3200  // Setup for appearance processing
3201  avatarAppearance = scene.AvatarService.GetAppearance(ID);
3202  if (avatarAppearance == null)
3203  avatarAppearance = new AvatarAppearance();
3204 
3205  AvatarWearable[] wearables = avatarAppearance.Wearables;
3206  for (int i=0; i<wearables.Length; i++)
3207  {
3208  wearables[i] = new AvatarWearable();
3209  }
3210 
3211  try
3212  {
3213  // m_log.DebugFormat("[RADMIN] {0} folders, {1} items in inventory",
3214  // uic.folders.Count, uic.items.Count);
3215 
3216  InventoryFolderBase clothingFolder = inventoryService.GetFolderForType(ID, FolderType.Clothing);
3217 
3218  // This should *never* be the case
3219  if (clothingFolder == null || clothingFolder.Type != (short)FolderType.Clothing)
3220  {
3221  clothingFolder = new InventoryFolderBase();
3222  clothingFolder.ID = UUID.Random();
3223  clothingFolder.Name = "Clothing";
3224  clothingFolder.Owner = ID;
3225  clothingFolder.Type = (short)FolderType.Clothing;
3226  clothingFolder.ParentID = inventoryService.GetRootFolder(ID).ID;
3227  clothingFolder.Version = 1;
3228  inventoryService.AddFolder(clothingFolder); // store base record
3229  m_log.ErrorFormat("[RADMIN]: Created clothing folder for {0}/{1}", name, ID);
3230  }
3231 
3232  // OK, now we have an inventory for the user, read in the outfits from the
3233  // default appearance XMl file.
3234 
3235  XmlNodeList outfits = avatar.GetElementsByTagName("Ensemble");
3236  InventoryFolderBase extraFolder;
3237  string outfitName;
3238  UUID assetid;
3239 
3240  foreach (XmlElement outfit in outfits)
3241  {
3242  m_log.DebugFormat("[RADMIN]: Loading outfit {0} for {1}",
3243  GetStringAttribute(outfit,"name","?"), GetStringAttribute(avatar,"name","?"));
3244 
3245  outfitName = GetStringAttribute(outfit,"name","");
3246  select = (GetStringAttribute(outfit,"default","no") == "yes");
3247 
3248  // If the folder already exists, re-use it. The defaults may
3249  // change over time. Augment only.
3250 
3251  List<InventoryFolderBase> folders = inventoryService.GetFolderContent(ID, clothingFolder.ID).Folders;
3252  extraFolder = null;
3253 
3254  foreach (InventoryFolderBase folder in folders)
3255  {
3256  if (folder.Name == outfitName)
3257  {
3258  extraFolder = folder;
3259  break;
3260  }
3261  }
3262 
3263  // Otherwise, we must create the folder.
3264  if (extraFolder == null)
3265  {
3266  m_log.DebugFormat("[RADMIN]: Creating outfit folder {0} for {1}", outfitName, name);
3267  extraFolder = new InventoryFolderBase();
3268  extraFolder.ID = UUID.Random();
3269  extraFolder.Name = outfitName;
3270  extraFolder.Owner = ID;
3271  extraFolder.Type = (short)FolderType.Clothing;
3272  extraFolder.Version = 1;
3273  extraFolder.ParentID = clothingFolder.ID;
3274  inventoryService.AddFolder(extraFolder);
3275  m_log.DebugFormat("[RADMIN]: Adding outfile folder {0} to folder {1}", extraFolder.ID, clothingFolder.ID);
3276  }
3277 
3278  // Now get the pieces that make up the outfit
3279  XmlNodeList items = outfit.GetElementsByTagName("Item");
3280 
3281  foreach (XmlElement item in items)
3282  {
3283  assetid = UUID.Zero;
3284  XmlNodeList children = item.ChildNodes;
3285  foreach (XmlNode child in children)
3286  {
3287  switch (child.Name)
3288  {
3289  case "Permissions" :
3290  m_log.DebugFormat("[RADMIN]: Permissions specified");
3291  perms = child;
3292  break;
3293  case "Asset" :
3294  assetid = new UUID(child.InnerText);
3295  break;
3296  }
3297  }
3298 
3299  InventoryItemBase inventoryItem = null;
3300 
3301  // Check if asset is in inventory already
3302  inventoryItem = null;
3303  List<InventoryItemBase> inventoryItems = inventoryService.GetFolderContent(ID, extraFolder.ID).Items;
3304 
3305  foreach (InventoryItemBase listItem in inventoryItems)
3306  {
3307  if (listItem.AssetID == assetid)
3308  {
3309  inventoryItem = listItem;
3310  break;
3311  }
3312  }
3313 
3314  // Create inventory item
3315  if (inventoryItem == null)
3316  {
3317  inventoryItem = new InventoryItemBase(UUID.Random(), ID);
3318  inventoryItem.Name = GetStringAttribute(item,"name","");
3319  inventoryItem.Description = GetStringAttribute(item,"desc","");
3320  inventoryItem.InvType = GetIntegerAttribute(item,"invtype",-1);
3321  inventoryItem.CreatorId = GetStringAttribute(item,"creatorid","");
3322  inventoryItem.CreatorData = GetStringAttribute(item, "creatordata", "");
3323  inventoryItem.NextPermissions = GetUnsignedAttribute(perms, "next", 0x7fffffff);
3324  inventoryItem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff);
3325  inventoryItem.BasePermissions = GetUnsignedAttribute(perms,"base",0x7fffffff);
3326  inventoryItem.EveryOnePermissions = GetUnsignedAttribute(perms,"everyone",0x7fffffff);
3327  inventoryItem.GroupPermissions = GetUnsignedAttribute(perms,"group",0x7fffffff);
3328  inventoryItem.AssetType = GetIntegerAttribute(item,"assettype",-1);
3329  inventoryItem.AssetID = assetid; // associated asset
3330  inventoryItem.GroupID = (UUID)GetStringAttribute(item,"groupid","");
3331  inventoryItem.GroupOwned = (GetStringAttribute(item,"groupowned","false") == "true");
3332  inventoryItem.SalePrice = GetIntegerAttribute(item,"saleprice",0);
3333  inventoryItem.SaleType = (byte)GetIntegerAttribute(item,"saletype",0);
3334  inventoryItem.Flags = GetUnsignedAttribute(item,"flags",0);
3335  inventoryItem.CreationDate = GetIntegerAttribute(item,"creationdate",Util.UnixTimeSinceEpoch());
3336  inventoryItem.Folder = extraFolder.ID; // Parent folder
3337 
3338  m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(inventoryItem);
3339  m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", inventoryItem.ID, extraFolder.ID);
3340  }
3341 
3342  // Attach item, if attachpoint is specified
3343  int attachpoint = GetIntegerAttribute(item,"attachpoint",0);
3344  if (attachpoint != 0)
3345  {
3346  avatarAppearance.SetAttachment(attachpoint, inventoryItem.ID, inventoryItem.AssetID);
3347  m_log.DebugFormat("[RADMIN]: Attached {0}", inventoryItem.ID);
3348  }
3349 
3350  // Record whether or not the item is to be initially worn
3351  try
3352  {
3353  if (select && (GetStringAttribute(item, "wear", "false") == "true"))
3354  {
3355  avatarAppearance.Wearables[inventoryItem.Flags].Wear(inventoryItem.ID, inventoryItem.AssetID);
3356  }
3357  }
3358  catch (Exception e)
3359  {
3360  m_log.WarnFormat("[RADMIN]: Error wearing item {0} : {1}", inventoryItem.ID, e.Message);
3361  }
3362  } // foreach item in outfit
3363  m_log.DebugFormat("[RADMIN]: Outfit {0} load completed", outfitName);
3364  } // foreach outfit
3365  m_log.DebugFormat("[RADMIN]: Inventory update complete for {0}", name);
3366  scene.AvatarService.SetAppearance(ID, avatarAppearance);
3367  }
3368  catch (Exception e)
3369  {
3370  m_log.WarnFormat("[RADMIN]: Inventory processing incomplete for user {0} : {1}",
3371  name, e.Message);
3372  }
3373  } // End of include
3374  }
3375  m_log.DebugFormat("[RADMIN]: Default avatar loading complete");
3376  }
3377  else
3378  {
3379  m_log.DebugFormat("[RADMIN]: No default avatar information available");
3380  return false;
3381  }
3382  }
3383  catch (Exception e)
3384  {
3385  m_log.WarnFormat("[RADMIN]: Exception whilst loading default avatars ; {0}", e.Message);
3386  return false;
3387  }
3388 
3389  return true;
3390  }
3391  }
3392 }
EstateSettings EstateSettings
Definition: RegionInfo.cs:275
void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
OpenSim.Framework.RegionInfo RegionInfo
OpenSimulator Application Plugin framework interface
InventoryFolderBase GetRootFolder(UUID userID)
Retrieve the root inventory folder for the given user.
Contains the Avatar's Appearance and methods to manipulate the appearance.
void Initialise(OpenSimBase openSim)
Initialize the Plugin
OpenSim.Framework.PermissionMask PermissionMask
bool AddFolder(InventoryFolderBase folder)
Add a new folder to the user's inventory
Records user information specific to a grid but which is not part of a user's account.
Interface to OpenSimulator's built in HTTP server. Use this to register handlers (http, llsd, xmlrpc, etc.) for given URLs.
Definition: IHttpServer.cs:36
bool StoreUserAccount(UserAccount data)
Store the data given, wich replaces the stored data, therefore must be complete.
Asset class. All Assets are reference by this class or a class derived from this class ...
Definition: AssetBase.cs:49
OpenSim.Services.Interfaces.PresenceInfo PresenceInfo
override Vector3 AbsolutePosition
Position of this avatar relative to the region the avatar is in
Inventory Item - contains all the properties associated with an individual inventory piece...
Exception thrown if Initialise has been called, but failed.
Definition: IPlugin.cs:35
Interactive OpenSim region server
Definition: OpenSim.cs:55
A class for triggering remote scene events.
Definition: EventManager.cs:44
UUID ID
A UUID containing the ID for the inventory node itself
virtual string Name
The name of the node (64 characters or less)
Common OpenSimulator simulator code
Definition: OpenSimBase.cs:58
Dictionary< string, object > ServiceURLs
uint Flags
Parcel settings. Access flags, Fly, NoPush, Voice, Scripts allowed, etc. ParcelFlags ...
Definition: LandData.cs:402
OpenSim.Services.Interfaces.GridRegion GridRegion
uint RegionLocY
The y co-ordinate of this region in map tiles (e.g. 1000). Coordinate is scaled as world coordinates ...
Definition: RegionInfo.cs:496
uint RegionLocX
The x co-ordinate of this region in map tiles (e.g. 1000). Coordinate is scaled as world coordinates ...
Definition: RegionInfo.cs:485
void PostInitialise()
Called when the application loading is completed