2008-04-28 14:41:46 +00:00
/ *
* Copyright ( c ) Contributors , http : //opensimulator.org/
* See CONTRIBUTORS . TXT for a full list of copyright holders .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
2009-06-01 06:37:14 +00:00
* * Neither the name of the OpenSimulator Project nor the
2008-04-28 14:41:46 +00:00
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ` ` AS IS ' ' AND ANY
* EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
using System ;
2008-05-01 14:45:56 +00:00
using System.Collections ;
2008-04-28 14:41:46 +00:00
using System.Collections.Generic ;
2012-05-31 00:52:26 +00:00
using System.Diagnostics ;
2008-04-28 14:41:46 +00:00
using System.IO ;
2013-02-27 22:25:03 +00:00
using System.Linq ;
2008-05-01 14:45:56 +00:00
using System.Reflection ;
2010-11-17 19:39:12 +00:00
using System.Text ;
2011-11-10 22:56:13 +00:00
using System.Text.RegularExpressions ;
2009-02-12 09:53:12 +00:00
using System.Timers ;
2008-05-01 14:45:56 +00:00
using log4net ;
2012-08-20 19:24:54 +00:00
using NDesk.Options ;
2008-04-28 14:41:46 +00:00
using Nini.Config ;
2009-02-12 09:53:12 +00:00
using OpenMetaverse ;
2008-04-28 14:41:46 +00:00
using OpenSim.Framework ;
using OpenSim.Framework.Console ;
2011-10-25 19:24:21 +00:00
using OpenSim.Framework.Servers ;
2012-07-25 22:11:50 +00:00
using OpenSim.Framework.Monitoring ;
2009-02-06 16:55:34 +00:00
using OpenSim.Region.Framework.Interfaces ;
using OpenSim.Region.Framework.Scenes ;
2014-04-02 04:32:29 +00:00
using OpenSim.Services.Interfaces ;
2008-04-28 14:41:46 +00:00
namespace OpenSim
{
2009-01-12 15:34:05 +00:00
/// <summary>
2008-06-01 01:01:16 +00:00
/// Interactive OpenSim region server
/// </summary>
2009-02-07 12:25:39 +00:00
public class OpenSim : OpenSimBase
2008-05-16 01:22:11 +00:00
{
2008-05-01 14:45:56 +00:00
private static readonly ILog m_log = LogManager . GetLogger ( MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2008-04-28 14:41:46 +00:00
protected string m_startupCommandsFile ;
protected string m_shutdownCommandsFile ;
2009-04-16 12:10:50 +00:00
protected bool m_gui = false ;
2009-08-17 08:21:39 +00:00
protected string m_consoleType = "local" ;
2010-01-11 03:29:24 +00:00
protected uint m_consolePort = 0 ;
2011-11-10 22:56:13 +00:00
/// <summary>
/// Prompt to use for simulator command line.
/// </summary>
private string m_consolePrompt ;
/// <summary>
/// Regex for parsing out special characters in the prompt.
/// </summary>
private Regex m_consolePromptRegex = new Regex ( @"([^\\])\\(\w)" , RegexOptions . Compiled ) ;
2008-04-28 14:41:46 +00:00
private string m_timedScript = "disabled" ;
2012-06-12 21:07:10 +00:00
private int m_timeInterval = 1200 ;
2008-04-28 14:41:46 +00:00
private Timer m_scriptTimer ;
2008-08-19 02:59:27 +00:00
2008-06-01 01:01:16 +00:00
public OpenSim ( IConfigSource configSource ) : base ( configSource )
2008-04-28 14:41:46 +00:00
{
}
2008-11-05 20:14:52 +00:00
protected override void ReadExtraConfigSettings ( )
2008-04-28 14:41:46 +00:00
{
2008-11-06 20:17:20 +00:00
base . ReadExtraConfigSettings ( ) ;
2012-11-22 05:48:41 +00:00
IConfig startupConfig = Config . Configs [ "Startup" ] ;
IConfig networkConfig = Config . Configs [ "Network" ] ;
2008-04-28 14:41:46 +00:00
2013-07-18 09:28:07 +00:00
int stpMinThreads = 2 ;
2009-10-22 08:30:12 +00:00
int stpMaxThreads = 15 ;
2009-10-22 01:28:53 +00:00
2008-04-28 14:41:46 +00:00
if ( startupConfig ! = null )
{
2009-03-11 09:31:02 +00:00
m_startupCommandsFile = startupConfig . GetString ( "startup_console_commands_file" , "startup_commands.txt" ) ;
m_shutdownCommandsFile = startupConfig . GetString ( "shutdown_console_commands_file" , "shutdown_commands.txt" ) ;
2008-04-28 14:41:46 +00:00
2009-08-17 08:21:39 +00:00
if ( startupConfig . GetString ( "console" , String . Empty ) = = String . Empty )
m_gui = startupConfig . GetBoolean ( "gui" , false ) ;
else
m_consoleType = startupConfig . GetString ( "console" , String . Empty ) ;
2009-02-10 12:25:29 +00:00
2010-01-11 07:59:13 +00:00
if ( networkConfig ! = null )
m_consolePort = ( uint ) networkConfig . GetInt ( "console_port" , 0 ) ;
2011-11-10 21:04:12 +00:00
2008-04-28 14:41:46 +00:00
m_timedScript = startupConfig . GetString ( "timer_Script" , "disabled" ) ;
2012-06-12 21:07:10 +00:00
if ( m_timedScript ! = "disabled" )
{
m_timeInterval = startupConfig . GetInt ( "timer_Interval" , 1200 ) ;
}
2011-11-10 21:04:12 +00:00
2009-10-22 06:03:18 +00:00
string asyncCallMethodStr = startupConfig . GetString ( "async_call_method" , String . Empty ) ;
FireAndForgetMethod asyncCallMethod ;
if ( ! String . IsNullOrEmpty ( asyncCallMethodStr ) & & Utils . EnumTryParse < FireAndForgetMethod > ( asyncCallMethodStr , out asyncCallMethod ) )
Util . FireAndForgetMethod = asyncCallMethod ;
2009-10-22 08:30:12 +00:00
2013-07-18 09:28:07 +00:00
stpMinThreads = startupConfig . GetInt ( "MinPoolThreads" , 15 ) ;
2014-08-08 22:47:03 +00:00
stpMaxThreads = startupConfig . GetInt ( "MaxPoolThreads" , 300 ) ;
2011-11-11 23:15:53 +00:00
m_consolePrompt = startupConfig . GetString ( "ConsolePrompt" , @"Region (\R) " ) ;
2008-04-28 14:41:46 +00:00
}
2009-10-22 06:03:18 +00:00
2009-10-22 08:30:12 +00:00
if ( Util . FireAndForgetMethod = = FireAndForgetMethod . SmartThreadPool )
2013-07-18 09:28:07 +00:00
Util . InitThreadPool ( stpMinThreads , stpMaxThreads ) ;
2009-10-22 08:30:12 +00:00
2009-10-22 06:03:18 +00:00
m_log . Info ( "[OPENSIM MAIN]: Using async_call_method " + Util . FireAndForgetMethod ) ;
2008-04-28 14:41:46 +00:00
}
/// <summary>
/// Performs initialisation of the scene, such as loading configuration from disk.
/// </summary>
2008-10-03 15:41:27 +00:00
protected override void StartupSpecific ( )
2008-04-28 14:41:46 +00:00
{
m_log . Info ( "====================================================================" ) ;
m_log . Info ( "========================= STARTING OPENSIM =========================" ) ;
m_log . Info ( "====================================================================" ) ;
2012-05-31 00:52:26 +00:00
2008-12-05 16:20:12 +00:00
//m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString());
2008-12-05 12:59:50 +00:00
// http://msdn.microsoft.com/en-us/library/bb384202.aspx
//GCSettings.LatencyMode = GCLatencyMode.Batch;
2008-12-05 13:12:16 +00:00
//m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString());
2008-05-16 01:22:11 +00:00
2009-05-04 12:15:55 +00:00
if ( m_gui ) // Driven by external GUI
2011-07-29 22:43:35 +00:00
{
2009-05-04 12:15:55 +00:00
m_console = new CommandConsole ( "Region" ) ;
2011-07-29 22:43:35 +00:00
}
2009-05-04 12:15:55 +00:00
else
2009-08-17 08:21:39 +00:00
{
switch ( m_consoleType )
{
case "basic" :
m_console = new CommandConsole ( "Region" ) ;
break ;
case "rest" :
m_console = new RemoteConsole ( "Region" ) ;
2012-11-22 05:48:41 +00:00
( ( RemoteConsole ) m_console ) . ReadConfig ( Config ) ;
2009-08-17 08:21:39 +00:00
break ;
default :
2014-09-22 15:54:12 +00:00
m_console = new LocalConsole ( "Region" , Config . Configs [ "Startup" ] ) ;
2009-08-17 08:21:39 +00:00
break ;
}
}
2008-08-18 00:39:10 +00:00
MainConsole . Instance = m_console ;
2013-03-14 23:39:15 +00:00
LogEnvironmentInformation ( ) ;
2012-11-22 05:48:41 +00:00
RegisterCommonAppenders ( Config . Configs [ "Startup" ] ) ;
2009-02-26 20:01:20 +00:00
RegisterConsoleCommands ( ) ;
2010-01-11 16:11:04 +00:00
base . StartupSpecific ( ) ;
2010-09-12 17:43:49 +00:00
2010-01-11 05:12:01 +00:00
MainServer . Instance . AddStreamHandler ( new OpenSim . SimStatusHandler ( ) ) ;
MainServer . Instance . AddStreamHandler ( new OpenSim . XSimStatusHandler ( this ) ) ;
if ( userStatsURI ! = String . Empty )
MainServer . Instance . AddStreamHandler ( new OpenSim . UXSimStatusHandler ( this ) ) ;
2013-08-06 15:21:16 +00:00
if ( managedStatsURI ! = String . Empty )
{
string urlBase = String . Format ( "/{0}/" , managedStatsURI ) ;
2013-08-08 16:41:11 +00:00
MainServer . Instance . AddHTTPHandler ( urlBase , StatsManager . HandleStatsRequest ) ;
m_log . InfoFormat ( "[OPENSIM] Enabling remote managed stats fetch. URL = {0}" , urlBase ) ;
2013-08-06 15:21:16 +00:00
}
2009-08-17 08:21:39 +00:00
if ( m_console is RemoteConsole )
2010-01-11 03:29:24 +00:00
{
if ( m_consolePort = = 0 )
{
( ( RemoteConsole ) m_console ) . SetServer ( m_httpServer ) ;
}
else
{
( ( RemoteConsole ) m_console ) . SetServer ( MainServer . GetHttpServer ( m_consolePort ) ) ;
}
}
2009-08-17 08:21:39 +00:00
2011-12-17 00:27:19 +00:00
// Hook up to the watchdog timer
Watchdog . OnWatchdogTimeout + = WatchdogTimeoutHandler ;
PrintFileToConsole ( "startuplogo.txt" ) ;
// For now, start at the 'root' level by default
2012-07-25 21:29:40 +00:00
if ( SceneManager . Scenes . Count = = 1 ) // If there is only one region, select it
2011-12-17 00:27:19 +00:00
ChangeSelectedRegion ( "region" ,
2012-07-25 21:29:40 +00:00
new string [ ] { "change" , "region" , SceneManager . Scenes [ 0 ] . RegionInfo . RegionName } ) ;
2011-12-17 00:27:19 +00:00
else
ChangeSelectedRegion ( "region" , new string [ ] { "change" , "region" , "root" } ) ;
2009-02-26 20:01:20 +00:00
//Run Startup Commands
2009-03-10 20:27:41 +00:00
if ( String . IsNullOrEmpty ( m_startupCommandsFile ) )
2009-02-26 20:01:20 +00:00
{
m_log . Info ( "[STARTUP]: No startup command script specified. Moving on..." ) ;
}
else
{
RunCommandScript ( m_startupCommandsFile ) ;
}
// Start timer script (run a script every xx seconds)
if ( m_timedScript ! = "disabled" )
{
m_scriptTimer = new Timer ( ) ;
m_scriptTimer . Enabled = true ;
2012-06-12 21:07:10 +00:00
m_scriptTimer . Interval = m_timeInterval * 1000 ;
2009-02-26 20:01:20 +00:00
m_scriptTimer . Elapsed + = RunAutoTimerScript ;
}
}
2009-08-13 02:54:57 +00:00
/// <summary>
/// Register standard set of region console commands
/// </summary>
2009-02-26 20:01:20 +00:00
private void RegisterConsoleCommands ( )
{
2012-06-15 01:51:52 +00:00
MainServer . RegisterHttpConsoleCommands ( m_console ) ;
2012-04-27 23:08:04 +00:00
m_console . Commands . AddCommand ( "Objects" , false , "force update" ,
2009-03-10 20:27:41 +00:00
"force update" ,
"Force the update of all objects on clients" ,
HandleForceUpdate ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 02:24:37 +00:00
m_console . Commands . AddCommand ( "General" , false , "change region" ,
2009-03-10 20:27:41 +00:00
"change region <region name>" ,
2013-09-26 23:27:11 +00:00
"Change current console region" ,
ChangeSelectedRegion ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Archiving" , false , "save xml" ,
2009-03-10 20:27:41 +00:00
"save xml" ,
2013-09-26 23:27:11 +00:00
"Save a region's data in XML format" ,
SaveXml ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Archiving" , false , "save xml2" ,
2009-03-10 20:27:41 +00:00
"save xml2" ,
2013-09-26 23:27:11 +00:00
"Save a region's data in XML2 format" ,
SaveXml2 ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Archiving" , false , "load xml" ,
2009-03-10 20:27:41 +00:00
"load xml [-newIDs [<x> <y> <z>]]" ,
2013-09-26 23:27:11 +00:00
"Load a region's data from XML format" ,
LoadXml ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Archiving" , false , "load xml2" ,
2009-03-10 20:27:41 +00:00
"load xml2" ,
2013-09-26 23:27:11 +00:00
"Load a region's data from XML2 format" ,
LoadXml2 ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Archiving" , false , "save prims xml2" ,
2009-03-10 20:27:41 +00:00
"save prims xml2 [<prim name> <file name>]" ,
2013-09-26 23:27:11 +00:00
"Save named prim to XML2" ,
SavePrimsXml2 ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Archiving" , false , "load oar" ,
2014-01-19 20:45:16 +00:00
"load oar [--merge] [--skip-assets]"
2014-10-10 23:02:18 +00:00
+ " [--default-user \"User Name\"]"
2014-02-02 20:21:18 +00:00
+ " [--force-terrain] [--force-parcels]"
2014-02-03 06:16:01 +00:00
+ " [--no-objects]"
2014-02-02 20:21:18 +00:00
+ " [--rotation degrees] [--rotation-center \"<x,y,z>\"]"
2014-10-10 23:02:18 +00:00
+ " [--displacement \"<x,y,z>\"]"
2014-01-19 20:45:16 +00:00
+ " [<OAR path>]" ,
2010-05-28 18:36:30 +00:00
"Load a region's data from an OAR archive." ,
2014-10-10 23:02:18 +00:00
"--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading).\n"
+ "--default-user will use this user for any objects with an owner whose UUID is not found in the grid.\n"
+ "--displacement will add this value to the position of every object loaded.\n"
+ "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge).\n"
+ "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge).\n"
+ "--no-objects suppresses the addition of any objects (good for loading only the terrain).\n"
+ "--rotation specified rotation to be applied to the oar. Specified in degrees.\n"
+ "--rotation-center Location (relative to original OAR) to apply rotation. Default is <128,128,0>.\n"
+ "--skip-assets will load the OAR but ignore the assets it contains.\n\n"
+ "The path can be either a filesystem location or a URI.\n"
+ " If this is not given then the command looks for an OAR named region.oar in the current directory." ,
2010-04-16 21:29:11 +00:00
LoadOar ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Archiving" , false , "save oar" ,
2010-12-11 01:57:32 +00:00
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
2012-07-24 16:48:08 +00:00
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [--all] [<OAR path>]" ,
2010-05-28 18:36:30 +00:00
"Save a region's data to an OAR archive." ,
2010-12-11 01:57:32 +00:00
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
2012-08-03 22:54:17 +00:00
"-h|--home=<url> adds the url of the profile service to the saved user information.\n"
+ "--noassets stops assets being saved to the OAR.\n"
+ "--publish saves an OAR stripped of owner and last owner information.\n"
+ " on reload, the estate owner will be the owner of all objects\n"
+ " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published\n"
+ "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR.\n"
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer\n"
2012-07-24 16:48:08 +00:00
+ "--all saves all the regions in the simulator, instead of just the current region.\n"
2011-09-11 17:52:35 +00:00
+ "The OAR path must be a filesystem path."
+ " If this is not given then the oar is saved to region.oar in the current directory." ,
2010-05-28 18:36:30 +00:00
SaveOar ) ;
2009-02-07 12:25:39 +00:00
2012-04-27 23:08:04 +00:00
m_console . Commands . AddCommand ( "Objects" , false , "edit scale" ,
2009-03-10 20:27:41 +00:00
"edit scale <name> <x> <y> <z>" ,
2013-09-26 23:27:11 +00:00
"Change the scale of a named prim" ,
HandleEditScale ) ;
2009-02-07 12:25:39 +00:00
2013-11-27 01:18:44 +00:00
m_console . Commands . AddCommand ( "Objects" , false , "rotate scene" ,
2013-12-10 21:57:18 +00:00
"rotate scene <degrees> [centerX, centerY]" ,
"Rotates all scene objects around centerX, centerY (defailt 128, 128) (please back up your region before using)" ,
2013-11-27 01:18:44 +00:00
HandleRotateScene ) ;
2013-12-10 21:57:18 +00:00
m_console . Commands . AddCommand ( "Objects" , false , "scale scene" ,
"scale scene <factor>" ,
"Scales the scene objects (please back up your region before using)" ,
HandleScaleScene ) ;
m_console . Commands . AddCommand ( "Objects" , false , "translate scene" ,
"translate scene xOffset yOffset zOffset" ,
"translates the scene objects (please back up your region before using)" ,
HandleTranslateScene ) ;
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Users" , false , "kick user" ,
2012-08-20 19:24:54 +00:00
"kick user <first> <last> [--force] [message]" ,
"Kick a user off the simulator" ,
"The --force option will kick the user without any checks to see whether it's already in the process of closing\n"
+ "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them" ,
KickUserCommand ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Users" , false , "show users" ,
2009-03-10 20:27:41 +00:00
"show users [full]" ,
2010-11-17 20:09:18 +00:00
"Show user data for users currently on the region" ,
"Without the 'full' option, only users actually on the region are shown."
+ " With the 'full' option child agents of users in neighbouring regions are also shown." ,
HandleShow ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Comms" , false , "show connections" ,
2009-10-14 20:00:42 +00:00
"show connections" ,
2013-09-26 23:27:11 +00:00
"Show connection data" ,
HandleShow ) ;
2009-10-14 20:00:42 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Comms" , false , "show circuits" ,
2011-02-06 01:57:30 +00:00
"show circuits" ,
2013-09-26 23:27:11 +00:00
"Show agent circuit data" ,
HandleShow ) ;
2011-02-06 01:57:30 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Comms" , false , "show pending-objects" ,
2011-02-07 03:39:29 +00:00
"show pending-objects" ,
2013-09-26 23:27:11 +00:00
"Show # of objects on the pending queues of all scene viewers" ,
HandleShow ) ;
2011-02-07 03:39:29 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "General" , false , "show modules" ,
2009-03-10 20:27:41 +00:00
"show modules" ,
2013-09-26 23:27:11 +00:00
"Show module data" ,
HandleShow ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Regions" , false , "show regions" ,
2009-03-10 20:27:41 +00:00
"show regions" ,
2013-09-26 23:27:11 +00:00
"Show region data" ,
HandleShow ) ;
2010-11-17 19:58:27 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Regions" , false , "show ratings" ,
2009-05-12 03:35:07 +00:00
"show ratings" ,
2013-09-26 23:27:11 +00:00
"Show rating data" ,
HandleShow ) ;
2009-02-07 12:25:39 +00:00
2012-04-27 23:08:04 +00:00
m_console . Commands . AddCommand ( "Objects" , false , "backup" ,
2009-03-10 20:27:41 +00:00
"backup" ,
2013-09-26 23:27:11 +00:00
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call." ,
RunCommand ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Regions" , false , "create region" ,
2010-08-14 10:46:17 +00:00
"create region [\"region name\"] <region_file.ini>" ,
"Create a new region." ,
2010-09-11 07:14:32 +00:00
"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."
2010-08-14 10:46:17 +00:00
+ " If \"region name\" does not exist in <region_file.ini>, it will be added." + Environment . NewLine
+ "Without \"region name\", the first region found in <region_file.ini> will be created." + Environment . NewLine
+ "If <region_file.ini> does not exist, it will be created." ,
HandleCreateRegion ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Regions" , false , "restart" ,
2009-03-10 20:27:41 +00:00
"restart" ,
2015-03-05 22:59:45 +00:00
"Restart the currently selected region(s) in this instance" ,
2013-09-26 23:27:11 +00:00
RunCommand ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "General" , false , "command-script" ,
2009-03-10 20:27:41 +00:00
"command-script <script>" ,
2013-09-26 23:27:11 +00:00
"Run a command script from file" ,
RunCommand ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Regions" , false , "remove-region" ,
2009-03-10 20:27:41 +00:00
"remove-region <name>" ,
2013-09-26 23:27:11 +00:00
"Remove a region from this simulator" ,
RunCommand ) ;
2009-02-07 12:25:39 +00:00
2012-03-08 01:51:37 +00:00
m_console . Commands . AddCommand ( "Regions" , false , "delete-region" ,
2009-03-10 20:27:41 +00:00
"delete-region <name>" ,
2013-09-26 23:27:11 +00:00
"Delete a region from disk" ,
RunCommand ) ;
2014-04-02 04:32:29 +00:00
2014-04-12 21:33:45 +00:00
m_console . Commands . AddCommand ( "Estates" , false , "estate create" ,
"estate create <owner UUID> <estate name>" ,
"Creates a new estate with the specified name, owned by the specified user."
+ " Estate name must be unique." ,
CreateEstateCommand ) ;
2014-04-02 04:32:29 +00:00
m_console . Commands . AddCommand ( "Estates" , false , "estate set owner" ,
"estate set owner <estate-id>[ <UUID> | <Firstname> <Lastname> ]" ,
"Sets the owner of the specified estate to the specified UUID or user. " ,
SetEstateOwnerCommand ) ;
m_console . Commands . AddCommand ( "Estates" , false , "estate set name" ,
"estate set name <estate-id> <new name>" ,
"Sets the name of the specified estate to the specified value. New name must be unique." ,
SetEstateNameCommand ) ;
2014-04-12 21:33:45 +00:00
m_console . Commands . AddCommand ( "Estates" , false , "estate link region" ,
"estate link region <estate ID> <region ID>" ,
"Attaches the specified region to the specified estate." ,
EstateLinkRegionCommand ) ;
2008-04-28 14:41:46 +00:00
}
2013-06-17 21:39:00 +00:00
protected override void ShutdownSpecific ( )
2008-12-11 14:31:58 +00:00
{
if ( m_shutdownCommandsFile ! = String . Empty )
{
RunCommandScript ( m_shutdownCommandsFile ) ;
}
2012-08-20 21:18:29 +00:00
2008-12-11 14:31:58 +00:00
base . ShutdownSpecific ( ) ;
}
2009-01-12 15:34:05 +00:00
2009-08-13 02:54:57 +00:00
/// <summary>
/// Timer to run a specific text file as console commands. Configured in in the main ini file
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
2008-04-28 14:41:46 +00:00
private void RunAutoTimerScript ( object sender , EventArgs e )
{
if ( m_timedScript ! = "disabled" )
{
RunCommandScript ( m_timedScript ) ;
}
}
2012-06-07 01:44:13 +00:00
private void WatchdogTimeoutHandler ( Watchdog . ThreadWatchdogInfo twi )
2009-10-22 19:33:23 +00:00
{
int now = Environment . TickCount & Int32 . MaxValue ;
2012-06-07 01:44:13 +00:00
m_log . ErrorFormat (
"[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}" ,
twi . Thread . Name ,
twi . Thread . ThreadState ,
now - twi . LastTick ,
twi . AlarmMethod ! = null ? string . Format ( "Data: {0}" , twi . AlarmMethod ( ) ) : "" ) ;
2009-10-22 19:33:23 +00:00
}
2008-04-28 14:41:46 +00:00
#region Console Commands
2009-08-13 02:54:57 +00:00
/// <summary>
/// Kicks users off the region
/// </summary>
/// <param name="module"></param>
/// <param name="cmdparams">name of avatar to kick</param>
2009-02-09 16:34:21 +00:00
private void KickUserCommand ( string module , string [ ] cmdparams )
{
2012-08-20 19:24:54 +00:00
bool force = false ;
OptionSet options = new OptionSet ( ) . Add ( "f|force" , delegate ( string v ) { force = v ! = null ; } ) ;
List < string > mainParams = options . Parse ( cmdparams ) ;
if ( mainParams . Count < 4 )
2009-02-09 16:34:21 +00:00
return ;
2009-03-25 18:04:33 +00:00
string alert = null ;
2012-08-20 19:24:54 +00:00
if ( mainParams . Count > 4 )
2009-03-25 18:48:30 +00:00
alert = String . Format ( "\n{0}\n" , String . Join ( " " , cmdparams , 4 , cmdparams . Length - 4 ) ) ;
2009-03-25 18:04:33 +00:00
2012-07-25 21:29:40 +00:00
IList agents = SceneManager . GetCurrentSceneAvatars ( ) ;
2009-02-09 16:34:21 +00:00
foreach ( ScenePresence presence in agents )
{
2010-01-15 23:11:58 +00:00
RegionInfo regionInfo = presence . Scene . RegionInfo ;
2009-02-09 16:34:21 +00:00
2013-07-17 21:55:48 +00:00
if ( presence . Firstname . ToLower ( ) . Equals ( mainParams [ 2 ] . ToLower ( ) ) & &
presence . Lastname . ToLower ( ) . Equals ( mainParams [ 3 ] . ToLower ( ) ) )
2009-02-09 16:34:21 +00:00
{
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output (
2009-02-09 16:34:21 +00:00
String . Format (
2010-08-10 20:39:03 +00:00
"Kicking user: {0,-16} {1,-16} {2,-37} in region: {3,-16}" ,
2009-03-25 18:48:30 +00:00
presence . Firstname , presence . Lastname , presence . UUID , regionInfo . RegionName ) ) ;
2009-02-09 16:34:21 +00:00
2009-03-25 18:48:30 +00:00
// kick client...
if ( alert ! = null )
presence . ControllingClient . Kick ( alert ) ;
2010-02-15 10:15:03 +00:00
else
2009-03-25 18:48:30 +00:00
presence . ControllingClient . Kick ( "\nThe OpenSim manager kicked you out.\n" ) ;
2013-09-27 18:14:21 +00:00
presence . Scene . CloseAgent ( presence . UUID , force ) ;
2013-07-17 21:55:48 +00:00
break ;
2009-02-09 16:34:21 +00:00
}
}
2012-06-07 23:18:25 +00:00
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "" ) ;
2009-02-09 16:34:21 +00:00
}
2008-06-22 05:08:58 +00:00
2009-08-13 02:54:57 +00:00
/// <summary>
/// Opens a file and uses it as input to the console command parser.
/// </summary>
/// <param name="fileName">name of file to use as input to the console</param>
2008-05-01 16:03:53 +00:00
private static void PrintFileToConsole ( string fileName )
2008-04-28 14:41:46 +00:00
{
if ( File . Exists ( fileName ) )
{
StreamReader readFile = File . OpenText ( fileName ) ;
2008-05-02 16:41:08 +00:00
string currentLine ;
2008-04-28 14:41:46 +00:00
while ( ( currentLine = readFile . ReadLine ( ) ) ! = null )
{
m_log . Info ( "[!]" + currentLine ) ;
}
}
}
2009-08-13 02:54:57 +00:00
/// <summary>
/// Force resending of all updates to all clients in active region(s)
/// </summary>
/// <param name="module"></param>
/// <param name="args"></param>
2009-02-07 12:25:39 +00:00
private void HandleForceUpdate ( string module , string [ ] args )
{
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "Updating all clients" ) ;
2012-07-25 21:29:40 +00:00
SceneManager . ForceCurrentSceneClientUpdate ( ) ;
2009-02-07 12:25:39 +00:00
}
2008-05-25 23:27:38 +00:00
2009-08-13 02:54:57 +00:00
/// <summary>
/// Edits the scale of a primative with the name specified
/// </summary>
/// <param name="module"></param>
/// <param name="args">0,1, name, x, y, z</param>
2009-02-07 12:25:39 +00:00
private void HandleEditScale ( string module , string [ ] args )
{
2009-03-24 19:04:28 +00:00
if ( args . Length = = 6 )
2009-02-07 12:25:39 +00:00
{
2012-07-25 21:29:40 +00:00
SceneManager . HandleEditCommandOnCurrentScene ( args ) ;
2009-02-07 12:25:39 +00:00
}
else
{
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "Argument error: edit scale <prim name> <x> <y> <z>" ) ;
2009-02-07 12:25:39 +00:00
}
}
2008-07-01 19:23:45 +00:00
2013-11-27 01:18:44 +00:00
private void HandleRotateScene ( string module , string [ ] args )
{
2013-11-27 05:07:37 +00:00
string usage = "Usage: rotate scene <angle in degrees> [centerX centerY] (centerX and centerY are optional and default to Constants.RegionSize / 2" ;
2013-11-27 01:18:44 +00:00
2013-11-27 05:07:37 +00:00
float centerX = Constants . RegionSize * 0.5f ;
float centerY = Constants . RegionSize * 0.5f ;
if ( args . Length < 3 | | args . Length = = 4 )
2013-11-27 01:18:44 +00:00
{
MainConsole . Instance . Output ( usage ) ;
return ;
}
float angle = ( float ) ( Convert . ToSingle ( args [ 2 ] ) / 180.0 * Math . PI ) ;
OpenMetaverse . Quaternion rot = OpenMetaverse . Quaternion . CreateFromAxisAngle ( 0 , 0 , 1 , angle ) ;
2013-11-27 05:07:37 +00:00
if ( args . Length > 4 )
{
centerX = Convert . ToSingle ( args [ 3 ] ) ;
centerY = Convert . ToSingle ( args [ 4 ] ) ;
}
Vector3 center = new Vector3 ( centerX , centerY , 0.0f ) ;
2013-11-27 01:18:44 +00:00
SceneManager . ForEachSelectedScene ( delegate ( Scene scene )
{
scene . ForEachSOG ( delegate ( SceneObjectGroup sog )
{
2014-02-16 01:10:20 +00:00
if ( ! sog . IsAttachment )
2013-11-27 01:18:44 +00:00
{
sog . RootPart . UpdateRotation ( rot * sog . GroupRotation ) ;
2013-11-27 05:07:37 +00:00
Vector3 offset = sog . AbsolutePosition - center ;
2013-11-27 01:18:44 +00:00
offset * = rot ;
2013-11-27 05:07:37 +00:00
sog . UpdateGroupPosition ( center + offset ) ;
2013-11-27 01:18:44 +00:00
}
} ) ;
} ) ;
2013-12-10 21:57:18 +00:00
}
private void HandleScaleScene ( string module , string [ ] args )
{
string usage = "Usage: scale scene <factor>" ;
if ( args . Length < 3 )
{
MainConsole . Instance . Output ( usage ) ;
return ;
}
float factor = ( float ) ( Convert . ToSingle ( args [ 2 ] ) ) ;
float minZ = float . MaxValue ;
SceneManager . ForEachSelectedScene ( delegate ( Scene scene )
{
scene . ForEachSOG ( delegate ( SceneObjectGroup sog )
{
2014-02-16 01:10:20 +00:00
if ( ! sog . IsAttachment )
2013-12-10 21:57:18 +00:00
{
if ( sog . RootPart . AbsolutePosition . Z < minZ )
minZ = sog . RootPart . AbsolutePosition . Z ;
}
} ) ;
} ) ;
SceneManager . ForEachSelectedScene ( delegate ( Scene scene )
{
scene . ForEachSOG ( delegate ( SceneObjectGroup sog )
{
2014-02-16 01:10:20 +00:00
if ( ! sog . IsAttachment )
2013-12-10 21:57:18 +00:00
{
Vector3 tmpRootPos = sog . RootPart . AbsolutePosition ;
tmpRootPos . Z - = minZ ;
tmpRootPos * = factor ;
tmpRootPos . Z + = minZ ;
foreach ( SceneObjectPart sop in sog . Parts )
{
if ( sop . ParentID ! = 0 )
sop . OffsetPosition * = factor ;
sop . Scale * = factor ;
}
sog . UpdateGroupPosition ( tmpRootPos ) ;
}
} ) ;
} ) ;
}
private void HandleTranslateScene ( string module , string [ ] args )
{
string usage = "Usage: translate scene <xOffset, yOffset, zOffset>" ;
if ( args . Length < 5 )
{
MainConsole . Instance . Output ( usage ) ;
return ;
}
float xOFfset = ( float ) Convert . ToSingle ( args [ 2 ] ) ;
float yOffset = ( float ) Convert . ToSingle ( args [ 3 ] ) ;
float zOffset = ( float ) Convert . ToSingle ( args [ 4 ] ) ;
Vector3 offset = new Vector3 ( xOFfset , yOffset , zOffset ) ;
SceneManager . ForEachSelectedScene ( delegate ( Scene scene )
{
scene . ForEachSOG ( delegate ( SceneObjectGroup sog )
{
2014-02-16 01:10:20 +00:00
if ( ! sog . IsAttachment )
2013-12-10 21:57:18 +00:00
sog . UpdateGroupPosition ( sog . AbsolutePosition + offset ) ;
} ) ;
} ) ;
2013-11-27 01:18:44 +00:00
}
2009-08-13 02:54:57 +00:00
/// <summary>
/// Creates a new region based on the parameters specified. This will ask the user questions on the console
/// </summary>
/// <param name="module"></param>
2010-08-14 10:46:17 +00:00
/// <param name="cmd">0,1,region name, region ini or XML file</param>
2009-02-07 12:25:39 +00:00
private void HandleCreateRegion ( string module , string [ ] cmd )
{
2010-08-14 10:46:17 +00:00
string regionName = string . Empty ;
string regionFile = string . Empty ;
2011-08-06 00:35:01 +00:00
2010-08-14 10:46:17 +00:00
if ( cmd . Length = = 3 )
2009-06-25 23:31:55 +00:00
{
2010-08-14 10:46:17 +00:00
regionFile = cmd [ 2 ] ;
}
else if ( cmd . Length > 3 )
{
regionName = cmd [ 2 ] ;
regionFile = cmd [ 3 ] ;
}
2011-08-06 00:35:01 +00:00
2010-08-14 10:46:17 +00:00
string extension = Path . GetExtension ( regionFile ) . ToLower ( ) ;
bool isXml = extension . Equals ( ".xml" ) ;
bool isIni = extension . Equals ( ".ini" ) ;
2011-08-06 00:35:01 +00:00
2010-08-14 10:46:17 +00:00
if ( ! isXml & & ! isIni )
{
MainConsole . Instance . Output ( "Usage: create region [\"region name\"] <region_file.ini>" ) ;
2009-06-25 23:31:55 +00:00
return ;
}
2011-08-06 00:35:01 +00:00
2010-08-14 10:46:17 +00:00
if ( ! Path . IsPathRooted ( regionFile ) )
2009-06-25 23:31:55 +00:00
{
string regionsDir = ConfigSource . Source . Configs [ "Startup" ] . GetString ( "regionload_regionsdir" , "Regions" ) . Trim ( ) ;
2010-08-14 10:46:17 +00:00
regionFile = Path . Combine ( regionsDir , regionFile ) ;
2009-06-25 23:31:55 +00:00
}
2010-08-14 10:46:17 +00:00
2010-09-10 23:27:52 +00:00
RegionInfo regInfo ;
2010-08-14 10:46:17 +00:00
if ( isXml )
2009-06-25 23:31:55 +00:00
{
2010-09-10 23:27:52 +00:00
regInfo = new RegionInfo ( regionName , regionFile , false , ConfigSource . Source ) ;
2009-06-25 23:31:55 +00:00
}
else
2009-02-07 12:25:39 +00:00
{
2010-09-10 23:27:52 +00:00
regInfo = new RegionInfo ( regionName , regionFile , false , ConfigSource . Source , regionName ) ;
2009-02-07 12:25:39 +00:00
}
2010-09-12 17:43:49 +00:00
2011-08-06 00:35:01 +00:00
Scene existingScene ;
if ( SceneManager . TryGetScene ( regInfo . RegionID , out existingScene ) )
{
MainConsole . Instance . OutputFormat (
"ERROR: Cannot create region {0} with ID {1}, this ID is already assigned to region {2}" ,
regInfo . RegionName , regInfo . RegionID , existingScene . RegionInfo . RegionName ) ;
return ;
}
2012-05-10 16:08:40 +00:00
bool changed = PopulateRegionEstateInfo ( regInfo ) ;
2011-08-06 00:35:01 +00:00
IScene scene ;
2010-09-12 17:43:49 +00:00
CreateRegion ( regInfo , true , out scene ) ;
2008-04-28 14:41:46 +00:00
2012-11-22 05:48:41 +00:00
if ( changed )
2014-06-01 17:06:26 +00:00
m_estateDataService . StoreEstateSettings ( regInfo . EstateSettings ) ;
2015-03-13 23:50:00 +00:00
scene . Start ( ) ;
2009-02-07 12:25:39 +00:00
}
2009-01-12 15:34:05 +00:00
2009-02-07 12:25:39 +00:00
/// <summary>
/// Runs commands issued by the server console from the operator
/// </summary>
/// <param name="command">The first argument of the parameter (the command)</param>
/// <param name="cmdparams">Additional arguments passed to the command</param>
public void RunCommand ( string module , string [ ] cmdparams )
{
List < string > args = new List < string > ( cmdparams ) ;
if ( args . Count < 1 )
return ;
2008-09-18 15:44:05 +00:00
2009-02-07 12:25:39 +00:00
string command = args [ 0 ] ;
args . RemoveAt ( 0 ) ;
2008-04-28 14:41:46 +00:00
2009-02-07 12:25:39 +00:00
cmdparams = args . ToArray ( ) ;
2008-04-28 14:41:46 +00:00
2009-02-07 12:25:39 +00:00
switch ( command )
{
2009-03-10 20:27:41 +00:00
case "backup" :
2011-12-17 02:42:43 +00:00
MainConsole . Instance . Output ( "Triggering save of pending object updates to persistent store" ) ;
2012-07-25 21:29:40 +00:00
SceneManager . BackupCurrentScene ( ) ;
2009-03-10 20:27:41 +00:00
break ;
case "remove-region" :
string regRemoveName = CombineParams ( cmdparams , 0 ) ;
Scene removeScene ;
2012-07-25 21:29:40 +00:00
if ( SceneManager . TryGetScene ( regRemoveName , out removeScene ) )
2009-03-10 20:27:41 +00:00
RemoveRegion ( removeScene , false ) ;
else
2011-12-17 02:42:43 +00:00
MainConsole . Instance . Output ( "No region with that name" ) ;
2009-03-10 20:27:41 +00:00
break ;
case "delete-region" :
string regDeleteName = CombineParams ( cmdparams , 0 ) ;
Scene killScene ;
2012-07-25 21:29:40 +00:00
if ( SceneManager . TryGetScene ( regDeleteName , out killScene ) )
2009-03-10 20:27:41 +00:00
RemoveRegion ( killScene , true ) ;
else
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "no region with that name" ) ;
2009-03-10 20:27:41 +00:00
break ;
case "restart" :
2012-07-25 21:29:40 +00:00
SceneManager . RestartCurrentScene ( ) ;
2009-03-10 20:27:41 +00:00
break ;
2008-04-28 14:41:46 +00:00
}
}
2008-08-18 00:39:10 +00:00
2008-08-05 17:00:35 +00:00
/// <summary>
2008-08-05 17:03:06 +00:00
/// Change the currently selected region. The selected region is that operated upon by single region commands.
2008-08-05 17:00:35 +00:00
/// </summary>
/// <param name="cmdParams"></param>
2009-02-07 12:25:39 +00:00
protected void ChangeSelectedRegion ( string module , string [ ] cmdparams )
2008-08-05 17:00:35 +00:00
{
2009-02-07 12:25:39 +00:00
if ( cmdparams . Length > 2 )
2008-08-05 17:00:35 +00:00
{
2009-02-07 12:25:39 +00:00
string newRegionName = CombineParams ( cmdparams , 2 ) ;
2008-08-05 17:00:35 +00:00
2012-07-25 21:29:40 +00:00
if ( ! SceneManager . TrySetCurrentScene ( newRegionName ) )
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( String . Format ( "Couldn't select region {0}" , newRegionName ) ) ;
2012-11-23 02:22:30 +00:00
else
RefreshPrompt ( ) ;
2008-08-05 17:00:35 +00:00
}
2008-08-05 17:52:06 +00:00
else
{
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "Usage: change region <region name>" ) ;
2008-08-18 00:39:10 +00:00
}
2012-11-23 02:22:30 +00:00
}
2011-11-10 21:04:12 +00:00
2012-11-23 02:22:30 +00:00
/// <summary>
/// Refreshs prompt with the current selection details.
/// </summary>
private void RefreshPrompt ( )
{
2012-07-25 21:29:40 +00:00
string regionName = ( SceneManager . CurrentScene = = null ? "root" : SceneManager . CurrentScene . RegionInfo . RegionName ) ;
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( String . Format ( "Currently selected region is {0}" , regionName ) ) ;
2011-11-10 22:56:13 +00:00
// m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
string prompt = m_consolePrompt ;
// Replace "\R" with the region name
// Replace "\\" with "\"
prompt = m_consolePromptRegex . Replace ( prompt , m = >
{
// m_log.DebugFormat("Matched {0}", m.Groups[2].Value);
if ( m . Groups [ 2 ] . Value = = "R" )
return m . Groups [ 1 ] . Value + regionName ;
else
return m . Groups [ 0 ] . Value ;
} ) ;
m_console . DefaultPrompt = prompt ;
2012-07-25 21:29:40 +00:00
m_console . ConsoleScene = SceneManager . CurrentScene ;
2008-08-05 17:00:35 +00:00
}
2008-08-18 00:39:10 +00:00
2012-11-23 02:22:30 +00:00
protected override void HandleRestartRegion ( RegionInfo whichRegion )
{
base . HandleRestartRegion ( whichRegion ) ;
// Where we are restarting multiple scenes at once, a previous call to RefreshPrompt may have set the
// m_console.ConsoleScene to null (indicating all scenes).
if ( m_console . ConsoleScene ! = null & & whichRegion . RegionName = = ( ( Scene ) m_console . ConsoleScene ) . Name )
SceneManager . TrySetCurrentScene ( whichRegion . RegionName ) ;
RefreshPrompt ( ) ;
}
2008-04-28 14:41:46 +00:00
// see BaseOpenSimServer
2009-08-13 02:54:57 +00:00
/// <summary>
/// Many commands list objects for debugging. Some of the types are listed here
/// </summary>
/// <param name="mod"></param>
/// <param name="cmd"></param>
2009-03-10 20:27:41 +00:00
public override void HandleShow ( string mod , string [ ] cmd )
2008-04-28 14:41:46 +00:00
{
2009-02-09 18:11:09 +00:00
base . HandleShow ( mod , cmd ) ;
2009-03-10 20:27:41 +00:00
2009-02-07 12:25:39 +00:00
List < string > args = new List < string > ( cmd ) ;
args . RemoveAt ( 0 ) ;
string [ ] showParams = args . ToArray ( ) ;
2008-05-16 01:22:11 +00:00
2008-09-12 22:39:17 +00:00
switch ( showParams [ 0 ] )
2008-04-28 14:41:46 +00:00
{
2008-05-22 04:55:23 +00:00
case "users" :
2008-09-12 22:39:17 +00:00
IList agents ;
if ( showParams . Length > 1 & & showParams [ 1 ] = = "full" )
{
2012-07-25 21:29:40 +00:00
agents = SceneManager . GetCurrentScenePresences ( ) ;
2012-06-04 21:22:46 +00:00
} else
2008-09-12 22:39:17 +00:00
{
2012-07-25 21:29:40 +00:00
agents = SceneManager . GetCurrentSceneAvatars ( ) ;
2008-09-12 22:39:17 +00:00
}
2010-11-17 20:09:18 +00:00
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( String . Format ( "\nAgents connected: {0}\n" , agents . Count ) ) ;
2008-05-25 23:27:38 +00:00
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output (
2010-08-10 20:39:03 +00:00
String . Format ( "{0,-16} {1,-16} {2,-37} {3,-11} {4,-16} {5,-30}" , "Firstname" , "Lastname" ,
2012-06-04 21:22:46 +00:00
"Agent ID" , "Root/Child" , "Region" , "Position" )
) ;
2008-05-22 04:55:23 +00:00
foreach ( ScenePresence presence in agents )
{
2010-01-15 23:11:58 +00:00
RegionInfo regionInfo = presence . Scene . RegionInfo ;
2008-05-22 04:55:23 +00:00
string regionName ;
if ( regionInfo = = null )
{
regionName = "Unresolvable" ;
2012-06-04 21:22:46 +00:00
} else
2008-05-22 04:55:23 +00:00
{
regionName = regionInfo . RegionName ;
}
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output (
2008-05-22 04:55:23 +00:00
String . Format (
2010-08-10 20:39:03 +00:00
"{0,-16} {1,-16} {2,-37} {3,-11} {4,-16} {5,-30}" ,
2008-09-03 03:32:29 +00:00
presence . Firstname ,
presence . Lastname ,
presence . UUID ,
presence . IsChildAgent ? "Child" : "Root" ,
2009-11-30 09:09:03 +00:00
regionName ,
2012-06-04 21:22:46 +00:00
presence . AbsolutePosition . ToString ( ) )
) ;
2008-05-22 04:55:23 +00:00
}
2008-05-25 23:27:38 +00:00
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( String . Empty ) ;
2009-10-14 20:00:42 +00:00
break ;
case "connections" :
2012-07-12 20:36:33 +00:00
HandleShowConnections ( ) ;
2008-05-22 04:55:23 +00:00
break ;
2011-02-06 01:57:30 +00:00
case "circuits" :
2012-07-12 22:09:36 +00:00
HandleShowCircuits ( ) ;
2011-02-06 01:57:30 +00:00
break ;
2008-04-28 14:41:46 +00:00
case "modules" :
2013-02-27 22:31:47 +00:00
SceneManager . ForEachSelectedScene (
2013-02-27 22:25:03 +00:00
scene = >
2012-06-04 21:22:46 +00:00
{
2013-02-27 22:25:03 +00:00
MainConsole . Instance . OutputFormat ( "Loaded region modules in {0} are:" , scene . Name ) ;
List < IRegionModuleBase > sharedModules = new List < IRegionModuleBase > ( ) ;
List < IRegionModuleBase > nonSharedModules = new List < IRegionModuleBase > ( ) ;
foreach ( IRegionModuleBase module in scene . RegionModules . Values )
{
2014-07-09 22:24:12 +00:00
if ( module . GetType ( ) . GetInterface ( "ISharedRegionModule" ) = = null )
2013-02-27 22:25:03 +00:00
nonSharedModules . Add ( module ) ;
else
sharedModules . Add ( module ) ;
}
foreach ( IRegionModuleBase module in sharedModules . OrderBy ( m = > m . Name ) )
MainConsole . Instance . OutputFormat ( "New Region Module (Shared): {0}" , module . Name ) ;
2013-11-19 23:53:15 +00:00
foreach ( IRegionModuleBase module in nonSharedModules . OrderBy ( m = > m . Name ) )
2013-02-27 22:25:03 +00:00
MainConsole . Instance . OutputFormat ( "New Region Module (Non-Shared): {0}" , module . Name ) ;
2012-06-04 21:22:46 +00:00
}
) ;
2011-10-31 23:42:28 +00:00
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "" ) ;
2008-04-28 14:41:46 +00:00
break ;
case "regions" :
2014-03-05 01:23:16 +00:00
ConsoleDisplayTable cdt = new ConsoleDisplayTable ( ) ;
cdt . AddColumn ( "Name" , ConsoleDisplayUtil . RegionNameSize ) ;
cdt . AddColumn ( "ID" , ConsoleDisplayUtil . UuidSize ) ;
cdt . AddColumn ( "Position" , ConsoleDisplayUtil . CoordTupleSize ) ;
2014-07-04 23:20:39 +00:00
cdt . AddColumn ( "Size" , 11 ) ;
2014-03-05 01:23:16 +00:00
cdt . AddColumn ( "Port" , ConsoleDisplayUtil . PortSize ) ;
cdt . AddColumn ( "Ready?" , 6 ) ;
cdt . AddColumn ( "Estate" , ConsoleDisplayUtil . EstateNameSize ) ;
2012-07-25 21:29:40 +00:00
SceneManager . ForEachScene (
2014-03-05 01:23:16 +00:00
scene = >
{
RegionInfo ri = scene . RegionInfo ;
cdt . AddRow (
2014-07-04 23:20:39 +00:00
ri . RegionName ,
ri . RegionID ,
string . Format ( "{0},{1}" , ri . RegionLocX , ri . RegionLocY ) ,
string . Format ( "{0}x{1}" , ri . RegionSizeX , ri . RegionSizeY ) ,
ri . InternalEndPoint . Port ,
scene . Ready ? "Yes" : "No" ,
ri . EstateSettings . EstateName ) ;
2014-03-05 01:23:16 +00:00
}
) ;
MainConsole . Instance . Output ( cdt . ToString ( ) ) ;
2008-04-28 14:41:46 +00:00
break ;
2008-12-18 13:16:41 +00:00
2009-05-12 03:35:07 +00:00
case "ratings" :
2012-07-25 21:29:40 +00:00
SceneManager . ForEachScene (
2009-05-12 03:35:07 +00:00
delegate ( Scene scene )
{
string rating = "" ;
if ( scene . RegionInfo . RegionSettings . Maturity = = 1 )
{
rating = "MATURE" ;
}
else if ( scene . RegionInfo . RegionSettings . Maturity = = 2 )
{
rating = "ADULT" ;
}
else
{
rating = "PG" ;
}
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( String . Format (
"Region Name: {0}, Region Rating {1}" ,
scene . RegionInfo . RegionName ,
rating ) ) ;
2009-05-12 03:35:07 +00:00
} ) ;
break ;
2008-04-28 14:41:46 +00:00
}
}
2008-08-18 00:39:10 +00:00
2012-07-12 22:09:36 +00:00
private void HandleShowCircuits ( )
{
ConsoleDisplayTable cdt = new ConsoleDisplayTable ( ) ;
cdt . AddColumn ( "Region" , 20 ) ;
cdt . AddColumn ( "Avatar name" , 24 ) ;
cdt . AddColumn ( "Type" , 5 ) ;
cdt . AddColumn ( "Code" , 10 ) ;
cdt . AddColumn ( "IP" , 16 ) ;
cdt . AddColumn ( "Viewer Name" , 24 ) ;
2012-07-25 21:29:40 +00:00
SceneManager . ForEachScene (
2012-07-12 22:09:36 +00:00
s = >
{
foreach ( AgentCircuitData aCircuit in s . AuthenticateHandler . GetAgentCircuits ( ) . Values )
cdt . AddRow (
s . Name ,
aCircuit . Name ,
aCircuit . child ? "child" : "root" ,
aCircuit . circuitcode . ToString ( ) ,
2012-10-29 23:22:40 +00:00
aCircuit . IPAddress ! = null ? aCircuit . IPAddress . ToString ( ) : "not set" ,
2013-12-08 14:50:24 +00:00
Util . GetViewerName ( aCircuit ) ) ;
2012-07-12 22:09:36 +00:00
} ) ;
MainConsole . Instance . Output ( cdt . ToString ( ) ) ;
}
2012-07-12 20:36:33 +00:00
private void HandleShowConnections ( )
{
ConsoleDisplayTable cdt = new ConsoleDisplayTable ( ) ;
cdt . AddColumn ( "Region" , 20 ) ;
2012-07-12 22:09:36 +00:00
cdt . AddColumn ( "Avatar name" , 24 ) ;
cdt . AddColumn ( "Circuit code" , 12 ) ;
cdt . AddColumn ( "Endpoint" , 23 ) ;
2012-07-12 21:37:48 +00:00
cdt . AddColumn ( "Active?" , 7 ) ;
2012-07-12 20:36:33 +00:00
2012-07-25 21:29:40 +00:00
SceneManager . ForEachScene (
2012-07-12 20:36:33 +00:00
s = > s . ForEachClient (
2012-07-12 21:37:48 +00:00
c = > cdt . AddRow (
2012-07-12 22:09:36 +00:00
s . Name ,
2012-07-12 21:37:48 +00:00
c . Name ,
c . CircuitCode . ToString ( ) ,
2012-07-19 22:35:56 +00:00
c . RemoteEndPoint . ToString ( ) ,
2012-07-12 21:37:48 +00:00
c . IsActive . ToString ( ) ) ) ) ;
2012-07-12 20:36:33 +00:00
MainConsole . Instance . Output ( cdt . ToString ( ) ) ;
}
2009-08-13 02:54:57 +00:00
/// <summary>
/// Use XML2 format to serialize data to a file
/// </summary>
/// <param name="module"></param>
/// <param name="cmdparams"></param>
2009-02-07 12:25:39 +00:00
protected void SavePrimsXml2 ( string module , string [ ] cmdparams )
{
if ( cmdparams . Length > 5 )
{
2012-07-25 21:29:40 +00:00
SceneManager . SaveNamedPrimsToXml2 ( cmdparams [ 3 ] , cmdparams [ 4 ] ) ;
2009-02-07 12:25:39 +00:00
}
else
{
2012-07-25 21:29:40 +00:00
SceneManager . SaveNamedPrimsToXml2 ( "Primitive" , DEFAULT_PRIM_BACKUP_FILENAME ) ;
2009-02-07 12:25:39 +00:00
}
}
2009-08-13 02:54:57 +00:00
/// <summary>
/// Use XML format to serialize data to a file
/// </summary>
/// <param name="module"></param>
/// <param name="cmdparams"></param>
2009-02-07 12:25:39 +00:00
protected void SaveXml ( string module , string [ ] cmdparams )
2008-07-12 20:14:17 +00:00
{
2010-01-19 23:50:30 +00:00
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." ) ;
2008-07-12 20:14:17 +00:00
if ( cmdparams . Length > 0 )
{
2012-07-25 21:29:40 +00:00
SceneManager . SaveCurrentSceneToXml ( cmdparams [ 2 ] ) ;
2008-07-12 20:14:17 +00:00
}
else
{
2012-07-25 21:29:40 +00:00
SceneManager . SaveCurrentSceneToXml ( DEFAULT_PRIM_BACKUP_FILENAME ) ;
2008-07-12 20:14:17 +00:00
}
2008-08-18 00:39:10 +00:00
}
2009-08-13 02:54:57 +00:00
/// <summary>
/// Loads data and region objects from XML format.
/// </summary>
/// <param name="module"></param>
/// <param name="cmdparams"></param>
2009-02-07 12:25:39 +00:00
protected void LoadXml ( string module , string [ ] cmdparams )
2008-07-12 20:14:17 +00:00
{
2010-01-19 23:50:30 +00:00
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." ) ;
2008-07-12 20:14:17 +00:00
2008-09-06 07:52:41 +00:00
Vector3 loadOffset = new Vector3 ( 0 , 0 , 0 ) ;
2009-02-07 12:25:39 +00:00
if ( cmdparams . Length > 2 )
2008-07-12 20:14:17 +00:00
{
bool generateNewIDS = false ;
2009-02-07 12:25:39 +00:00
if ( cmdparams . Length > 3 )
2008-07-12 20:14:17 +00:00
{
2009-02-07 12:25:39 +00:00
if ( cmdparams [ 3 ] = = "-newUID" )
2008-07-12 20:14:17 +00:00
{
generateNewIDS = true ;
}
2009-02-07 12:25:39 +00:00
if ( cmdparams . Length > 4 )
2008-07-12 20:14:17 +00:00
{
2010-02-12 23:13:35 +00:00
loadOffset . X = ( float ) Convert . ToDecimal ( cmdparams [ 4 ] , Culture . NumberFormatInfo ) ;
2009-02-07 12:25:39 +00:00
if ( cmdparams . Length > 5 )
2008-07-12 20:14:17 +00:00
{
2010-02-12 23:13:35 +00:00
loadOffset . Y = ( float ) Convert . ToDecimal ( cmdparams [ 5 ] , Culture . NumberFormatInfo ) ;
2008-07-12 20:14:17 +00:00
}
2009-02-07 12:25:39 +00:00
if ( cmdparams . Length > 6 )
2008-07-12 20:14:17 +00:00
{
2010-02-12 23:13:35 +00:00
loadOffset . Z = ( float ) Convert . ToDecimal ( cmdparams [ 6 ] , Culture . NumberFormatInfo ) ;
2008-07-12 20:14:17 +00:00
}
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( String . Format ( "loadOffsets <X,Y,Z> = <{0},{1},{2}>" , loadOffset . X , loadOffset . Y , loadOffset . Z ) ) ;
2008-07-12 20:14:17 +00:00
}
}
2012-07-25 21:29:40 +00:00
SceneManager . LoadCurrentSceneFromXml ( cmdparams [ 2 ] , generateNewIDS , loadOffset ) ;
2008-07-12 20:14:17 +00:00
}
else
{
2009-01-12 15:34:05 +00:00
try
{
2012-07-25 21:29:40 +00:00
SceneManager . LoadCurrentSceneFromXml ( DEFAULT_PRIM_BACKUP_FILENAME , false , loadOffset ) ;
2009-01-12 15:34:05 +00:00
}
2009-03-25 19:21:28 +00:00
catch ( FileNotFoundException )
2009-01-12 15:34:05 +00:00
{
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "Default xml not found. Usage: load-xml <filename>" ) ;
2009-01-12 15:34:05 +00:00
}
2008-07-12 20:14:17 +00:00
}
2008-08-18 00:39:10 +00:00
}
2009-08-13 02:54:57 +00:00
/// <summary>
/// Serialize region data to XML2Format
/// </summary>
/// <param name="module"></param>
/// <param name="cmdparams"></param>
2009-02-07 12:25:39 +00:00
protected void SaveXml2 ( string module , string [ ] cmdparams )
2008-07-12 20:14:17 +00:00
{
2009-02-07 12:25:39 +00:00
if ( cmdparams . Length > 2 )
2008-07-12 20:14:17 +00:00
{
2012-07-25 21:29:40 +00:00
SceneManager . SaveCurrentSceneToXml2 ( cmdparams [ 2 ] ) ;
2008-07-12 20:14:17 +00:00
}
else
{
2012-07-25 21:29:40 +00:00
SceneManager . SaveCurrentSceneToXml2 ( DEFAULT_PRIM_BACKUP_FILENAME ) ;
2008-07-12 20:14:17 +00:00
}
}
2008-08-18 00:39:10 +00:00
2009-08-13 02:54:57 +00:00
/// <summary>
/// Load region data from Xml2Format
/// </summary>
/// <param name="module"></param>
/// <param name="cmdparams"></param>
2009-02-07 12:25:39 +00:00
protected void LoadXml2 ( string module , string [ ] cmdparams )
2008-07-12 20:14:17 +00:00
{
2009-02-07 12:25:39 +00:00
if ( cmdparams . Length > 2 )
2008-07-12 20:14:17 +00:00
{
2009-02-26 21:00:33 +00:00
try
{
2012-07-25 21:29:40 +00:00
SceneManager . LoadCurrentSceneFromXml2 ( cmdparams [ 2 ] ) ;
2009-02-26 21:00:33 +00:00
}
2009-03-25 19:21:28 +00:00
catch ( FileNotFoundException )
2009-02-26 21:00:33 +00:00
{
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "Specified xml not found. Usage: load xml2 <filename>" ) ;
2009-02-26 21:00:33 +00:00
}
2008-07-12 20:14:17 +00:00
}
else
{
2009-01-12 15:34:05 +00:00
try
{
2012-07-25 21:29:40 +00:00
SceneManager . LoadCurrentSceneFromXml2 ( DEFAULT_PRIM_BACKUP_FILENAME ) ;
2009-01-12 15:34:05 +00:00
}
2009-03-25 19:21:28 +00:00
catch ( FileNotFoundException )
2009-01-12 15:34:05 +00:00
{
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( "Default xml not found. Usage: load xml2 <filename>" ) ;
2009-01-12 15:34:05 +00:00
}
2008-07-12 20:14:17 +00:00
}
2008-08-18 00:39:10 +00:00
}
2008-07-29 14:28:08 +00:00
/// <summary>
2009-07-10 11:03:38 +00:00
/// Load a whole region from an opensimulator archive.
2008-07-29 14:28:08 +00:00
/// </summary>
/// <param name="cmdparams"></param>
2009-02-07 12:25:39 +00:00
protected void LoadOar ( string module , string [ ] cmdparams )
2008-07-12 20:14:17 +00:00
{
2009-05-18 18:44:55 +00:00
try
2009-09-30 16:00:09 +00:00
{
2012-07-25 21:29:40 +00:00
SceneManager . LoadArchiveToCurrentScene ( cmdparams ) ;
2008-07-12 20:14:17 +00:00
}
2009-05-18 18:44:55 +00:00
catch ( Exception e )
2008-07-12 20:14:17 +00:00
{
2010-01-19 23:50:30 +00:00
MainConsole . Instance . Output ( e . Message ) ;
2009-09-30 16:00:09 +00:00
}
2008-07-12 20:14:17 +00:00
}
2008-08-18 00:39:10 +00:00
2008-07-29 14:28:08 +00:00
/// <summary>
/// Save a region to a file, including all the assets needed to restore it.
/// </summary>
/// <param name="cmdparams"></param>
2009-02-07 12:25:39 +00:00
protected void SaveOar ( string module , string [ ] cmdparams )
2008-07-12 20:14:17 +00:00
{
2012-07-25 21:29:40 +00:00
SceneManager . SaveCurrentSceneToArchive ( cmdparams ) ;
2008-08-18 00:39:10 +00:00
}
2009-01-12 15:34:05 +00:00
2014-04-12 21:33:45 +00:00
protected void CreateEstateCommand ( string module , string [ ] args )
{
string response = null ;
UUID userID ;
if ( args . Length = = 2 )
{
response = "No user specified." ;
}
else if ( ! UUID . TryParse ( args [ 2 ] , out userID ) )
{
response = String . Format ( "{0} is not a valid UUID" , args [ 2 ] ) ;
}
else if ( args . Length = = 3 )
{
response = "No estate name specified." ;
}
else
{
Scene scene = SceneManager . CurrentOrFirstScene ;
// TODO: Is there a better choice here?
UUID scopeID = UUID . Zero ;
UserAccount account = scene . UserAccountService . GetUserAccount ( scopeID , userID ) ;
if ( account = = null )
{
response = String . Format ( "Could not find user {0}" , userID ) ;
}
else
{
// concatenate it all to "name"
StringBuilder sb = new StringBuilder ( args [ 3 ] ) ;
for ( int i = 4 ; i < args . Length ; i + + )
sb . Append ( " " + args [ i ] ) ;
string estateName = sb . ToString ( ) . Trim ( ) ;
// send it off for processing.
IEstateModule estateModule = scene . RequestModuleInterface < IEstateModule > ( ) ;
response = estateModule . CreateEstate ( estateName , userID ) ;
if ( response = = String . Empty )
{
List < int > estates = scene . EstateDataService . GetEstates ( estateName ) ;
response = String . Format ( "Estate {0} created as \"{1}\"" , estates . ElementAt ( 0 ) , estateName ) ;
}
}
}
// give the user some feedback
if ( response ! = null )
MainConsole . Instance . Output ( response ) ;
}
2014-04-02 04:32:29 +00:00
protected void SetEstateOwnerCommand ( string module , string [ ] args )
{
string response = null ;
Scene scene = SceneManager . CurrentOrFirstScene ;
IEstateModule estateModule = scene . RequestModuleInterface < IEstateModule > ( ) ;
if ( args . Length = = 3 )
{
response = "No estate specified." ;
}
else
{
int estateId ;
if ( ! int . TryParse ( args [ 3 ] , out estateId ) )
{
response = String . Format ( "\"{0}\" is not a valid ID for an Estate" , args [ 3 ] ) ;
}
else
{
if ( args . Length = = 4 )
{
response = "No user specified." ;
}
else
{
UserAccount account = null ;
// TODO: Is there a better choice here?
UUID scopeID = UUID . Zero ;
string s1 = args [ 4 ] ;
if ( args . Length = = 5 )
{
// attempt to get account by UUID
UUID u ;
if ( UUID . TryParse ( s1 , out u ) )
{
account = scene . UserAccountService . GetUserAccount ( scopeID , u ) ;
if ( account = = null )
response = String . Format ( "Could not find user {0}" , s1 ) ;
}
else
{
response = String . Format ( "Invalid UUID {0}" , s1 ) ;
}
}
else
{
// attempt to get account by Firstname, Lastname
string s2 = args [ 5 ] ;
account = scene . UserAccountService . GetUserAccount ( scopeID , s1 , s2 ) ;
if ( account = = null )
response = String . Format ( "Could not find user {0} {1}" , s1 , s2 ) ;
}
// If it's valid, send it off for processing.
if ( account ! = null )
response = estateModule . SetEstateOwner ( estateId , account ) ;
if ( response = = String . Empty )
{
response = String . Format ( "Estate owner changed to {0} ({1} {2})" , account . PrincipalID , account . FirstName , account . LastName ) ;
}
}
}
}
// give the user some feedback
if ( response ! = null )
MainConsole . Instance . Output ( response ) ;
}
protected void SetEstateNameCommand ( string module , string [ ] args )
{
string response = null ;
Scene scene = SceneManager . CurrentOrFirstScene ;
IEstateModule estateModule = scene . RequestModuleInterface < IEstateModule > ( ) ;
if ( args . Length = = 3 )
{
response = "No estate specified." ;
}
else
{
int estateId ;
if ( ! int . TryParse ( args [ 3 ] , out estateId ) )
{
response = String . Format ( "\"{0}\" is not a valid ID for an Estate" , args [ 3 ] ) ;
}
else
{
if ( args . Length = = 4 )
{
response = "No name specified." ;
}
else
{
// everything after the estate ID is "name"
StringBuilder sb = new StringBuilder ( args [ 4 ] ) ;
for ( int i = 5 ; i < args . Length ; i + + )
sb . Append ( " " + args [ i ] ) ;
string estateName = sb . ToString ( ) ;
// send it off for processing.
response = estateModule . SetEstateName ( estateId , estateName ) ;
if ( response = = String . Empty )
{
response = String . Format ( "Estate {0} renamed to \"{1}\"" , estateId , estateName ) ;
}
}
}
}
// give the user some feedback
if ( response ! = null )
MainConsole . Instance . Output ( response ) ;
}
2014-04-12 21:33:45 +00:00
private void EstateLinkRegionCommand ( string module , string [ ] args )
{
int estateId = - 1 ;
UUID regionId = UUID . Zero ;
Scene scene = null ;
string response = null ;
if ( args . Length = = 3 )
{
response = "No estate specified." ;
}
else if ( ! int . TryParse ( args [ 3 ] , out estateId ) )
{
response = String . Format ( "\"{0}\" is not a valid ID for an Estate" , args [ 3 ] ) ;
}
else if ( args . Length = = 4 )
{
response = "No region specified." ;
}
else if ( ! UUID . TryParse ( args [ 4 ] , out regionId ) )
{
response = String . Format ( "\"{0}\" is not a valid UUID for a Region" , args [ 4 ] ) ;
}
else if ( ! SceneManager . TryGetScene ( regionId , out scene ) )
{
// region may exist, but on a different sim.
response = String . Format ( "No access to Region \"{0}\"" , args [ 4 ] ) ;
}
if ( response ! = null )
{
MainConsole . Instance . Output ( response ) ;
return ;
}
// send it off for processing.
IEstateModule estateModule = scene . RequestModuleInterface < IEstateModule > ( ) ;
response = estateModule . SetRegionEstate ( scene . RegionInfo , estateId ) ;
if ( response = = String . Empty )
{
estateModule . TriggerRegionInfoChange ( ) ;
estateModule . sendRegionHandshakeToAll ( ) ;
response = String . Format ( "Region {0} is now attached to estate {1}" , regionId , estateId ) ;
}
// give the user some feedback
if ( response ! = null )
MainConsole . Instance . Output ( response ) ;
}
2014-04-02 04:32:29 +00:00
# endregion
2008-05-01 16:03:53 +00:00
private static string CombineParams ( string [ ] commandParams , int pos )
2008-04-28 14:41:46 +00:00
{
string result = String . Empty ;
for ( int i = pos ; i < commandParams . Length ; i + + )
{
result + = commandParams [ i ] + " " ;
}
result = result . TrimEnd ( ' ' ) ;
return result ;
}
2008-06-09 08:46:33 +00:00
}
2009-04-05 10:31:18 +00:00
}