OpenSim.cs 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  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. using System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.Diagnostics;
  31. using System.IO;
  32. using System.Reflection;
  33. using System.Text;
  34. using System.Text.RegularExpressions;
  35. using System.Timers;
  36. using log4net;
  37. using NDesk.Options;
  38. using Nini.Config;
  39. using OpenMetaverse;
  40. using OpenSim.Framework;
  41. using OpenSim.Framework.Console;
  42. using OpenSim.Framework.Servers;
  43. using OpenSim.Framework.Monitoring;
  44. using OpenSim.Region.Framework.Interfaces;
  45. using OpenSim.Region.Framework.Scenes;
  46. namespace OpenSim
  47. {
  48. /// <summary>
  49. /// Interactive OpenSim region server
  50. /// </summary>
  51. public class OpenSim : OpenSimBase
  52. {
  53. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  54. protected string m_startupCommandsFile;
  55. protected string m_shutdownCommandsFile;
  56. protected bool m_gui = false;
  57. protected string m_consoleType = "local";
  58. protected uint m_consolePort = 0;
  59. /// <summary>
  60. /// Prompt to use for simulator command line.
  61. /// </summary>
  62. private string m_consolePrompt;
  63. /// <summary>
  64. /// Regex for parsing out special characters in the prompt.
  65. /// </summary>
  66. private Regex m_consolePromptRegex = new Regex(@"([^\\])\\(\w)", RegexOptions.Compiled);
  67. private string m_timedScript = "disabled";
  68. private int m_timeInterval = 1200;
  69. private Timer m_scriptTimer;
  70. public OpenSim(IConfigSource configSource) : base(configSource)
  71. {
  72. }
  73. protected override void ReadExtraConfigSettings()
  74. {
  75. base.ReadExtraConfigSettings();
  76. IConfig startupConfig = m_config.Source.Configs["Startup"];
  77. IConfig networkConfig = m_config.Source.Configs["Network"];
  78. int stpMaxThreads = 15;
  79. if (startupConfig != null)
  80. {
  81. m_startupCommandsFile = startupConfig.GetString("startup_console_commands_file", "startup_commands.txt");
  82. m_shutdownCommandsFile = startupConfig.GetString("shutdown_console_commands_file", "shutdown_commands.txt");
  83. if (startupConfig.GetString("console", String.Empty) == String.Empty)
  84. m_gui = startupConfig.GetBoolean("gui", false);
  85. else
  86. m_consoleType= startupConfig.GetString("console", String.Empty);
  87. if (networkConfig != null)
  88. m_consolePort = (uint)networkConfig.GetInt("console_port", 0);
  89. m_timedScript = startupConfig.GetString("timer_Script", "disabled");
  90. if (m_timedScript != "disabled")
  91. {
  92. m_timeInterval = startupConfig.GetInt("timer_Interval", 1200);
  93. }
  94. if (m_logFileAppender != null)
  95. {
  96. if (m_logFileAppender is log4net.Appender.FileAppender)
  97. {
  98. log4net.Appender.FileAppender appender =
  99. (log4net.Appender.FileAppender)m_logFileAppender;
  100. string fileName = startupConfig.GetString("LogFile", String.Empty);
  101. if (fileName != String.Empty)
  102. {
  103. appender.File = fileName;
  104. appender.ActivateOptions();
  105. }
  106. m_log.InfoFormat("[LOGGING]: Logging started to file {0}", appender.File);
  107. }
  108. }
  109. string asyncCallMethodStr = startupConfig.GetString("async_call_method", String.Empty);
  110. FireAndForgetMethod asyncCallMethod;
  111. if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod))
  112. Util.FireAndForgetMethod = asyncCallMethod;
  113. stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
  114. m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
  115. }
  116. if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
  117. Util.InitThreadPool(stpMaxThreads);
  118. m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
  119. }
  120. /// <summary>
  121. /// Performs initialisation of the scene, such as loading configuration from disk.
  122. /// </summary>
  123. protected override void StartupSpecific()
  124. {
  125. m_log.Info("====================================================================");
  126. m_log.Info("========================= STARTING OPENSIM =========================");
  127. m_log.Info("====================================================================");
  128. //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString());
  129. // http://msdn.microsoft.com/en-us/library/bb384202.aspx
  130. //GCSettings.LatencyMode = GCLatencyMode.Batch;
  131. //m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString());
  132. if (m_gui) // Driven by external GUI
  133. {
  134. m_console = new CommandConsole("Region");
  135. }
  136. else
  137. {
  138. switch (m_consoleType)
  139. {
  140. case "basic":
  141. m_console = new CommandConsole("Region");
  142. break;
  143. case "rest":
  144. m_console = new RemoteConsole("Region");
  145. ((RemoteConsole)m_console).ReadConfig(m_config.Source);
  146. break;
  147. default:
  148. m_console = new LocalConsole("Region");
  149. break;
  150. }
  151. }
  152. MainConsole.Instance = m_console;
  153. RegisterConsoleCommands();
  154. base.StartupSpecific();
  155. MainServer.Instance.AddStreamHandler(new OpenSim.SimStatusHandler());
  156. MainServer.Instance.AddStreamHandler(new OpenSim.XSimStatusHandler(this));
  157. if (userStatsURI != String.Empty)
  158. MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this));
  159. if (m_console is RemoteConsole)
  160. {
  161. if (m_consolePort == 0)
  162. {
  163. ((RemoteConsole)m_console).SetServer(m_httpServer);
  164. }
  165. else
  166. {
  167. ((RemoteConsole)m_console).SetServer(MainServer.GetHttpServer(m_consolePort));
  168. }
  169. }
  170. // Hook up to the watchdog timer
  171. Watchdog.OnWatchdogTimeout += WatchdogTimeoutHandler;
  172. PrintFileToConsole("startuplogo.txt");
  173. // For now, start at the 'root' level by default
  174. if (SceneManager.Scenes.Count == 1) // If there is only one region, select it
  175. ChangeSelectedRegion("region",
  176. new string[] {"change", "region", SceneManager.Scenes[0].RegionInfo.RegionName});
  177. else
  178. ChangeSelectedRegion("region", new string[] {"change", "region", "root"});
  179. //Run Startup Commands
  180. if (String.IsNullOrEmpty(m_startupCommandsFile))
  181. {
  182. m_log.Info("[STARTUP]: No startup command script specified. Moving on...");
  183. }
  184. else
  185. {
  186. RunCommandScript(m_startupCommandsFile);
  187. }
  188. // Start timer script (run a script every xx seconds)
  189. if (m_timedScript != "disabled")
  190. {
  191. m_scriptTimer = new Timer();
  192. m_scriptTimer.Enabled = true;
  193. m_scriptTimer.Interval = m_timeInterval*1000;
  194. m_scriptTimer.Elapsed += RunAutoTimerScript;
  195. }
  196. }
  197. /// <summary>
  198. /// Register standard set of region console commands
  199. /// </summary>
  200. private void RegisterConsoleCommands()
  201. {
  202. MainServer.RegisterHttpConsoleCommands(m_console);
  203. m_console.Commands.AddCommand("Objects", false, "force update",
  204. "force update",
  205. "Force the update of all objects on clients",
  206. HandleForceUpdate);
  207. m_console.Commands.AddCommand("Debug", false, "debug packet",
  208. "debug packet <level> [<avatar-first-name> <avatar-last-name>]",
  209. "Turn on packet debugging",
  210. "If level > 255 then all incoming and outgoing packets are logged.\n"
  211. + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
  212. + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
  213. + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
  214. + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
  215. + "If level <= 0 then no packets are logged.\n"
  216. + "If an avatar name is given then only packets from that avatar are logged",
  217. Debug);
  218. m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
  219. m_console.Commands.AddCommand("Debug", false, "debug scene",
  220. "debug scene active|collisions|physics|scripting|teleport true|false",
  221. "Turn on scene debugging.",
  222. "If active is false then main scene update and maintenance loops are suspended.\n"
  223. + "If collisions is false then collisions with other objects are turned off.\n"
  224. + "If physics is false then all physics objects are non-physical.\n"
  225. + "If scripting is false then no scripting operations happen.\n"
  226. + "If teleport is true then some extra teleport debug information is logged.",
  227. Debug);
  228. m_console.Commands.AddCommand("General", false, "change region",
  229. "change region <region name>",
  230. "Change current console region", ChangeSelectedRegion);
  231. m_console.Commands.AddCommand("Archiving", false, "save xml",
  232. "save xml",
  233. "Save a region's data in XML format", SaveXml);
  234. m_console.Commands.AddCommand("Archiving", false, "save xml2",
  235. "save xml2",
  236. "Save a region's data in XML2 format", SaveXml2);
  237. m_console.Commands.AddCommand("Archiving", false, "load xml",
  238. "load xml [-newIDs [<x> <y> <z>]]",
  239. "Load a region's data from XML format", LoadXml);
  240. m_console.Commands.AddCommand("Archiving", false, "load xml2",
  241. "load xml2",
  242. "Load a region's data from XML2 format", LoadXml2);
  243. m_console.Commands.AddCommand("Archiving", false, "save prims xml2",
  244. "save prims xml2 [<prim name> <file name>]",
  245. "Save named prim to XML2", SavePrimsXml2);
  246. m_console.Commands.AddCommand("Archiving", false, "load oar",
  247. "load oar [--merge] [--skip-assets] [<OAR path>]",
  248. "Load a region's data from an OAR archive.",
  249. "--merge will merge the OAR with the existing scene." + Environment.NewLine
  250. + "--skip-assets will load the OAR but ignore the assets it contains." + Environment.NewLine
  251. + "The path can be either a filesystem location or a URI."
  252. + " If this is not given then the command looks for an OAR named region.oar in the current directory.",
  253. LoadOar);
  254. m_console.Commands.AddCommand("Archiving", false, "save oar",
  255. //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
  256. "save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [--all] [<OAR path>]",
  257. "Save a region's data to an OAR archive.",
  258. // "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
  259. "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
  260. + "--noassets stops assets being saved to the OAR.\n"
  261. + "--publish saves an OAR stripped of owner and last owner information.\n"
  262. + " on reload, the estate owner will be the owner of all objects\n"
  263. + " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published\n"
  264. + "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR.\n"
  265. + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer\n"
  266. + "--all saves all the regions in the simulator, instead of just the current region.\n"
  267. + "The OAR path must be a filesystem path."
  268. + " If this is not given then the oar is saved to region.oar in the current directory.",
  269. SaveOar);
  270. m_console.Commands.AddCommand("Objects", false, "edit scale",
  271. "edit scale <name> <x> <y> <z>",
  272. "Change the scale of a named prim", HandleEditScale);
  273. m_console.Commands.AddCommand("Users", false, "kick user",
  274. "kick user <first> <last> [--force] [message]",
  275. "Kick a user off the simulator",
  276. "The --force option will kick the user without any checks to see whether it's already in the process of closing\n"
  277. + "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them",
  278. KickUserCommand);
  279. m_console.Commands.AddCommand("Users", false, "show users",
  280. "show users [full]",
  281. "Show user data for users currently on the region",
  282. "Without the 'full' option, only users actually on the region are shown."
  283. + " With the 'full' option child agents of users in neighbouring regions are also shown.",
  284. HandleShow);
  285. m_console.Commands.AddCommand("Comms", false, "show connections",
  286. "show connections",
  287. "Show connection data", HandleShow);
  288. m_console.Commands.AddCommand("Comms", false, "show circuits",
  289. "show circuits",
  290. "Show agent circuit data", HandleShow);
  291. m_console.Commands.AddCommand("Comms", false, "show pending-objects",
  292. "show pending-objects",
  293. "Show # of objects on the pending queues of all scene viewers", HandleShow);
  294. m_console.Commands.AddCommand("General", false, "show modules",
  295. "show modules",
  296. "Show module data", HandleShow);
  297. m_console.Commands.AddCommand("Regions", false, "show regions",
  298. "show regions",
  299. "Show region data", HandleShow);
  300. m_console.Commands.AddCommand("Regions", false, "show ratings",
  301. "show ratings",
  302. "Show rating data", HandleShow);
  303. m_console.Commands.AddCommand("Objects", false, "backup",
  304. "backup",
  305. "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
  306. m_console.Commands.AddCommand("Regions", false, "create region",
  307. "create region [\"region name\"] <region_file.ini>",
  308. "Create a new region.",
  309. "The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given."
  310. + " If \"region name\" does not exist in <region_file.ini>, it will be added." + Environment.NewLine
  311. + "Without \"region name\", the first region found in <region_file.ini> will be created." + Environment.NewLine
  312. + "If <region_file.ini> does not exist, it will be created.",
  313. HandleCreateRegion);
  314. m_console.Commands.AddCommand("Regions", false, "restart",
  315. "restart",
  316. "Restart all sims in this instance", RunCommand);
  317. m_console.Commands.AddCommand("General", false, "config set",
  318. "config set <section> <key> <value>",
  319. "Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
  320. m_console.Commands.AddCommand("General", false, "config get",
  321. "config get [<section>] [<key>]",
  322. "Synonym for config show",
  323. HandleConfig);
  324. m_console.Commands.AddCommand("General", false, "config show",
  325. "config show [<section>] [<key>]",
  326. "Show config information",
  327. "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
  328. + "If a section is given but not a field, then all fields in that section are printed.",
  329. HandleConfig);
  330. m_console.Commands.AddCommand("General", false, "config save",
  331. "config save <path>",
  332. "Save current configuration to a file at the given path", HandleConfig);
  333. m_console.Commands.AddCommand("General", false, "command-script",
  334. "command-script <script>",
  335. "Run a command script from file", RunCommand);
  336. m_console.Commands.AddCommand("Regions", false, "remove-region",
  337. "remove-region <name>",
  338. "Remove a region from this simulator", RunCommand);
  339. m_console.Commands.AddCommand("Regions", false, "delete-region",
  340. "delete-region <name>",
  341. "Delete a region from disk", RunCommand);
  342. m_console.Commands.AddCommand("General", false, "modules list",
  343. "modules list",
  344. "List modules", HandleModules);
  345. m_console.Commands.AddCommand("General", false, "modules load",
  346. "modules load <name>",
  347. "Load a module", HandleModules);
  348. m_console.Commands.AddCommand("General", false, "modules unload",
  349. "modules unload <name>",
  350. "Unload a module", HandleModules);
  351. }
  352. public override void ShutdownSpecific()
  353. {
  354. if (m_shutdownCommandsFile != String.Empty)
  355. {
  356. RunCommandScript(m_shutdownCommandsFile);
  357. }
  358. base.ShutdownSpecific();
  359. }
  360. /// <summary>
  361. /// Timer to run a specific text file as console commands. Configured in in the main ini file
  362. /// </summary>
  363. /// <param name="sender"></param>
  364. /// <param name="e"></param>
  365. private void RunAutoTimerScript(object sender, EventArgs e)
  366. {
  367. if (m_timedScript != "disabled")
  368. {
  369. RunCommandScript(m_timedScript);
  370. }
  371. }
  372. private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi)
  373. {
  374. int now = Environment.TickCount & Int32.MaxValue;
  375. m_log.ErrorFormat(
  376. "[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}",
  377. twi.Thread.Name,
  378. twi.Thread.ThreadState,
  379. now - twi.LastTick,
  380. twi.AlarmMethod != null ? string.Format("Data: {0}", twi.AlarmMethod()) : "");
  381. }
  382. #region Console Commands
  383. /// <summary>
  384. /// Kicks users off the region
  385. /// </summary>
  386. /// <param name="module"></param>
  387. /// <param name="cmdparams">name of avatar to kick</param>
  388. private void KickUserCommand(string module, string[] cmdparams)
  389. {
  390. bool force = false;
  391. OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; });
  392. List<string> mainParams = options.Parse(cmdparams);
  393. if (mainParams.Count < 4)
  394. return;
  395. string alert = null;
  396. if (mainParams.Count > 4)
  397. alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
  398. IList agents = SceneManager.GetCurrentSceneAvatars();
  399. foreach (ScenePresence presence in agents)
  400. {
  401. RegionInfo regionInfo = presence.Scene.RegionInfo;
  402. if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
  403. presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
  404. {
  405. MainConsole.Instance.Output(
  406. String.Format(
  407. "Kicking user: {0,-16} {1,-16} {2,-37} in region: {3,-16}",
  408. presence.Firstname, presence.Lastname, presence.UUID, regionInfo.RegionName));
  409. // kick client...
  410. if (alert != null)
  411. presence.ControllingClient.Kick(alert);
  412. else
  413. presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
  414. presence.Scene.IncomingCloseAgent(presence.UUID, force);
  415. }
  416. }
  417. MainConsole.Instance.Output("");
  418. }
  419. /// <summary>
  420. /// Run an optional startup list of commands
  421. /// </summary>
  422. /// <param name="fileName"></param>
  423. private void RunCommandScript(string fileName)
  424. {
  425. if (File.Exists(fileName))
  426. {
  427. m_log.Info("[COMMANDFILE]: Running " + fileName);
  428. using (StreamReader readFile = File.OpenText(fileName))
  429. {
  430. string currentCommand;
  431. while ((currentCommand = readFile.ReadLine()) != null)
  432. {
  433. currentCommand = currentCommand.Trim();
  434. if (!(currentCommand == ""
  435. || currentCommand.StartsWith(";")
  436. || currentCommand.StartsWith("//")
  437. || currentCommand.StartsWith("#")))
  438. {
  439. m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'");
  440. m_console.RunCommand(currentCommand);
  441. }
  442. }
  443. }
  444. }
  445. }
  446. /// <summary>
  447. /// Opens a file and uses it as input to the console command parser.
  448. /// </summary>
  449. /// <param name="fileName">name of file to use as input to the console</param>
  450. private static void PrintFileToConsole(string fileName)
  451. {
  452. if (File.Exists(fileName))
  453. {
  454. StreamReader readFile = File.OpenText(fileName);
  455. string currentLine;
  456. while ((currentLine = readFile.ReadLine()) != null)
  457. {
  458. m_log.Info("[!]" + currentLine);
  459. }
  460. }
  461. }
  462. /// <summary>
  463. /// Force resending of all updates to all clients in active region(s)
  464. /// </summary>
  465. /// <param name="module"></param>
  466. /// <param name="args"></param>
  467. private void HandleForceUpdate(string module, string[] args)
  468. {
  469. MainConsole.Instance.Output("Updating all clients");
  470. SceneManager.ForceCurrentSceneClientUpdate();
  471. }
  472. /// <summary>
  473. /// Edits the scale of a primative with the name specified
  474. /// </summary>
  475. /// <param name="module"></param>
  476. /// <param name="args">0,1, name, x, y, z</param>
  477. private void HandleEditScale(string module, string[] args)
  478. {
  479. if (args.Length == 6)
  480. {
  481. SceneManager.HandleEditCommandOnCurrentScene(args);
  482. }
  483. else
  484. {
  485. MainConsole.Instance.Output("Argument error: edit scale <prim name> <x> <y> <z>");
  486. }
  487. }
  488. /// <summary>
  489. /// Creates a new region based on the parameters specified. This will ask the user questions on the console
  490. /// </summary>
  491. /// <param name="module"></param>
  492. /// <param name="cmd">0,1,region name, region ini or XML file</param>
  493. private void HandleCreateRegion(string module, string[] cmd)
  494. {
  495. string regionName = string.Empty;
  496. string regionFile = string.Empty;
  497. if (cmd.Length == 3)
  498. {
  499. regionFile = cmd[2];
  500. }
  501. else if (cmd.Length > 3)
  502. {
  503. regionName = cmd[2];
  504. regionFile = cmd[3];
  505. }
  506. string extension = Path.GetExtension(regionFile).ToLower();
  507. bool isXml = extension.Equals(".xml");
  508. bool isIni = extension.Equals(".ini");
  509. if (!isXml && !isIni)
  510. {
  511. MainConsole.Instance.Output("Usage: create region [\"region name\"] <region_file.ini>");
  512. return;
  513. }
  514. if (!Path.IsPathRooted(regionFile))
  515. {
  516. string regionsDir = ConfigSource.Source.Configs["Startup"].GetString("regionload_regionsdir", "Regions").Trim();
  517. regionFile = Path.Combine(regionsDir, regionFile);
  518. }
  519. RegionInfo regInfo;
  520. if (isXml)
  521. {
  522. regInfo = new RegionInfo(regionName, regionFile, false, ConfigSource.Source);
  523. }
  524. else
  525. {
  526. regInfo = new RegionInfo(regionName, regionFile, false, ConfigSource.Source, regionName);
  527. }
  528. Scene existingScene;
  529. if (SceneManager.TryGetScene(regInfo.RegionID, out existingScene))
  530. {
  531. MainConsole.Instance.OutputFormat(
  532. "ERROR: Cannot create region {0} with ID {1}, this ID is already assigned to region {2}",
  533. regInfo.RegionName, regInfo.RegionID, existingScene.RegionInfo.RegionName);
  534. return;
  535. }
  536. bool changed = PopulateRegionEstateInfo(regInfo);
  537. IScene scene;
  538. CreateRegion(regInfo, true, out scene);
  539. if (changed)
  540. regInfo.EstateSettings.Save();
  541. }
  542. /// <summary>
  543. /// Change and load configuration file data.
  544. /// </summary>
  545. /// <param name="module"></param>
  546. /// <param name="cmd"></param>
  547. private void HandleConfig(string module, string[] cmd)
  548. {
  549. List<string> args = new List<string>(cmd);
  550. args.RemoveAt(0);
  551. string[] cmdparams = args.ToArray();
  552. if (cmdparams.Length > 0)
  553. {
  554. string firstParam = cmdparams[0].ToLower();
  555. switch (firstParam)
  556. {
  557. case "set":
  558. if (cmdparams.Length < 4)
  559. {
  560. Notice("Syntax: config set <section> <key> <value>");
  561. Notice("Example: config set ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
  562. }
  563. else
  564. {
  565. IConfig c;
  566. IConfigSource source = new IniConfigSource();
  567. c = source.AddConfig(cmdparams[1]);
  568. if (c != null)
  569. {
  570. string _value = String.Join(" ", cmdparams, 3, cmdparams.Length - 3);
  571. c.Set(cmdparams[2], _value);
  572. m_config.Source.Merge(source);
  573. Notice("In section [{0}], set {1} = {2}", c.Name, cmdparams[2], _value);
  574. }
  575. }
  576. break;
  577. case "get":
  578. case "show":
  579. if (cmdparams.Length == 1)
  580. {
  581. foreach (IConfig config in m_config.Source.Configs)
  582. {
  583. Notice("[{0}]", config.Name);
  584. string[] keys = config.GetKeys();
  585. foreach (string key in keys)
  586. Notice(" {0} = {1}", key, config.GetString(key));
  587. }
  588. }
  589. else if (cmdparams.Length == 2 || cmdparams.Length == 3)
  590. {
  591. IConfig config = m_config.Source.Configs[cmdparams[1]];
  592. if (config == null)
  593. {
  594. Notice("Section \"{0}\" does not exist.",cmdparams[1]);
  595. break;
  596. }
  597. else
  598. {
  599. if (cmdparams.Length == 2)
  600. {
  601. Notice("[{0}]", config.Name);
  602. foreach (string key in config.GetKeys())
  603. Notice(" {0} = {1}", key, config.GetString(key));
  604. }
  605. else
  606. {
  607. Notice(
  608. "config get {0} {1} : {2}",
  609. cmdparams[1], cmdparams[2], config.GetString(cmdparams[2]));
  610. }
  611. }
  612. }
  613. else
  614. {
  615. Notice("Syntax: config {0} [<section>] [<key>]", firstParam);
  616. Notice("Example: config {0} ScriptEngine.DotNetEngine NumberOfScriptThreads", firstParam);
  617. }
  618. break;
  619. case "save":
  620. if (cmdparams.Length < 2)
  621. {
  622. Notice("Syntax: config save <path>");
  623. return;
  624. }
  625. if (Application.iniFilePath == cmdparams[1])
  626. {
  627. Notice("Path can not be " + Application.iniFilePath);
  628. return;
  629. }
  630. Notice("Saving configuration file: " + cmdparams[1]);
  631. m_config.Save(cmdparams[1]);
  632. break;
  633. }
  634. }
  635. }
  636. /// <summary>
  637. /// Load, Unload, and list Region modules in use
  638. /// </summary>
  639. /// <param name="module"></param>
  640. /// <param name="cmd"></param>
  641. private void HandleModules(string module, string[] cmd)
  642. {
  643. List<string> args = new List<string>(cmd);
  644. args.RemoveAt(0);
  645. string[] cmdparams = args.ToArray();
  646. if (cmdparams.Length > 0)
  647. {
  648. switch (cmdparams[0].ToLower())
  649. {
  650. case "list":
  651. foreach (IRegionModule irm in m_moduleLoader.GetLoadedSharedModules)
  652. {
  653. MainConsole.Instance.Output(String.Format("Shared region module: {0}", irm.Name));
  654. }
  655. break;
  656. case "unload":
  657. if (cmdparams.Length > 1)
  658. {
  659. foreach (IRegionModule rm in new ArrayList(m_moduleLoader.GetLoadedSharedModules))
  660. {
  661. if (rm.Name.ToLower() == cmdparams[1].ToLower())
  662. {
  663. MainConsole.Instance.Output(String.Format("Unloading module: {0}", rm.Name));
  664. m_moduleLoader.UnloadModule(rm);
  665. }
  666. }
  667. }
  668. break;
  669. case "load":
  670. if (cmdparams.Length > 1)
  671. {
  672. foreach (Scene s in new ArrayList(SceneManager.Scenes))
  673. {
  674. MainConsole.Instance.Output(String.Format("Loading module: {0}", cmdparams[1]));
  675. m_moduleLoader.LoadRegionModules(cmdparams[1], s);
  676. }
  677. }
  678. break;
  679. }
  680. }
  681. }
  682. /// <summary>
  683. /// Runs commands issued by the server console from the operator
  684. /// </summary>
  685. /// <param name="command">The first argument of the parameter (the command)</param>
  686. /// <param name="cmdparams">Additional arguments passed to the command</param>
  687. public void RunCommand(string module, string[] cmdparams)
  688. {
  689. List<string> args = new List<string>(cmdparams);
  690. if (args.Count < 1)
  691. return;
  692. string command = args[0];
  693. args.RemoveAt(0);
  694. cmdparams = args.ToArray();
  695. switch (command)
  696. {
  697. case "command-script":
  698. if (cmdparams.Length > 0)
  699. {
  700. RunCommandScript(cmdparams[0]);
  701. }
  702. break;
  703. case "backup":
  704. MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
  705. SceneManager.BackupCurrentScene();
  706. break;
  707. case "remove-region":
  708. string regRemoveName = CombineParams(cmdparams, 0);
  709. Scene removeScene;
  710. if (SceneManager.TryGetScene(regRemoveName, out removeScene))
  711. RemoveRegion(removeScene, false);
  712. else
  713. MainConsole.Instance.Output("No region with that name");
  714. break;
  715. case "delete-region":
  716. string regDeleteName = CombineParams(cmdparams, 0);
  717. Scene killScene;
  718. if (SceneManager.TryGetScene(regDeleteName, out killScene))
  719. RemoveRegion(killScene, true);
  720. else
  721. MainConsole.Instance.Output("no region with that name");
  722. break;
  723. case "restart":
  724. SceneManager.RestartCurrentScene();
  725. break;
  726. }
  727. }
  728. /// <summary>
  729. /// Change the currently selected region. The selected region is that operated upon by single region commands.
  730. /// </summary>
  731. /// <param name="cmdParams"></param>
  732. protected void ChangeSelectedRegion(string module, string[] cmdparams)
  733. {
  734. if (cmdparams.Length > 2)
  735. {
  736. string newRegionName = CombineParams(cmdparams, 2);
  737. if (!SceneManager.TrySetCurrentScene(newRegionName))
  738. MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName));
  739. }
  740. else
  741. {
  742. MainConsole.Instance.Output("Usage: change region <region name>");
  743. }
  744. string regionName = (SceneManager.CurrentScene == null ? "root" : SceneManager.CurrentScene.RegionInfo.RegionName);
  745. MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
  746. // m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
  747. string prompt = m_consolePrompt;
  748. // Replace "\R" with the region name
  749. // Replace "\\" with "\"
  750. prompt = m_consolePromptRegex.Replace(prompt, m =>
  751. {
  752. // m_log.DebugFormat("Matched {0}", m.Groups[2].Value);
  753. if (m.Groups[2].Value == "R")
  754. return m.Groups[1].Value + regionName;
  755. else
  756. return m.Groups[0].Value;
  757. });
  758. m_console.DefaultPrompt = prompt;
  759. m_console.ConsoleScene = SceneManager.CurrentScene;
  760. }
  761. /// <summary>
  762. /// Turn on some debugging values for OpenSim.
  763. /// </summary>
  764. /// <param name="args"></param>
  765. protected void Debug(string module, string[] args)
  766. {
  767. if (args.Length == 1)
  768. return;
  769. switch (args[1])
  770. {
  771. case "packet":
  772. string name = null;
  773. if (args.Length == 5)
  774. name = string.Format("{0} {1}", args[3], args[4]);
  775. if (args.Length > 2)
  776. {
  777. int newDebug;
  778. if (int.TryParse(args[2], out newDebug))
  779. {
  780. SceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
  781. // We provide user information elsewhere if any clients had their debug level set.
  782. // MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
  783. }
  784. else
  785. {
  786. MainConsole.Instance.Output("Usage: debug packet 0..255");
  787. }
  788. }
  789. break;
  790. case "scene":
  791. if (args.Length == 4)
  792. {
  793. if (SceneManager.CurrentScene == null)
  794. {
  795. MainConsole.Instance.Output("Please use 'change region <regioname>' first");
  796. }
  797. else
  798. {
  799. string key = args[2];
  800. string value = args[3];
  801. SceneManager.CurrentScene.SetSceneCoreDebug(
  802. new Dictionary<string, string>() { { key, value } });
  803. MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
  804. }
  805. }
  806. else
  807. {
  808. MainConsole.Instance.Output(
  809. "Usage: debug scene active|scripting|collisions|physics|teleport true|false");
  810. }
  811. break;
  812. default:
  813. MainConsole.Instance.Output("Unknown debug command");
  814. break;
  815. }
  816. }
  817. // see BaseOpenSimServer
  818. /// <summary>
  819. /// Many commands list objects for debugging. Some of the types are listed here
  820. /// </summary>
  821. /// <param name="mod"></param>
  822. /// <param name="cmd"></param>
  823. public override void HandleShow(string mod, string[] cmd)
  824. {
  825. base.HandleShow(mod, cmd);
  826. List<string> args = new List<string>(cmd);
  827. args.RemoveAt(0);
  828. string[] showParams = args.ToArray();
  829. switch (showParams[0])
  830. {
  831. case "users":
  832. IList agents;
  833. if (showParams.Length > 1 && showParams[1] == "full")
  834. {
  835. agents = SceneManager.GetCurrentScenePresences();
  836. } else
  837. {
  838. agents = SceneManager.GetCurrentSceneAvatars();
  839. }
  840. MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
  841. MainConsole.Instance.Output(
  842. String.Format("{0,-16} {1,-16} {2,-37} {3,-11} {4,-16} {5,-30}", "Firstname", "Lastname",
  843. "Agent ID", "Root/Child", "Region", "Position")
  844. );
  845. foreach (ScenePresence presence in agents)
  846. {
  847. RegionInfo regionInfo = presence.Scene.RegionInfo;
  848. string regionName;
  849. if (regionInfo == null)
  850. {
  851. regionName = "Unresolvable";
  852. } else
  853. {
  854. regionName = regionInfo.RegionName;
  855. }
  856. MainConsole.Instance.Output(
  857. String.Format(
  858. "{0,-16} {1,-16} {2,-37} {3,-11} {4,-16} {5,-30}",
  859. presence.Firstname,
  860. presence.Lastname,
  861. presence.UUID,
  862. presence.IsChildAgent ? "Child" : "Root",
  863. regionName,
  864. presence.AbsolutePosition.ToString())
  865. );
  866. }
  867. MainConsole.Instance.Output(String.Empty);
  868. break;
  869. case "connections":
  870. HandleShowConnections();
  871. break;
  872. case "circuits":
  873. HandleShowCircuits();
  874. break;
  875. case "modules":
  876. MainConsole.Instance.Output("The currently loaded shared modules are:");
  877. foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules)
  878. {
  879. MainConsole.Instance.Output("Shared Module: " + module.Name);
  880. }
  881. SceneManager.ForEachScene(
  882. delegate(Scene scene) {
  883. m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
  884. foreach (IRegionModule module in scene.Modules.Values)
  885. {
  886. if (!module.IsSharedModule)
  887. {
  888. m_log.Error("Region Module: " + module.Name);
  889. }
  890. }
  891. }
  892. );
  893. SceneManager.ForEachScene(
  894. delegate(Scene scene) {
  895. MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:");
  896. foreach (IRegionModuleBase module in scene.RegionModules.Values)
  897. {
  898. Type type = module.GetType().GetInterface("ISharedRegionModule");
  899. string module_type = type != null ? "Shared" : "Non-Shared";
  900. MainConsole.Instance.OutputFormat("New Region Module ({0}): {1}", module_type, module.Name);
  901. }
  902. }
  903. );
  904. MainConsole.Instance.Output("");
  905. break;
  906. case "regions":
  907. SceneManager.ForEachScene(
  908. delegate(Scene scene)
  909. {
  910. MainConsole.Instance.Output(String.Format(
  911. "Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}, Estate Name: {4}",
  912. scene.RegionInfo.RegionName,
  913. scene.RegionInfo.RegionLocX,
  914. scene.RegionInfo.RegionLocY,
  915. scene.RegionInfo.InternalEndPoint.Port,
  916. scene.RegionInfo.EstateSettings.EstateName));
  917. });
  918. break;
  919. case "ratings":
  920. SceneManager.ForEachScene(
  921. delegate(Scene scene)
  922. {
  923. string rating = "";
  924. if (scene.RegionInfo.RegionSettings.Maturity == 1)
  925. {
  926. rating = "MATURE";
  927. }
  928. else if (scene.RegionInfo.RegionSettings.Maturity == 2)
  929. {
  930. rating = "ADULT";
  931. }
  932. else
  933. {
  934. rating = "PG";
  935. }
  936. MainConsole.Instance.Output(String.Format(
  937. "Region Name: {0}, Region Rating {1}",
  938. scene.RegionInfo.RegionName,
  939. rating));
  940. });
  941. break;
  942. }
  943. }
  944. private void HandleShowCircuits()
  945. {
  946. ConsoleDisplayTable cdt = new ConsoleDisplayTable();
  947. cdt.AddColumn("Region", 20);
  948. cdt.AddColumn("Avatar name", 24);
  949. cdt.AddColumn("Type", 5);
  950. cdt.AddColumn("Code", 10);
  951. cdt.AddColumn("IP", 16);
  952. cdt.AddColumn("Viewer Name", 24);
  953. SceneManager.ForEachScene(
  954. s =>
  955. {
  956. foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values)
  957. cdt.AddRow(
  958. s.Name,
  959. aCircuit.Name,
  960. aCircuit.child ? "child" : "root",
  961. aCircuit.circuitcode.ToString(),
  962. aCircuit.IPAddress != null ? aCircuit.IPAddress.ToString() : "not set",
  963. aCircuit.Viewer);
  964. });
  965. MainConsole.Instance.Output(cdt.ToString());
  966. }
  967. private void HandleShowConnections()
  968. {
  969. ConsoleDisplayTable cdt = new ConsoleDisplayTable();
  970. cdt.AddColumn("Region", 20);
  971. cdt.AddColumn("Avatar name", 24);
  972. cdt.AddColumn("Circuit code", 12);
  973. cdt.AddColumn("Endpoint", 23);
  974. cdt.AddColumn("Active?", 7);
  975. SceneManager.ForEachScene(
  976. s => s.ForEachClient(
  977. c => cdt.AddRow(
  978. s.Name,
  979. c.Name,
  980. c.CircuitCode.ToString(),
  981. c.RemoteEndPoint.ToString(),
  982. c.IsActive.ToString())));
  983. MainConsole.Instance.Output(cdt.ToString());
  984. }
  985. /// <summary>
  986. /// Use XML2 format to serialize data to a file
  987. /// </summary>
  988. /// <param name="module"></param>
  989. /// <param name="cmdparams"></param>
  990. protected void SavePrimsXml2(string module, string[] cmdparams)
  991. {
  992. if (cmdparams.Length > 5)
  993. {
  994. SceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
  995. }
  996. else
  997. {
  998. SceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
  999. }
  1000. }
  1001. /// <summary>
  1002. /// Use XML format to serialize data to a file
  1003. /// </summary>
  1004. /// <param name="module"></param>
  1005. /// <param name="cmdparams"></param>
  1006. protected void SaveXml(string module, string[] cmdparams)
  1007. {
  1008. MainConsole.Instance.Output("PLEASE NOTE, save-xml is DEPRECATED and may be REMOVED soon. If you are using this and there is some reason you can't use save-xml2, please file a mantis detailing the reason.");
  1009. if (cmdparams.Length > 0)
  1010. {
  1011. SceneManager.SaveCurrentSceneToXml(cmdparams[2]);
  1012. }
  1013. else
  1014. {
  1015. SceneManager.SaveCurrentSceneToXml(DEFAULT_PRIM_BACKUP_FILENAME);
  1016. }
  1017. }
  1018. /// <summary>
  1019. /// Loads data and region objects from XML format.
  1020. /// </summary>
  1021. /// <param name="module"></param>
  1022. /// <param name="cmdparams"></param>
  1023. protected void LoadXml(string module, string[] cmdparams)
  1024. {
  1025. MainConsole.Instance.Output("PLEASE NOTE, load-xml is DEPRECATED and may be REMOVED soon. If you are using this and there is some reason you can't use load-xml2, please file a mantis detailing the reason.");
  1026. Vector3 loadOffset = new Vector3(0, 0, 0);
  1027. if (cmdparams.Length > 2)
  1028. {
  1029. bool generateNewIDS = false;
  1030. if (cmdparams.Length > 3)
  1031. {
  1032. if (cmdparams[3] == "-newUID")
  1033. {
  1034. generateNewIDS = true;
  1035. }
  1036. if (cmdparams.Length > 4)
  1037. {
  1038. loadOffset.X = (float)Convert.ToDecimal(cmdparams[4], Culture.NumberFormatInfo);
  1039. if (cmdparams.Length > 5)
  1040. {
  1041. loadOffset.Y = (float)Convert.ToDecimal(cmdparams[5], Culture.NumberFormatInfo);
  1042. }
  1043. if (cmdparams.Length > 6)
  1044. {
  1045. loadOffset.Z = (float)Convert.ToDecimal(cmdparams[6], Culture.NumberFormatInfo);
  1046. }
  1047. MainConsole.Instance.Output(String.Format("loadOffsets <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
  1048. }
  1049. }
  1050. SceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
  1051. }
  1052. else
  1053. {
  1054. try
  1055. {
  1056. SceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset);
  1057. }
  1058. catch (FileNotFoundException)
  1059. {
  1060. MainConsole.Instance.Output("Default xml not found. Usage: load-xml <filename>");
  1061. }
  1062. }
  1063. }
  1064. /// <summary>
  1065. /// Serialize region data to XML2Format
  1066. /// </summary>
  1067. /// <param name="module"></param>
  1068. /// <param name="cmdparams"></param>
  1069. protected void SaveXml2(string module, string[] cmdparams)
  1070. {
  1071. if (cmdparams.Length > 2)
  1072. {
  1073. SceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
  1074. }
  1075. else
  1076. {
  1077. SceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME);
  1078. }
  1079. }
  1080. /// <summary>
  1081. /// Load region data from Xml2Format
  1082. /// </summary>
  1083. /// <param name="module"></param>
  1084. /// <param name="cmdparams"></param>
  1085. protected void LoadXml2(string module, string[] cmdparams)
  1086. {
  1087. if (cmdparams.Length > 2)
  1088. {
  1089. try
  1090. {
  1091. SceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
  1092. }
  1093. catch (FileNotFoundException)
  1094. {
  1095. MainConsole.Instance.Output("Specified xml not found. Usage: load xml2 <filename>");
  1096. }
  1097. }
  1098. else
  1099. {
  1100. try
  1101. {
  1102. SceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME);
  1103. }
  1104. catch (FileNotFoundException)
  1105. {
  1106. MainConsole.Instance.Output("Default xml not found. Usage: load xml2 <filename>");
  1107. }
  1108. }
  1109. }
  1110. /// <summary>
  1111. /// Load a whole region from an opensimulator archive.
  1112. /// </summary>
  1113. /// <param name="cmdparams"></param>
  1114. protected void LoadOar(string module, string[] cmdparams)
  1115. {
  1116. try
  1117. {
  1118. SceneManager.LoadArchiveToCurrentScene(cmdparams);
  1119. }
  1120. catch (Exception e)
  1121. {
  1122. MainConsole.Instance.Output(e.Message);
  1123. }
  1124. }
  1125. /// <summary>
  1126. /// Save a region to a file, including all the assets needed to restore it.
  1127. /// </summary>
  1128. /// <param name="cmdparams"></param>
  1129. protected void SaveOar(string module, string[] cmdparams)
  1130. {
  1131. SceneManager.SaveCurrentSceneToArchive(cmdparams);
  1132. }
  1133. private static string CombineParams(string[] commandParams, int pos)
  1134. {
  1135. string result = String.Empty;
  1136. for (int i = pos; i < commandParams.Length; i++)
  1137. {
  1138. result += commandParams[i] + " ";
  1139. }
  1140. result = result.TrimEnd(' ');
  1141. return result;
  1142. }
  1143. #endregion
  1144. }
  1145. }