OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
OpenSimBase.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.Generic;
30 using System.IO;
31 using System.Linq;
32 using System.Net;
33 using System.Reflection;
34 using System.Text;
35 using log4net;
36 using Nini.Config;
37 using OpenMetaverse;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Console;
40 using OpenSim.Framework.Servers;
41 using OpenSim.Framework.Servers.HttpServer;
42 using OpenSim.Framework.Monitoring;
43 using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
44 using OpenSim.Region.Framework;
45 using OpenSim.Region.Framework.Interfaces;
46 using OpenSim.Region.Framework.Scenes;
47 using OpenSim.Region.PhysicsModules.SharedBase;
48 using OpenSim.Server.Base;
49 using OpenSim.Services.Base;
50 using OpenSim.Services.Interfaces;
51 using OpenSim.Services.UserAccountService;
52 
53 namespace OpenSim
54 {
59  {
60  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
61 
62  // These are the names of the plugin-points extended by this
63  // class during system startup.
64  //
65 
66  private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache";
67  private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetClient";
68 
69  // OpenSim.ini Section name for ESTATES Settings
70  public const string ESTATE_SECTION_NAME = "Estates";
71 
78  public bool EnableInitialPluginLoad { get; set; }
79 
84  public bool LoadEstateDataService { get; set; }
85 
86  protected string proxyUrl;
87  protected int proxyOffset = 0;
88 
89  public string userStatsURI = String.Empty;
90  public string managedStatsURI = String.Empty;
91 
92  protected bool m_autoCreateClientStack = true;
93 
97  protected const string DEFAULT_PRIM_BACKUP_FILENAME = "prim-backup.xml";
98 
100  {
101  get { return m_configSettings; }
102  set { m_configSettings = value; }
103  }
104 
106 
108 
110 
111  public List<IApplicationPlugin> m_plugins = new List<IApplicationPlugin>();
112 
113  private List<string> m_permsModules;
114 
115  private bool m_securePermissionsLoading = true;
116 
120  public OpenSimConfigSource ConfigSource { get; private set; }
121 
122  protected EnvConfigSource m_EnvConfigSource = new EnvConfigSource();
123 
124  public EnvConfigSource envConfigSource
125  {
126  get { return m_EnvConfigSource; }
127  }
128 
129  public uint HttpServerPort
130  {
131  get { return m_httpServerPort; }
132  }
133 
135 
137  {
138  get { return m_applicationRegistry; }
139  }
140 
145  public OpenSimBase(IConfigSource configSource) : base()
146  {
148  LoadEstateDataService = true;
149  LoadConfigSettings(configSource);
150  }
151 
152  protected virtual void LoadConfigSettings(IConfigSource configSource)
153  {
155  ConfigSource = m_configLoader.LoadConfigSettings(configSource, envConfigSource, out m_configSettings, out m_networkServersInfo);
156  Config = ConfigSource.Source;
158  }
159 
160  protected virtual void ReadExtraConfigSettings()
161  {
162  IConfig networkConfig = Config.Configs["Network"];
163  if (networkConfig != null)
164  {
165  proxyUrl = networkConfig.GetString("proxy_url", "");
166  proxyOffset = Int32.Parse(networkConfig.GetString("proxy_offset", "0"));
167  }
168 
169  IConfig startupConfig = Config.Configs["Startup"];
170  if (startupConfig != null)
171  {
172  Util.LogOverloads = startupConfig.GetBoolean("LogOverloads", true);
173  }
174  }
175 
176  protected virtual void LoadPlugins()
177  {
178  IConfig startupConfig = Config.Configs["Startup"];
179  string registryLocation = (startupConfig != null) ? startupConfig.GetString("RegistryLocation", String.Empty) : String.Empty;
180 
181  // The location can also be specified in the environment. If there
182  // is no location in the configuration, we must call the constructor
183  // without a location parameter to allow that to happen.
184  if (registryLocation == String.Empty)
185  {
187  {
188  loader.Load("/OpenSim/Startup");
189  m_plugins = loader.Plugins;
190  }
191  }
192  else
193  {
195  {
196  loader.Load("/OpenSim/Startup");
197  m_plugins = loader.Plugins;
198  }
199  }
200  }
201 
202  protected override List<string> GetHelpTopics()
203  {
204  List<string> topics = base.GetHelpTopics();
205  Scene s = SceneManager.CurrentOrFirstScene;
206  if (s != null && s.GetCommanders() != null)
207  topics.AddRange(s.GetCommanders().Keys);
208 
209  return topics;
210  }
211 
216  protected override void StartupSpecific()
217  {
218  IConfig startupConfig = Config.Configs["Startup"];
219  if (startupConfig != null)
220  {
221  string pidFile = startupConfig.GetString("PIDFile", String.Empty);
222  if (pidFile != String.Empty)
223  CreatePIDFile(pidFile);
224 
225  userStatsURI = startupConfig.GetString("Stats_URI", String.Empty);
226 
227  m_securePermissionsLoading = startupConfig.GetBoolean("SecurePermissionsLoading", true);
228 
229  string permissionModules = Util.GetConfigVarFromSections<string>(Config, "permissionmodules",
230  new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule");
231 
232  m_permsModules = new List<string>(permissionModules.Split(','));
233 
234  managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty);
235  }
236 
237  // Load the simulation data service
238  IConfig simDataConfig = Config.Configs["SimulationDataStore"];
239  if (simDataConfig == null)
240  throw new Exception("Configuration file is missing the [SimulationDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?");
241 
242  string module = simDataConfig.GetString("LocalServiceModule", String.Empty);
243  if (String.IsNullOrEmpty(module))
244  throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [SimulationDataStore] section.");
245 
246  m_simulationDataService = ServerUtils.LoadPlugin<ISimulationDataService>(module, new object[] { Config });
247  if (m_simulationDataService == null)
248  throw new Exception(
249  string.Format(
250  "Could not load an ISimulationDataService implementation from {0}, as configured in the LocalServiceModule parameter of the [SimulationDataStore] config section.",
251  module));
252 
253  // Load the estate data service
254  module = Util.GetConfigVarFromSections<string>(Config, "LocalServiceModule", new string[]{"EstateDataStore", "EstateService"}, String.Empty);
255  if (String.IsNullOrEmpty(module))
256  throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [EstateDataStore] or [EstateService] section");
257 
259  {
260  m_estateDataService = ServerUtils.LoadPlugin<IEstateDataService>(module, new object[] { Config });
261  if (m_estateDataService == null)
262  throw new Exception(
263  string.Format(
264  "Could not load an IEstateDataService implementation from {0}, as configured in the LocalServiceModule parameter of the [EstateDataStore] config section.",
265  module));
266  }
267 
268  base.StartupSpecific();
269 
271  LoadPlugins();
272 
273  // We still want to post initalize any plugins even if loading has been disabled since a test may have
274  // inserted them manually.
275  foreach (IApplicationPlugin plugin in m_plugins)
276  plugin.PostInitialise();
277 
278  if (m_console != null)
280  }
281 
282  protected virtual void AddPluginCommands(ICommandConsole console)
283  {
284  List<string> topics = GetHelpTopics();
285 
286  foreach (string topic in topics)
287  {
288  string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
289 
290  // This is a hack to allow the user to enter the help command in upper or lowercase. This will go
291  // away at some point.
292  console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
293  "help " + capitalizedTopic,
294  "Get help on plugin command '" + topic + "'",
295  HandleCommanderHelp);
296  console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
297  "help " + capitalizedTopic,
298  "Get help on plugin command '" + topic + "'",
299  HandleCommanderHelp);
300 
301  ICommander commander = null;
302 
303  Scene s = SceneManager.CurrentOrFirstScene;
304 
305  if (s != null && s.GetCommanders() != null)
306  {
307  if (s.GetCommanders().ContainsKey(topic))
308  commander = s.GetCommanders()[topic];
309  }
310 
311  if (commander == null)
312  continue;
313 
314  foreach (string command in commander.Commands.Keys)
315  {
316  console.Commands.AddCommand(capitalizedTopic, false,
317  topic + " " + command,
318  topic + " " + commander.Commands[command].ShortHelp(),
319  String.Empty, HandleCommanderCommand);
320  }
321  }
322  }
323 
324  private void HandleCommanderCommand(string module, string[] cmd)
325  {
326  SceneManager.SendCommandToPluginModules(cmd);
327  }
328 
329  private void HandleCommanderHelp(string module, string[] cmd)
330  {
331  // Only safe for the interactive console, since it won't
332  // let us come here unless both scene and commander exist
333  //
334  ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1].ToLower());
335  if (moduleCommander != null)
336  m_console.Output(moduleCommander.Help);
337  }
338 
339  protected override void Initialize()
340  {
341  // Called from base.StartUp()
342 
343  IConfig startupConfig = Config.Configs["Startup"];
344  if (startupConfig == null || startupConfig.GetBoolean("JobEngineEnabled", true))
345  WorkManager.JobEngine.Start();
346 
347  m_httpServerPort = m_networkServersInfo.HttpListenerPort;
348  SceneManager.OnRestartSim += HandleRestartRegion;
349 
350  // Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is
351  // heavily used during initial startup.
352  //
353  // FIXME: It's also possible that region ready status should be flipped during an OAR load since this
354  // also makes heavy use of the CPU.
355  SceneManager.OnRegionsReadyStatusChange
356  += sm => { MemoryWatchdog.Enabled = sm.AllRegionsReady; Watchdog.Enabled = sm.AllRegionsReady; };
357  }
358 
365  public void CreateRegion(RegionInfo regionInfo, bool portadd_flag, out IScene scene)
366  {
367  CreateRegion(regionInfo, portadd_flag, false, out scene);
368  }
369 
375  public void CreateRegion(RegionInfo regionInfo, out IScene scene)
376  {
377  CreateRegion(regionInfo, false, true, out scene);
378  }
379 
387  public void CreateRegion(RegionInfo regionInfo, bool portadd_flag, bool do_post_init, out IScene mscene)
388  {
389  int port = regionInfo.InternalEndPoint.Port;
390 
391  // set initial RegionID to originRegionID in RegionInfo. (it needs for loding prims)
392  // Commented this out because otherwise regions can't register with
393  // the grid as there is already another region with the same UUID
394  // at those coordinates. This is required for the load balancer to work.
395  // --Mike, 2009.02.25
396  //regionInfo.originRegionID = regionInfo.RegionID;
397 
398  // set initial ServerURI
399  regionInfo.HttpPort = m_httpServerPort;
400  regionInfo.ServerURI = "http://" + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort.ToString() + "/";
401 
402  regionInfo.osSecret = m_osSecret;
403 
404  if ((proxyUrl.Length > 0) && (portadd_flag))
405  {
406  // set proxy url to RegionInfo
407  regionInfo.proxyUrl = proxyUrl;
408  regionInfo.ProxyOffset = proxyOffset;
409  Util.XmlRpcCommand(proxyUrl, "AddPort", port, port + proxyOffset, regionInfo.ExternalHostName);
410  }
411 
412  Scene scene = SetupScene(regionInfo, proxyOffset, Config);
413 
414  m_log.Info("[MODULES]: Loading Region's modules (old style)");
415 
416  // Use this in the future, the line above will be deprecated soon
417  m_log.Info("[REGIONMODULES]: Loading Region's modules (new style)");
418  IRegionModulesController controller;
419  if (ApplicationRegistry.TryGet(out controller))
420  {
421  controller.AddRegionToModules(scene);
422  }
423  else m_log.Error("[REGIONMODULES]: The new RegionModulesController is missing...");
424 
425  if (m_securePermissionsLoading)
426  {
427  foreach (string s in m_permsModules)
428  {
429  if (!scene.RegionModules.ContainsKey(s))
430  {
431  m_log.Fatal("[MODULES]: Required module " + s + " not found.");
432  Environment.Exit(0);
433  }
434  }
435 
436  m_log.InfoFormat("[SCENE]: Secure permissions loading enabled, modules loaded: {0}", String.Join(" ", m_permsModules.ToArray()));
437  }
438 
439  scene.SetModuleInterfaces();
440 // First Step of bootreport sequence
441  if (scene.SnmpService != null)
442  {
443  scene.SnmpService.ColdStart(1,scene);
444  scene.SnmpService.LinkDown(scene);
445  }
446 
447  if (scene.SnmpService != null)
448  {
449  scene.SnmpService.BootInfo("Loading prins", scene);
450  }
451 
452  while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
453  SetUpEstateOwner(scene);
454 
455  // Prims have to be loaded after module configuration since some modules may be invoked during the load
456  scene.LoadPrimsFromStorage(regionInfo.originRegionID);
457 
458  // TODO : Try setting resource for region xstats here on scene
459  MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo));
460 
461  scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
462  scene.EventManager.TriggerParcelPrimCountUpdate();
463 
464  if (scene.SnmpService != null)
465  {
466  scene.SnmpService.BootInfo("Grid Registration in progress", scene);
467  }
468 
469  try
470  {
471  scene.RegisterRegionWithGrid();
472  }
473  catch (Exception e)
474  {
475  m_log.ErrorFormat(
476  "[STARTUP]: Registration of region with grid failed, aborting startup due to {0} {1}",
477  e.Message, e.StackTrace);
478 
479  if (scene.SnmpService != null)
480  {
481  scene.SnmpService.Critical("Grid registration failed. Startup aborted.", scene);
482  }
483  // Carrying on now causes a lot of confusion down the
484  // line - we need to get the user's attention
485  Environment.Exit(1);
486  }
487 
488  if (scene.SnmpService != null)
489  {
490  scene.SnmpService.BootInfo("Grid Registration done", scene);
491  }
492 
493  // We need to do this after we've initialized the
494  // scripting engines.
495  scene.CreateScriptInstances();
496 
497  if (scene.SnmpService != null)
498  {
499  scene.SnmpService.BootInfo("ScriptEngine started", scene);
500  }
501 
502  SceneManager.Add(scene);
503 
504  //if (m_autoCreateClientStack)
505  //{
506  // foreach (IClientNetworkServer clientserver in clientServers)
507  // {
508  // m_clientServers.Add(clientserver);
509  // clientserver.Start();
510  // }
511  //}
512 
513  if (scene.SnmpService != null)
514  {
515  scene.SnmpService.BootInfo("Initializing region modules", scene);
516  }
517  scene.EventManager.OnShutdown += delegate() { ShutdownRegion(scene); };
518 
519  mscene = scene;
520 
521  if (scene.SnmpService != null)
522  {
523  scene.SnmpService.BootInfo("The region is operational", scene);
524  scene.SnmpService.LinkUp(scene);
525  }
526 
527  //return clientServers;
528  }
529 
538  private void SetUpEstateOwner(Scene scene)
539  {
540  RegionInfo regionInfo = scene.RegionInfo;
541 
542  string estateOwnerFirstName = null;
543  string estateOwnerLastName = null;
544  string estateOwnerEMail = null;
545  string estateOwnerPassword = null;
546  string rawEstateOwnerUuid = null;
547 
548  if (Config.Configs[ESTATE_SECTION_NAME] != null)
549  {
550  string defaultEstateOwnerName
551  = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerName", "").Trim();
552  string[] ownerNames = defaultEstateOwnerName.Split(' ');
553 
554  if (ownerNames.Length >= 2)
555  {
556  estateOwnerFirstName = ownerNames[0];
557  estateOwnerLastName = ownerNames[1];
558  }
559 
560  // Info to be used only on Standalone Mode
561  rawEstateOwnerUuid = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerUUID", null);
562  estateOwnerEMail = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerEMail", null);
563  estateOwnerPassword = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerPassword", null);
564  }
565 
566  MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
567  List<char> excluded = new List<char>(new char[1]{' '});
568 
569 
570  if (estateOwnerFirstName == null || estateOwnerLastName == null)
571  {
572  estateOwnerFirstName = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
573  estateOwnerLastName = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
574  }
575 
576  UserAccount account
577  = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, estateOwnerFirstName, estateOwnerLastName);
578 
579  if (account == null)
580  {
581 
582  // XXX: The LocalUserAccountServicesConnector is currently registering its inner service rather than
583  // itself!
584 // if (scene.UserAccountService is LocalUserAccountServicesConnector)
585 // {
586 // IUserAccountService innerUas
587 // = ((LocalUserAccountServicesConnector)scene.UserAccountService).UserAccountService;
588 //
589 // m_log.DebugFormat("B {0}", innerUas.GetType());
590 //
591 // if (innerUas is UserAccountService)
592 // {
593 
595  {
596  if (estateOwnerPassword == null)
597  estateOwnerPassword = MainConsole.Instance.PasswdPrompt("Password");
598 
599  if (estateOwnerEMail == null)
600  estateOwnerEMail = MainConsole.Instance.CmdPrompt("Email");
601 
602  if (rawEstateOwnerUuid == null)
603  rawEstateOwnerUuid = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
604 
605  UUID estateOwnerUuid = UUID.Zero;
606  if (!UUID.TryParse(rawEstateOwnerUuid, out estateOwnerUuid))
607  {
608  m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawEstateOwnerUuid);
609  return;
610  }
611 
612  // If we've been given a zero uuid then this signals that we should use a random user id
613  if (estateOwnerUuid == UUID.Zero)
614  estateOwnerUuid = UUID.Random();
615 
616  account
617  = ((UserAccountService)scene.UserAccountService).CreateUser(
618  regionInfo.ScopeID,
619  estateOwnerUuid,
620  estateOwnerFirstName,
621  estateOwnerLastName,
622  estateOwnerPassword,
623  estateOwnerEMail);
624  }
625  }
626 
627  if (account == null)
628  {
629  m_log.ErrorFormat(
630  "[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first at the grid level.");
631  }
632  else
633  {
634  regionInfo.EstateSettings.EstateOwner = account.PrincipalID;
635  m_estateDataService.StoreEstateSettings(regionInfo.EstateSettings);
636  }
637  }
638 
639  private void ShutdownRegion(Scene scene)
640  {
641  m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);
642  if (scene.SnmpService != null)
643  {
644  scene.SnmpService.BootInfo("The region is shutting down", scene);
645  scene.SnmpService.LinkDown(scene);
646  }
647  IRegionModulesController controller;
648  if (ApplicationRegistry.TryGet<IRegionModulesController>(out controller))
649  {
650  controller.RemoveRegionFromModules(scene);
651  }
652  }
653 
654  public void RemoveRegion(Scene scene, bool cleanup)
655  {
656  // only need to check this if we are not at the
657  // root level
658  if ((SceneManager.CurrentScene != null) &&
660  {
661  SceneManager.TrySetCurrentScene("..");
662  }
663 
664  scene.DeleteAllSceneObjects();
665  SceneManager.CloseScene(scene);
666  //ShutdownClientServer(scene.RegionInfo);
667 
668  if (!cleanup)
669  return;
670 
671  if (!String.IsNullOrEmpty(scene.RegionInfo.RegionFile))
672  {
673  if (scene.RegionInfo.RegionFile.ToLower().EndsWith(".xml"))
674  {
675  File.Delete(scene.RegionInfo.RegionFile);
676  m_log.InfoFormat("[OPENSIM]: deleting region file \"{0}\"", scene.RegionInfo.RegionFile);
677  }
678  if (scene.RegionInfo.RegionFile.ToLower().EndsWith(".ini"))
679  {
680  try
681  {
682  IniConfigSource source = new IniConfigSource(scene.RegionInfo.RegionFile);
683  if (source.Configs[scene.RegionInfo.RegionName] != null)
684  {
685  source.Configs.Remove(scene.RegionInfo.RegionName);
686 
687  if (source.Configs.Count == 0)
688  {
689  File.Delete(scene.RegionInfo.RegionFile);
690  }
691  else
692  {
693  source.Save(scene.RegionInfo.RegionFile);
694  }
695  }
696  }
697  catch (Exception)
698  {
699  }
700  }
701  }
702  }
703 
704  public void RemoveRegion(string name, bool cleanUp)
705  {
706  Scene target;
707  if (SceneManager.TryGetScene(name, out target))
708  RemoveRegion(target, cleanUp);
709  }
710 
716  public void CloseRegion(Scene scene)
717  {
718  // only need to check this if we are not at the
719  // root level
720  if ((SceneManager.CurrentScene != null) &&
722  {
723  SceneManager.TrySetCurrentScene("..");
724  }
725 
726  SceneManager.CloseScene(scene);
727  //ShutdownClientServer(scene.RegionInfo);
728  }
729 
735  public void CloseRegion(string name)
736  {
737  Scene target;
738  if (SceneManager.TryGetScene(name, out target))
739  CloseRegion(target);
740  }
741 
748  protected Scene SetupScene(RegionInfo regionInfo)
749  {
750  return SetupScene(regionInfo, 0, null);
751  }
752 
761  protected Scene SetupScene(RegionInfo regionInfo, int proxyOffset, IConfigSource configSource)
762  {
763  //List<IClientNetworkServer> clientNetworkServers = null;
764 
765  AgentCircuitManager circuitManager = new AgentCircuitManager();
766  Scene scene = CreateScene(regionInfo, m_simulationDataService, m_estateDataService, circuitManager);
767 
768  scene.LoadWorldMap();
769 
770  return scene;
771  }
772 
773  protected override Scene CreateScene(RegionInfo regionInfo, ISimulationDataService simDataService,
774  IEstateDataService estateDataService, AgentCircuitManager circuitManager)
775  {
776  return new Scene(
777  regionInfo, circuitManager,
778  simDataService, estateDataService,
779  Config, m_version);
780  }
781 
782  protected virtual void HandleRestartRegion(RegionInfo whichRegion)
783  {
784  m_log.InfoFormat(
785  "[OPENSIM]: Got restart signal from SceneManager for region {0} ({1},{2})",
786  whichRegion.RegionName, whichRegion.RegionLocX, whichRegion.RegionLocY);
787 
788  //ShutdownClientServer(whichRegion);
789  IScene scene;
790  CreateRegion(whichRegion, true, out scene);
791  scene.Start();
792  }
793 
794  # region Setup methods
795 
803  {
804  public SimStatusHandler() : base("GET", "/simstatus", "SimStatus", "Simulator Status") {}
805 
806  protected override byte[] ProcessRequest(string path, Stream request,
807  IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
808  {
809  return Util.UTF8.GetBytes("OK");
810  }
811 
812  public override string ContentType
813  {
814  get { return "text/plain"; }
815  }
816  }
817 
823  {
824  OpenSimBase m_opensim;
825 
827  : base("GET", "/" + Util.SHA1Hash(sim.osSecret), "XSimStatus", "Simulator XStatus")
828  {
829  m_opensim = sim;
830  }
831 
832  protected override byte[] ProcessRequest(string path, Stream request,
833  IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
834  {
835  return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest));
836  }
837 
838  public override string ContentType
839  {
840  get { return "text/plain"; }
841  }
842  }
843 
851  {
852  OpenSimBase m_opensim;
853 
855  : base("GET", "/" + sim.userStatsURI, "UXSimStatus", "Simulator UXStatus")
856  {
857  m_opensim = sim;
858  }
859 
860  protected override byte[] ProcessRequest(string path, Stream request,
861  IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
862  {
863  return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest));
864  }
865 
866  public override string ContentType
867  {
868  get { return "text/plain"; }
869  }
870  }
871 
872  #endregion
873 
877  protected override void ShutdownSpecific()
878  {
879  if (proxyUrl.Length > 0)
880  {
881  Util.XmlRpcCommand(proxyUrl, "Stop");
882  }
883 
884  m_log.Info("[SHUTDOWN]: Closing all threads");
885  m_log.Info("[SHUTDOWN]: Killing listener thread");
886  m_log.Info("[SHUTDOWN]: Killing clients");
887  m_log.Info("[SHUTDOWN]: Closing console and terminating");
888 
889  try
890  {
891  SceneManager.Close();
892 
893  foreach (IApplicationPlugin plugin in m_plugins)
894  plugin.Dispose();
895  }
896  catch (Exception e)
897  {
898  m_log.Error("[SHUTDOWN]: Ignoring failure during shutdown - ", e);
899  }
900 
901  base.ShutdownSpecific();
902  }
903 
909  public void GetRunTime(out string starttime, out string uptime)
910  {
911  starttime = m_startuptime.ToString();
912  uptime = (DateTime.Now - m_startuptime).ToString();
913  }
914 
919  public void GetAvatarNumber(out int usernum)
920  {
921  usernum = SceneManager.GetCurrentSceneAvatars().Count;
922  }
923 
928  public void GetRegionNumber(out int regionnum)
929  {
930  regionnum = SceneManager.Scenes.Count;
931  }
932 
943  public bool CreateEstate(RegionInfo regInfo, Dictionary<string, EstateSettings> estatesByName, string estateName)
944  {
945  // Create a new estate
946  regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true);
947 
948  string newName;
949  if (!string.IsNullOrEmpty(estateName))
950  newName = estateName;
951  else
952  newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
953 
954  if (estatesByName.ContainsKey(newName))
955  {
956  MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName);
957  return false;
958  }
959 
960  regInfo.EstateSettings.EstateName = newName;
961 
962  // FIXME: Later on, the scene constructor will reload the estate settings no matter what.
963  // Therefore, we need to do an initial save here otherwise the new estate name will be reset
964  // back to the default. The reloading of estate settings by scene could be eliminated if it
965  // knows that the passed in settings in RegionInfo are already valid. Also, it might be
966  // possible to eliminate some additional later saves made by callers of this method.
967  EstateDataService.StoreEstateSettings(regInfo.EstateSettings);
968 
969  return true;
970  }
971 
977  {
978  if (EstateDataService != null)
979  regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
980 
981  if (regInfo.EstateSettings.EstateID != 0)
982  return false; // estate info in the database did not change
983 
984  m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
985 
986  List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
987  Dictionary<string, EstateSettings> estatesByName = new Dictionary<string, EstateSettings>();
988 
989  foreach (EstateSettings estate in estates)
990  estatesByName[estate.EstateName] = estate;
991 
992  string defaultEstateName = null;
993 
994  if (Config.Configs[ESTATE_SECTION_NAME] != null)
995  {
996  defaultEstateName = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateName", null);
997 
998  if (defaultEstateName != null)
999  {
1000  EstateSettings defaultEstate;
1001  bool defaultEstateJoined = false;
1002 
1003  if (estatesByName.ContainsKey(defaultEstateName))
1004  {
1005  defaultEstate = estatesByName[defaultEstateName];
1006 
1007  if (EstateDataService.LinkRegion(regInfo.RegionID, (int)defaultEstate.EstateID))
1008  defaultEstateJoined = true;
1009  }
1010  else
1011  {
1012  if (CreateEstate(regInfo, estatesByName, defaultEstateName))
1013  defaultEstateJoined = true;
1014  }
1015 
1016  if (defaultEstateJoined)
1017  return true; // need to update the database
1018  else
1019  m_log.ErrorFormat(
1020  "[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
1021  }
1022  }
1023 
1024  // If we have no default estate or creation of the default estate failed then ask the user.
1025  while (true)
1026  {
1027  if (estates.Count == 0)
1028  {
1029  m_log.Info("[ESTATE]: No existing estates found. You must create a new one.");
1030 
1031  if (CreateEstate(regInfo, estatesByName, null))
1032  break;
1033  else
1034  continue;
1035  }
1036  else
1037  {
1038  string response
1039  = MainConsole.Instance.CmdPrompt(
1040  string.Format(
1041  "Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
1042  "yes",
1043  new List<string>() { "yes", "no" });
1044 
1045  if (response == "no")
1046  {
1047  if (CreateEstate(regInfo, estatesByName, null))
1048  break;
1049  else
1050  continue;
1051  }
1052  else
1053  {
1054  string[] estateNames = estatesByName.Keys.ToArray();
1055  response
1056  = MainConsole.Instance.CmdPrompt(
1057  string.Format(
1058  "Name of estate to join. Existing estate names are ({0})",
1059  string.Join(", ", estateNames)),
1060  estateNames[0]);
1061 
1062  List<int> estateIDs = EstateDataService.GetEstates(response);
1063  if (estateIDs.Count < 1)
1064  {
1065  MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
1066  continue;
1067  }
1068 
1069  int estateID = estateIDs[0];
1070 
1071  regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
1072 
1073  if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
1074  break;
1075 
1076  MainConsole.Instance.Output("Joining the estate failed. Please try again.");
1077  }
1078  }
1079  }
1080 
1081  return true; // need to update the database
1082  }
1083  }
1084 
1085  public class OpenSimConfigSource
1086  {
1087  public IConfigSource Source;
1088  }
1089 }
override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
Definition: OpenSimBase.cs:806
virtual void LoadConfigSettings(IConfigSource configSource)
Definition: OpenSimBase.cs:152
void GetRegionNumber(out int regionnum)
Get the number of regions
Definition: OpenSimBase.cs:928
Scene SetupScene(RegionInfo regionInfo, int proxyOffset, IConfigSource configSource)
Create a scene and its initial base structures.
Definition: OpenSimBase.cs:761
EstateSettings EstateSettings
Definition: RegionInfo.cs:275
void GetAvatarNumber(out int usernum)
Get the number of the avatars in the Region server
Definition: OpenSimBase.cs:919
Handler to supply the current status of this sim
Definition: OpenSimBase.cs:802
void RemoveRegion(string name, bool cleanUp)
Definition: OpenSimBase.cs:704
Loads the Configuration files into nIni
bool LinkRegion(UUID regionID, int estateID)
Link a region to an estate.
List< IApplicationPlugin > m_plugins
Definition: OpenSimBase.cs:111
override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
Definition: OpenSimBase.cs:832
override Scene CreateScene(RegionInfo regionInfo, ISimulationDataService simDataService, IEstateDataService estateDataService, AgentCircuitManager circuitManager)
Definition: OpenSimBase.cs:773
OpenSim.Framework.RegionInfo RegionInfo
OpenSimulator Application Plugin framework interface
Dictionary< string, ICommander > GetCommanders()
Definition: SceneBase.cs:372
Scene SetupScene(RegionInfo regionInfo)
Create a scene and its initial base structures.
Definition: OpenSimBase.cs:748
OpenSimConfigSource ConfigSource
Definition: OpenSimBase.cs:120
override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
Definition: OpenSimBase.cs:860
ConfigSettings m_configSettings
Definition: OpenSimBase.cs:105
Handler to supply the current extended status of this sim Sends the statistical data in a json serial...
Definition: OpenSimBase.cs:822
virtual void LoadPlugins()
Definition: OpenSimBase.cs:176
void CloseRegion(Scene scene)
Remove a region from the simulator without deleting it permanently.
Definition: OpenSimBase.cs:716
EnvConfigSource envConfigSource
Definition: OpenSimBase.cs:125
string m_version
Server version information. Usually VersionInfo + information about git commit, operating system...
Definition: ServerBase.cs:71
IRegistryCore ApplicationRegistry
Definition: OpenSimBase.cs:137
void GetRunTime(out string starttime, out string uptime)
Get the start time and up time of Region server
Definition: OpenSimBase.cs:909
OpenSimBase(IConfigSource configSource)
Constructor.
Definition: OpenSimBase.cs:145
ConfigurationLoader m_configLoader
Definition: OpenSimBase.cs:107
Handler to supply the current extended status of this sim to a user configured URI Sends the statisti...
Definition: OpenSimBase.cs:850
Dictionary< string, IRegionModuleBase > RegionModules
Definition: SceneBase.cs:75
IRegistryCore m_applicationRegistry
Definition: OpenSimBase.cs:134
virtual void HandleRestartRegion(RegionInfo whichRegion)
Definition: OpenSimBase.cs:782
static ICommandConsole Instance
Definition: MainConsole.cs:35
delegate void ConsoleCommand(string[] comParams)
Manager for adding, closing and restarting scenes.
Definition: SceneManager.cs:44
IUserAccountService UserAccountService
Definition: Scene.cs:732
Scene CurrentScene
Scene selected from the console.
void CreateRegion(RegionInfo regionInfo, bool portadd_flag, bool do_post_init, out IScene mscene)
Execute the region creation process. This includes setting up scene infrastructure.
Definition: OpenSimBase.cs:387
bool EnableInitialPluginLoad
Allow all plugin loading to be disabled for tests/debug.
Definition: OpenSimBase.cs:78
bool LoadEstateDataService
Control whether we attempt to load an estate data service.
Definition: OpenSimBase.cs:84
override void ShutdownSpecific()
Performs any last-minute sanity checking and shuts down the region server
Definition: OpenSimBase.cs:877
override void Initialize()
Definition: OpenSimBase.cs:339
const string DEFAULT_PRIM_BACKUP_FILENAME
Definition: OpenSimBase.cs:97
void CreateRegion(RegionInfo regionInfo, out IScene scene)
Execute the region creation process. This includes setting up scene infrastructure.
Definition: OpenSimBase.cs:375
override List< string > GetHelpTopics()
Provides a list of help topics that are available. Overriding classes should append their topics to t...
Definition: OpenSimBase.cs:202
Common OpenSimulator simulator code
Definition: OpenSimBase.cs:58
bool m_autoCreateClientStack
Definition: OpenSimBase.cs:92
string m_osSecret
Random uuid for private data
ICommandConsole m_console
Console to be used for any command line output. Can be null, in which case there should be no output...
Definition: ServerBase.cs:56
ConfigSettings ConfigurationSettings
Definition: OpenSimBase.cs:100
void RemoveRegion(Scene scene, bool cleanup)
Definition: OpenSimBase.cs:654
bool CreateEstate(RegionInfo regInfo, Dictionary< string, EstateSettings > estatesByName, string estateName)
Create an estate with an initial region.
Definition: OpenSimBase.cs:943
EnvConfigSource m_EnvConfigSource
Definition: OpenSimBase.cs:122
ConsoleCommand CreateAccount
Definition: OpenSimBase.cs:109
void CloseRegion(string name)
Remove a region from the simulator without deleting it permanently.
Definition: OpenSimBase.cs:735
bool PopulateRegionEstateInfo(RegionInfo regInfo)
Load the estate information for the provided RegionInfo object.
Definition: OpenSimBase.cs:976
void CreateRegion(RegionInfo regionInfo, bool portadd_flag, out IScene scene)
Execute the region creation process. This includes setting up scene infrastructure.
Definition: OpenSimBase.cs:365
const string ESTATE_SECTION_NAME
Definition: OpenSimBase.cs:70
virtual void AddPluginCommands(ICommandConsole console)
Definition: OpenSimBase.cs:282
ISimulationDataService m_simulationDataService
bool TryGetScene(string regionName, out Scene scene)
override void StartupSpecific()
Performs startup specific to the region server, including initialization of the scene such as loading...
Definition: OpenSimBase.cs:216
virtual void ReadExtraConfigSettings()
Definition: OpenSimBase.cs:160