Merge branch 'dev' of ssh://sceneapi@island.sciencesim.com/home/sceneapi/sceneapi into dev
						commit
						6ec6fe6745
					
				|  | @ -50,8 +50,8 @@ namespace OpenSim.Framework.Capabilities | |||
| 
 | ||||
|     public class Caps | ||||
|     { | ||||
|         private static readonly ILog m_log = | ||||
|             LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| //        private static readonly ILog m_log = | ||||
| //            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private string m_httpListenerHostName; | ||||
|         private uint m_httpListenPort; | ||||
|  |  | |||
|  | @ -73,7 +73,7 @@ namespace OpenSim.Capabilities.Handlers | |||
|             string textureStr = query.GetOne("texture_id"); | ||||
|             string format = query.GetOne("format"); | ||||
| 
 | ||||
|             m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr); | ||||
|             //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr); | ||||
| 
 | ||||
|             if (m_assetService == null) | ||||
|             { | ||||
|  |  | |||
|  | @ -0,0 +1,19 @@ | |||
| :VERSION 1         # --------------------------  | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| CREATE TABLE "GridUser" ( | ||||
|     "UserID" VARCHAR(255) NOT NULL, | ||||
|     "HomeRegionID" CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||||
|     "HomePosition" CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||||
|     "HomeLookAt" CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||||
|     "LastRegionID" CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||||
|     "LastPosition" CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||||
|     "LastLookAt" CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||||
|     "Online" CHAR(5) NOT NULL DEFAULT 'false', | ||||
|     "Login" CHAR(16) NOT NULL DEFAULT '0', | ||||
|     "Logout" CHAR(16) NOT NULL DEFAULT '0', | ||||
|     PRIMARY KEY  ("UserID") | ||||
| )  | ||||
| 
 | ||||
| COMMIT | ||||
|  | @ -43,7 +43,7 @@ namespace OpenSim.Data.MySQL | |||
|     public class MySQLAvatarData : MySQLGenericTableHandler<AvatarBaseData>, | ||||
|             IAvatarData | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         public MySQLAvatarData(string connectionString, string realm) : | ||||
|                 base(connectionString, realm, "Avatar") | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ namespace OpenSim.Data.MySQL | |||
|         private string m_connectionString; | ||||
|         private long m_waitTimeout; | ||||
|         private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond; | ||||
|         private long m_lastConnectionUse; | ||||
| //        private long m_lastConnectionUse; | ||||
| 
 | ||||
|         private FieldInfo[] m_Fields; | ||||
|         private Dictionary<string, FieldInfo> m_FieldMap = | ||||
|  | @ -127,7 +127,7 @@ namespace OpenSim.Data.MySQL | |||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 m_lastConnectionUse = DateTime.Now.Ticks; | ||||
| //                m_lastConnectionUse = DateTime.Now.Ticks; | ||||
| 
 | ||||
|                 m_log.DebugFormat( | ||||
|                     "[REGION DB]: Connection wait timeout {0} seconds", | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ namespace OpenSim.Data.MySQL | |||
| { | ||||
|     public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new() | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|          | ||||
|         protected Dictionary<string, FieldInfo> m_Fields = | ||||
|                 new Dictionary<string, FieldInfo>(); | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ namespace OpenSim.Data.MySQL | |||
|     public class MySQLPresenceData : MySQLGenericTableHandler<PresenceData>, | ||||
|             IPresenceData | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         public MySQLPresenceData(string connectionString, string realm) : | ||||
|                 base(connectionString, realm, "Presence") | ||||
|  |  | |||
|  | @ -189,7 +189,7 @@ namespace OpenSim.Data.MySQL | |||
|                     { | ||||
|                         cmd.ExecuteNonQuery(); | ||||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     catch (Exception) | ||||
|                     { | ||||
|                         return false; | ||||
|                     } | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ using System.Reflection; | |||
| using log4net; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| using log4net; | ||||
| 
 | ||||
| #if CSharpSqlite | ||||
|     using Community.CsharpSqlite.Sqlite; | ||||
| #else | ||||
|  | @ -49,7 +49,6 @@ namespace OpenSim.Data.SQLite | |||
|         private string m_Realm; | ||||
|         private List<string> m_ColumnNames; | ||||
|         private int m_LastExpire; | ||||
|         private string m_connectionString; | ||||
| 
 | ||||
|         protected static SqliteConnection m_Connection; | ||||
|         private static bool m_initialized = false; | ||||
|  | @ -58,7 +57,6 @@ namespace OpenSim.Data.SQLite | |||
|                 : base(connectionString) | ||||
|         { | ||||
|             m_Realm = realm; | ||||
|             m_connectionString = connectionString; | ||||
| 
 | ||||
|             if (!m_initialized) | ||||
|             { | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite | |||
|     public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>, | ||||
|             IAvatarData | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         public SQLiteAvatarData(string connectionString, string realm) : | ||||
|                 base(connectionString, realm, "Avatar") | ||||
|  |  | |||
|  | @ -460,7 +460,7 @@ namespace OpenSim.Framework | |||
|                     { | ||||
|                         info["state"] = OSD.FromString(AttachmentObjectStates[i++]); | ||||
|                     } | ||||
|                     catch (IndexOutOfRangeException e) | ||||
|                     catch (IndexOutOfRangeException) | ||||
|                     { | ||||
|                         m_log.WarnFormat("[CHILD AGENT DATA]: scripts list is shorter than object list."); | ||||
|                     } | ||||
|  |  | |||
|  | @ -29,113 +29,13 @@ namespace OpenSim.Framework | |||
| { | ||||
|     public class ConfigSettings | ||||
|     { | ||||
|         private string m_physicsEngine; | ||||
| 
 | ||||
|         public string PhysicsEngine | ||||
|         { | ||||
|             get { return m_physicsEngine; } | ||||
|             set { m_physicsEngine = value; } | ||||
|         } | ||||
|         private string m_meshEngineName; | ||||
| 
 | ||||
|         public string MeshEngineName | ||||
|         { | ||||
|             get { return m_meshEngineName; } | ||||
|             set { m_meshEngineName = value; } | ||||
|         } | ||||
| 
 | ||||
|         private bool m_see_into_region_from_neighbor; | ||||
| 
 | ||||
|         public bool See_into_region_from_neighbor | ||||
|         { | ||||
|             get { return m_see_into_region_from_neighbor; } | ||||
|             set { m_see_into_region_from_neighbor = value; } | ||||
|         } | ||||
| 
 | ||||
|         private string m_storageDll; | ||||
| 
 | ||||
|         public string StorageDll | ||||
|         { | ||||
|             get { return m_storageDll; } | ||||
|             set { m_storageDll = value; } | ||||
|         } | ||||
| 
 | ||||
|         private string m_clientstackDll; | ||||
| 
 | ||||
|         public string ClientstackDll | ||||
|         { | ||||
|             get { return m_clientstackDll; } | ||||
|             set { m_clientstackDll = value; } | ||||
|         } | ||||
| 
 | ||||
|         private bool m_physicalPrim; | ||||
| 
 | ||||
|         public bool PhysicalPrim | ||||
|         { | ||||
|             get { return m_physicalPrim; } | ||||
|             set { m_physicalPrim = value; } | ||||
|         } | ||||
| 
 | ||||
|         private bool m_standaloneAuthenticate = false; | ||||
| 
 | ||||
|         public bool StandaloneAuthenticate | ||||
|         { | ||||
|             get { return m_standaloneAuthenticate; } | ||||
|             set { m_standaloneAuthenticate = value; } | ||||
|         } | ||||
| 
 | ||||
|         private string m_standaloneWelcomeMessage = null; | ||||
| 
 | ||||
|         public string StandaloneWelcomeMessage | ||||
|         { | ||||
|             get { return m_standaloneWelcomeMessage; } | ||||
|             set { m_standaloneWelcomeMessage = value; } | ||||
|         } | ||||
| 
 | ||||
|         private string m_standaloneInventoryPlugin; | ||||
| 
 | ||||
|         public string StandaloneInventoryPlugin | ||||
|         { | ||||
|             get { return m_standaloneInventoryPlugin; } | ||||
|             set { m_standaloneInventoryPlugin = value; } | ||||
|         } | ||||
| 
 | ||||
|         private string m_standaloneUserPlugin; | ||||
| 
 | ||||
|         public string StandaloneUserPlugin | ||||
|         { | ||||
|             get { return m_standaloneUserPlugin; } | ||||
|             set { m_standaloneUserPlugin = value; } | ||||
|         } | ||||
| 
 | ||||
|         private string m_standaloneInventorySource; | ||||
| 
 | ||||
|         public string StandaloneInventorySource | ||||
|         { | ||||
|             get { return m_standaloneInventorySource; } | ||||
|             set { m_standaloneInventorySource = value; } | ||||
|         } | ||||
| 
 | ||||
|         private string m_standaloneUserSource; | ||||
| 
 | ||||
|         public string StandaloneUserSource | ||||
|         { | ||||
|             get { return m_standaloneUserSource; } | ||||
|             set { m_standaloneUserSource = value; } | ||||
|         } | ||||
| 
 | ||||
|         protected string m_librariesXMLFile; | ||||
|         public string LibrariesXMLFile | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return m_librariesXMLFile; | ||||
|             } | ||||
|             set | ||||
|             { | ||||
|                 m_librariesXMLFile = value; | ||||
|             } | ||||
|         } | ||||
|         public string PhysicsEngine                 { get; set; } | ||||
|         public string MeshEngineName                { get; set; } | ||||
|         public bool   See_into_region_from_neighbor { get; set; } | ||||
|         public string StorageDll                    { get; set; } | ||||
|         public string ClientstackDll                { get; set; } | ||||
|         public bool   PhysicalPrim                  { get; set; } | ||||
|         public string LibrariesXMLFile              { get; set; } | ||||
| 
 | ||||
|         public const uint DefaultAssetServerHttpPort = 8003; | ||||
|         public const uint DefaultRegionHttpPort = 9000; | ||||
|  | @ -146,4 +46,4 @@ namespace OpenSim.Framework | |||
|         public const uint DefaultGridServerHttpPort = 8003; | ||||
|         public const uint DefaultInventoryServerHttpPort = 8003; | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -78,7 +78,7 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|     public delegate void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag); | ||||
| 
 | ||||
|     public delegate void RequestMapName(IClientAPI remoteClient, string mapName); | ||||
|     public delegate void RequestMapName(IClientAPI remoteClient, string mapName, uint flags); | ||||
| 
 | ||||
|     public delegate void TeleportLocationRequest( | ||||
|         IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags); | ||||
|  |  | |||
|  | @ -52,6 +52,11 @@ namespace OpenSim.Framework | |||
|             return GetHttpServer(port,null); | ||||
|         } | ||||
| 
 | ||||
|         public static void AddHttpServer(BaseHttpServer server) | ||||
|         { | ||||
|             m_Servers.Add(server.Port, server); | ||||
|         } | ||||
| 
 | ||||
|         public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr) | ||||
|         { | ||||
|             if (port == 0) | ||||
|  |  | |||
|  | @ -49,6 +49,12 @@ namespace OpenSim.Framework | |||
|         public string HttpSSLCN = ""; | ||||
|         public uint httpSSLPort = 9001; | ||||
| 
 | ||||
|         // "Out of band" managemnt https | ||||
|         public bool ssl_listener = false; | ||||
|         public uint https_port = 0; | ||||
|         public string cert_path = String.Empty; | ||||
|         public string cert_pass = String.Empty; | ||||
| 
 | ||||
|         public string MessagingURL = String.Empty; | ||||
| 
 | ||||
|         public NetworkServersInfo() | ||||
|  | @ -86,6 +92,15 @@ namespace OpenSim.Framework | |||
|             secureInventoryServer = config.Configs["Network"].GetBoolean("secure_inventory_server", true); | ||||
| 
 | ||||
|             MessagingURL = config.Configs["Network"].GetString("messaging_server_url", string.Empty); | ||||
| 
 | ||||
|             // "Out of band management https" | ||||
|             ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false); | ||||
|             if( ssl_listener) | ||||
|             { | ||||
|                 cert_path = config.Configs["Network"].GetString("cert_path",String.Empty); | ||||
|                 cert_pass = config.Configs["Network"].GetString("cert_pass",String.Empty); | ||||
|                 https_port = (uint)config.Configs["Network"].GetInt("https_port", 0); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -38,7 +38,7 @@ namespace OpenSim.Framework | |||
| { | ||||
|     public class PriorityQueue | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); | ||||
| 
 | ||||
|  |  | |||
|  | @ -96,251 +96,6 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     [Serializable] | ||||
|     public class SimpleRegionInfo | ||||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// The port by which http communication occurs with the region (most noticeably, CAPS communication) | ||||
|         /// </summary> | ||||
|         public uint HttpPort | ||||
|         { | ||||
|             get { return m_httpPort; } | ||||
|             set { m_httpPort = value; } | ||||
|         } | ||||
|         protected uint m_httpPort; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// A well-formed URI for the host region server (namely "http://" + ExternalHostName) | ||||
|         /// </summary> | ||||
|         public string ServerURI | ||||
|         { | ||||
|             get {  | ||||
|                 if ( m_serverURI != string.Empty ) { | ||||
|                     return m_serverURI; | ||||
|                 } else { | ||||
|                     return "http://" + m_externalHostName + ":" + m_httpPort + "/"; | ||||
|                 } | ||||
|             } | ||||
|             set {  | ||||
|                 if ( value.EndsWith("/") ) { | ||||
|                     m_serverURI = value; | ||||
|                 } else { | ||||
|                     m_serverURI = value + '/'; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         protected string m_serverURI; | ||||
| 
 | ||||
|         public string RegionName | ||||
|         { | ||||
|             get { return m_regionName; } | ||||
|             set { m_regionName = value; } | ||||
|         } | ||||
|         protected string m_regionName = String.Empty; | ||||
| 
 | ||||
|         protected bool Allow_Alternate_Ports; | ||||
|         public bool m_allow_alternate_ports; | ||||
|         protected string m_externalHostName; | ||||
| 
 | ||||
|         protected IPEndPoint m_internalEndPoint; | ||||
|         protected uint? m_regionLocX; | ||||
|         protected uint? m_regionLocY; | ||||
|         protected uint m_remotingPort; | ||||
|         public UUID RegionID = UUID.Zero; | ||||
|         public string RemotingAddress; | ||||
|         public UUID ScopeID = UUID.Zero; | ||||
| 
 | ||||
|         public SimpleRegionInfo() | ||||
|         { | ||||
|             m_serverURI = string.Empty; | ||||
|         } | ||||
| 
 | ||||
|         public SimpleRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) | ||||
|         { | ||||
|             m_regionLocX = regionLocX; | ||||
|             m_regionLocY = regionLocY; | ||||
| 
 | ||||
|             m_internalEndPoint = internalEndPoint; | ||||
|             m_externalHostName = externalUri; | ||||
|             m_serverURI = string.Empty; | ||||
|         } | ||||
| 
 | ||||
|         public SimpleRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port) | ||||
|         { | ||||
|             m_regionLocX = regionLocX; | ||||
|             m_regionLocY = regionLocY; | ||||
| 
 | ||||
|             m_externalHostName = externalUri; | ||||
| 
 | ||||
|             m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port); | ||||
|             m_serverURI = string.Empty; | ||||
|         } | ||||
| 
 | ||||
|         public SimpleRegionInfo(RegionInfo ConvertFrom) | ||||
|         { | ||||
|             m_regionName = ConvertFrom.RegionName; | ||||
|             m_regionLocX = ConvertFrom.RegionLocX; | ||||
|             m_regionLocY = ConvertFrom.RegionLocY; | ||||
|             m_internalEndPoint = ConvertFrom.InternalEndPoint; | ||||
|             m_externalHostName = ConvertFrom.ExternalHostName; | ||||
|             m_remotingPort = ConvertFrom.RemotingPort; | ||||
|             m_httpPort = ConvertFrom.HttpPort; | ||||
|             m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; | ||||
|             RemotingAddress = ConvertFrom.RemotingAddress; | ||||
|             RegionID = UUID.Zero; | ||||
|             ServerURI = ConvertFrom.ServerURI; | ||||
|         } | ||||
| 
 | ||||
|         public uint RemotingPort | ||||
|         { | ||||
|             get { return m_remotingPort; } | ||||
|             set { m_remotingPort = value; } | ||||
|         } | ||||
| 
 | ||||
|         /// <value> | ||||
|         /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw. | ||||
|         /// | ||||
|         /// XXX Isn't this really doing too much to be a simple getter, rather than an explict method? | ||||
|         /// </value> | ||||
|         public IPEndPoint ExternalEndPoint | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 // Old one defaults to IPv6 | ||||
|                 //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port); | ||||
| 
 | ||||
|                 IPAddress ia = null; | ||||
|                 // If it is already an IP, don't resolve it - just return directly | ||||
|                 if (IPAddress.TryParse(m_externalHostName, out ia)) | ||||
|                     return new IPEndPoint(ia, m_internalEndPoint.Port); | ||||
| 
 | ||||
|                 // Reset for next check | ||||
|                 ia = null; | ||||
|                 try | ||||
|                 { | ||||
|                     foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) | ||||
|                     { | ||||
|                         if (ia == null) | ||||
|                             ia = Adr; | ||||
| 
 | ||||
|                         if (Adr.AddressFamily == AddressFamily.InterNetwork) | ||||
|                         { | ||||
|                             ia = Adr; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 catch (SocketException e) | ||||
|                 { | ||||
|                     throw new Exception( | ||||
|                         "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" + | ||||
|                         e + "' attached to this exception", e); | ||||
|                 } | ||||
| 
 | ||||
|                 return new IPEndPoint(ia, m_internalEndPoint.Port); | ||||
|             } | ||||
| 
 | ||||
|             set { m_externalHostName = value.ToString(); } | ||||
|         } | ||||
| 
 | ||||
|         public string ExternalHostName | ||||
|         { | ||||
|             get { return m_externalHostName; } | ||||
|             set { m_externalHostName = value; } | ||||
|         } | ||||
| 
 | ||||
|         public IPEndPoint InternalEndPoint | ||||
|         { | ||||
|             get { return m_internalEndPoint; } | ||||
|             set { m_internalEndPoint = value; } | ||||
|         } | ||||
| 
 | ||||
|         public uint RegionLocX | ||||
|         { | ||||
|             get { return m_regionLocX.Value; } | ||||
|             set { m_regionLocX = value; } | ||||
|         } | ||||
| 
 | ||||
|         public uint RegionLocY | ||||
|         { | ||||
|             get { return m_regionLocY.Value; } | ||||
|             set { m_regionLocY = value; } | ||||
|         } | ||||
| 
 | ||||
|         public ulong RegionHandle | ||||
|         { | ||||
|             get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); } | ||||
|         } | ||||
| 
 | ||||
|         public int getInternalEndPointPort() | ||||
|         { | ||||
|             return m_internalEndPoint.Port; | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<string, object> ToKeyValuePairs() | ||||
|         { | ||||
|             Dictionary<string, object> kvp = new Dictionary<string, object>(); | ||||
|             kvp["uuid"] = RegionID.ToString(); | ||||
|             kvp["locX"] = RegionLocX.ToString(); | ||||
|             kvp["locY"] = RegionLocY.ToString(); | ||||
|             kvp["external_ip_address"] = ExternalEndPoint.Address.ToString(); | ||||
|             kvp["external_port"] = ExternalEndPoint.Port.ToString(); | ||||
|             kvp["external_host_name"] = ExternalHostName; | ||||
|             kvp["http_port"] = HttpPort.ToString(); | ||||
|             kvp["internal_ip_address"] = InternalEndPoint.Address.ToString(); | ||||
|             kvp["internal_port"] = InternalEndPoint.Port.ToString(); | ||||
|             kvp["alternate_ports"] = m_allow_alternate_ports.ToString(); | ||||
|             kvp["server_uri"] = ServerURI; | ||||
| 
 | ||||
|             return kvp; | ||||
|         } | ||||
| 
 | ||||
|         public SimpleRegionInfo(Dictionary<string, object> kvp) | ||||
|         { | ||||
|             if ((kvp["external_ip_address"] != null) && (kvp["external_port"] != null)) | ||||
|             { | ||||
|                 int port = 0; | ||||
|                 Int32.TryParse((string)kvp["external_port"], out port); | ||||
|                 IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["external_ip_address"]), port); | ||||
|                 ExternalEndPoint = ep; | ||||
|             } | ||||
|             else | ||||
|                 ExternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); | ||||
| 
 | ||||
|             if (kvp["external_host_name"] != null) | ||||
|                 ExternalHostName = (string)kvp["external_host_name"]; | ||||
| 
 | ||||
|             if (kvp["http_port"] != null) | ||||
|             { | ||||
|                 UInt32 port = 0; | ||||
|                 UInt32.TryParse((string)kvp["http_port"], out port); | ||||
|                 HttpPort = port; | ||||
|             } | ||||
| 
 | ||||
|             if ((kvp["internal_ip_address"] != null) && (kvp["internal_port"] != null)) | ||||
|             { | ||||
|                 int port = 0; | ||||
|                 Int32.TryParse((string)kvp["internal_port"], out port); | ||||
|                 IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["internal_ip_address"]), port); | ||||
|                 InternalEndPoint = ep; | ||||
|             } | ||||
|             else | ||||
|                 InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); | ||||
| 
 | ||||
|             if (kvp["alternate_ports"] != null) | ||||
|             { | ||||
|                 bool alts = false; | ||||
|                 Boolean.TryParse((string)kvp["alternate_ports"], out alts); | ||||
|                 m_allow_alternate_ports = alts; | ||||
|             } | ||||
| 
 | ||||
|             if (kvp["server_uri"] != null) | ||||
|                 ServerURI = (string)kvp["server_uri"]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class RegionInfo | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ using System.Collections.Specialized; | |||
| using System.IO; | ||||
| using System.Net; | ||||
| using System.Net.Sockets; | ||||
| using System.Security.Cryptography.X509Certificates; | ||||
| using System.Reflection; | ||||
| using System.Globalization; | ||||
| using System.Text; | ||||
|  | @ -72,6 +73,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|         protected uint m_port; | ||||
|         protected uint m_sslport; | ||||
|         protected bool m_ssl; | ||||
|         private X509Certificate2 m_cert; | ||||
|         protected bool m_firstcaps = true; | ||||
|         protected string m_SSLCommonName = ""; | ||||
| 
 | ||||
|  | @ -123,6 +125,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl) | ||||
|         { | ||||
|             if (m_ssl) | ||||
|             { | ||||
|                 m_cert = new X509Certificate2(CPath, CPass); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Add a stream handler to the http server.  If the handler already exists, then nothing happens. | ||||
|         /// </summary> | ||||
|  | @ -1683,6 +1693,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             try | ||||
|             { | ||||
|                 //m_httpListener = new HttpListener(); | ||||
| 
 | ||||
|                 NotSocketErrors = 0; | ||||
|                 if (!m_ssl) | ||||
|                 { | ||||
|  | @ -1702,6 +1713,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                 { | ||||
|                     //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/"); | ||||
|                     //m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); | ||||
|                     m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert); | ||||
|                     m_httpListener2.ExceptionThrown += httpServerException; | ||||
|                     m_httpListener2.LogWriter = httpserverlog; | ||||
|                 } | ||||
| 
 | ||||
|                 m_httpListener2.RequestReceived += OnRequest; | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ using System.Collections.Generic; | |||
| using System.Collections.Specialized; | ||||
| using System.Globalization; | ||||
| using System.IO; | ||||
| using System.IO.Compression; | ||||
| using System.Net; | ||||
| using System.Net.Security; | ||||
| using System.Reflection; | ||||
|  | @ -140,22 +141,32 @@ namespace OpenSim.Framework | |||
|         /// PUT JSON-encoded data to a web service that returns LLSD or | ||||
|         /// JSON data | ||||
|         /// </summary> | ||||
|         public static OSDMap PutToServiceCompressed(string url, OSDMap data, int timeout) | ||||
|         { | ||||
|             return ServiceOSDRequest(url,data, "PUT", timeout, true); | ||||
|         } | ||||
| 
 | ||||
|         public static OSDMap PutToService(string url, OSDMap data, int timeout) | ||||
|         { | ||||
|             return ServiceOSDRequest(url,data, "PUT", timeout); | ||||
|             return ServiceOSDRequest(url,data, "PUT", timeout, false); | ||||
|         } | ||||
| 
 | ||||
|         public static OSDMap PostToService(string url, OSDMap data, int timeout) | ||||
|         { | ||||
|             return ServiceOSDRequest(url, data, "POST", timeout); | ||||
|             return ServiceOSDRequest(url, data, "POST", timeout, false); | ||||
|         } | ||||
| 
 | ||||
|         public static OSDMap PostToServiceCompressed(string url, OSDMap data, int timeout) | ||||
|         { | ||||
|             return ServiceOSDRequest(url, data, "POST", timeout, true); | ||||
|         } | ||||
| 
 | ||||
|         public static OSDMap GetFromService(string url, int timeout) | ||||
|         { | ||||
|             return ServiceOSDRequest(url, null, "GET", timeout); | ||||
|             return ServiceOSDRequest(url, null, "GET", timeout, false); | ||||
|         } | ||||
|          | ||||
|         public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout) | ||||
|         public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed) | ||||
|         { | ||||
|             int reqnum = m_requestNumber++; | ||||
|             // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||||
|  | @ -180,10 +191,31 @@ namespace OpenSim.Framework | |||
|                     string strBuffer =  OSDParser.SerializeJsonString(data); | ||||
|                     byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); | ||||
| 
 | ||||
|                     request.ContentType = "application/json"; | ||||
|                     request.ContentLength = buffer.Length;   //Count bytes to send | ||||
|                     using (Stream requestStream = request.GetRequestStream()) | ||||
|                             requestStream.Write(buffer, 0, buffer.Length);         //Send it | ||||
|                     if (compressed) | ||||
|                     { | ||||
|                         request.ContentType = "application/x-gzip"; | ||||
|                         using (MemoryStream ms = new MemoryStream()) | ||||
|                         { | ||||
|                             using (GZipStream comp = new GZipStream(ms, CompressionMode.Compress)) | ||||
|                             { | ||||
|                                 comp.Write(buffer, 0, buffer.Length); | ||||
|                                 // We need to close the gzip stream before we write it anywhere | ||||
|                                 // because apparently something important related to gzip compression | ||||
|                                 // gets written on the strteam upon Dispose() | ||||
|                             } | ||||
|                             byte[] buf = ms.ToArray(); | ||||
|                             request.ContentLength = buf.Length;   //Count bytes to send | ||||
|                             using (Stream requestStream = request.GetRequestStream()) | ||||
|                                 requestStream.Write(buf, 0, (int)buf.Length); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         request.ContentType = "application/json"; | ||||
|                         request.ContentLength = buffer.Length;   //Count bytes to send | ||||
|                         using (Stream requestStream = request.GetRequestStream()) | ||||
|                                 requestStream.Write(buffer, 0, buffer.Length);         //Send it | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|                 // capture how much time was spent writing, this may seem silly | ||||
|  | @ -809,7 +841,7 @@ namespace OpenSim.Framework | |||
|             { | ||||
|                 if ((verb == "POST") || (verb == "PUT")) | ||||
|                 { | ||||
|                     request.ContentType = "text/www-form-urlencoded"; | ||||
|                     request.ContentType = "application/x-www-form-urlencoded"; | ||||
| 
 | ||||
|                     int length = 0; | ||||
|                     using (StreamWriter writer = new StreamWriter(buffer)) | ||||
|  | @ -886,6 +918,10 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|     public class SynchronousRestObjectRequester | ||||
|     { | ||||
|         private static readonly ILog m_log = | ||||
|             LogManager.GetLogger( | ||||
|             MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Perform a synchronous REST request. | ||||
|         /// </summary> | ||||
|  | @ -929,8 +965,9 @@ namespace OpenSim.Framework | |||
|                     requestStream = request.GetRequestStream(); | ||||
|                     requestStream.Write(buffer.ToArray(), 0, length); | ||||
|                 } | ||||
|                 catch (Exception) | ||||
|                 catch (Exception e) | ||||
|                 { | ||||
|                     m_log.WarnFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e);  | ||||
|                     return deserial; | ||||
|                 } | ||||
|                 finally | ||||
|  | @ -944,19 +981,28 @@ namespace OpenSim.Framework | |||
|             { | ||||
|                 using (WebResponse resp = request.GetResponse()) | ||||
|                 { | ||||
|                     if (resp.ContentLength > 0) | ||||
|                     if (resp.ContentLength != 0) | ||||
|                     { | ||||
|                         Stream respStream = resp.GetResponseStream(); | ||||
|                         XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); | ||||
|                         deserial = (TResponse)deserializer.Deserialize(respStream); | ||||
|                         respStream.Close(); | ||||
|                     } | ||||
|                     else | ||||
|                         m_log.WarnFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb); | ||||
| 
 | ||||
|                 } | ||||
|             } | ||||
|             catch (System.InvalidOperationException) | ||||
|             { | ||||
|                 // This is what happens when there is invalid XML | ||||
|                 m_log.WarnFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString()); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 m_log.WarnFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e); | ||||
|             } | ||||
| 
 | ||||
|             return deserial; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -372,21 +372,7 @@ namespace OpenSim | |||
|                     = startupConfig.GetString("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll"); | ||||
|             } | ||||
| 
 | ||||
|             IConfig standaloneConfig = m_config.Source.Configs["StandAlone"]; | ||||
|             if (standaloneConfig != null) | ||||
|             { | ||||
|                 m_configSettings.StandaloneAuthenticate = standaloneConfig.GetBoolean("accounts_authenticate", true); | ||||
|                 m_configSettings.StandaloneWelcomeMessage = standaloneConfig.GetString("welcome_message"); | ||||
| 
 | ||||
|                 m_configSettings.StandaloneInventoryPlugin = standaloneConfig.GetString("inventory_plugin"); | ||||
|                 m_configSettings.StandaloneInventorySource = standaloneConfig.GetString("inventory_source"); | ||||
|                 m_configSettings.StandaloneUserPlugin = standaloneConfig.GetString("userDatabase_plugin"); | ||||
|                 m_configSettings.StandaloneUserSource = standaloneConfig.GetString("user_source"); | ||||
| 
 | ||||
|                 m_configSettings.LibrariesXMLFile = standaloneConfig.GetString("LibrariesXMLFile"); | ||||
|             } | ||||
| 
 | ||||
|             m_networkServersInfo.loadFromConfiguration(m_config.Source); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -1436,7 +1436,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         public void SendMapBlock(List<MapBlockData> mapBlocks, uint flag) | ||||
|         { | ||||
| 
 | ||||
|             MapBlockData[] mapBlocks2 = mapBlocks.ToArray(); | ||||
| 
 | ||||
|             int maxsend = 10; | ||||
|  | @ -1686,14 +1685,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                     currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]); | ||||
|                 else | ||||
|                 { | ||||
| //                    m_log.DebugFormat( | ||||
| //                        "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID); | ||||
|                     OutPacket(currentPacket, ThrottleOutPacketType.Asset, false); | ||||
|                     currentPacket = null; | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|             if (currentPacket != null) | ||||
|             { | ||||
| //                m_log.DebugFormat( | ||||
| //                    "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID); | ||||
|                 OutPacket(currentPacket, ThrottleOutPacketType.Asset, false); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder) | ||||
|  | @ -6087,7 +6091,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 AvatarWearingArgs wearingArgs = new AvatarWearingArgs(); | ||||
|                 for (int i = 0; i < nowWearing.WearableData.Length; i++) | ||||
|                 { | ||||
|                     m_log.DebugFormat("[XXX]: Wearable type {0} item {1}", nowWearing.WearableData[i].WearableType, nowWearing.WearableData[i].ItemID); | ||||
|                     //m_log.DebugFormat("[XXX]: Wearable type {0} item {1}", nowWearing.WearableData[i].WearableType, nowWearing.WearableData[i].ItemID); | ||||
|                     AvatarWearingArgs.Wearable wearable = | ||||
|                         new AvatarWearingArgs.Wearable(nowWearing.WearableData[i].ItemID, | ||||
|                                                        nowWearing.WearableData[i].WearableType); | ||||
|  | @ -8369,13 +8373,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                     return true; | ||||
|             } | ||||
|             #endregion | ||||
| 
 | ||||
|             string mapName = Util.UTF8.GetString(map.NameData.Name, 0, | ||||
|                                                      map.NameData.Name.Length - 1); | ||||
|             RequestMapName handlerMapNameRequest = OnMapNameRequest; | ||||
|             if (handlerMapNameRequest != null) | ||||
|             { | ||||
|                 handlerMapNameRequest(this, mapName); | ||||
|                 handlerMapNameRequest(this, mapName, map.AgentData.Flags); | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  |  | |||
|  | @ -96,6 +96,22 @@ namespace OpenSim.Region.ClientStack | |||
| 
 | ||||
|             MainServer.Instance = m_httpServer; | ||||
| 
 | ||||
|             // "OOB" Server | ||||
|             if (m_networkServersInfo.ssl_listener) | ||||
|             { | ||||
|                 BaseHttpServer server = null; | ||||
|                 server = new BaseHttpServer( | ||||
|                     m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path, | ||||
|                     m_networkServersInfo.cert_pass); | ||||
|                 // Add the server to m_Servers | ||||
|                 if(server != null) | ||||
|                 { | ||||
|                     m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port); | ||||
|                     MainServer.AddHttpServer(server); | ||||
|                     server.Start(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             base.StartupSpecific(); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
|             } | ||||
| 
 | ||||
|             if (m_scene == null) | ||||
|                 m_scene = scene; | ||||
|                 m_scene = scene;           | ||||
|         } | ||||
| 
 | ||||
|         public void PostInitialise() | ||||
|  | @ -162,12 +162,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
|                     // one and we're done otherwise, ask for a rebake | ||||
|                     if (checkonly) return false; | ||||
| 
 | ||||
|                     m_log.InfoFormat("[AVFACTORY] missing baked texture {0}, request rebake",face.TextureID); | ||||
|                     m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake",face.TextureID); | ||||
|                     client.SendRebakeAvatarTextures(face.TextureID); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             m_log.DebugFormat("[AVFACTORY]: complete texture check for {0}", client.AgentId); | ||||
|             m_log.DebugFormat("[AVFACTORY]: completed texture check for {0}", client.AgentId); | ||||
| 
 | ||||
|             // If we only found default textures, then the appearance is not cached | ||||
|             return (defonly ? false : true); | ||||
|  |  | |||
|  | @ -178,6 +178,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
|                 List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>( | ||||
|                         "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); | ||||
| 
 | ||||
|                 if (msglist == null) | ||||
|                     m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list."); | ||||
| 
 | ||||
|                 foreach (GridInstantMessage im in msglist) | ||||
|                 { | ||||
|                     // client.SendInstantMessage(im); | ||||
|  |  | |||
|  | @ -66,8 +66,8 @@ namespace OpenSim.Region.CoreModules.Framework | |||
|             m_scene = scene; | ||||
|             m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); | ||||
|             MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps", | ||||
|                 "show capabilities", | ||||
|                 "Shows all  registered capabilities", CapabilitiesCommand); | ||||
|                 "show caps", | ||||
|                 "Shows all registered capabilities", CapabilitiesCommand); | ||||
|         } | ||||
| 
 | ||||
|         public void RegionLoaded(Scene scene) | ||||
|  |  | |||
|  | @ -395,6 +395,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); | ||||
| 
 | ||||
|                 m_log.DebugFormat( | ||||
|                     "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); | ||||
| 
 | ||||
|  | @ -891,6 +893,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
|                 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | ||||
|                 { | ||||
|                     // region doesn't take it | ||||
|                     ReInstantiateScripts(agent); | ||||
|                     ResetFromTransit(agent.UUID); | ||||
|                     return agent; | ||||
|                 } | ||||
|  | @ -1763,14 +1766,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
|         protected void ReInstantiateScripts(ScenePresence sp) | ||||
|         { | ||||
|             int i = 0; | ||||
|             sp.Attachments.ForEach(delegate(SceneObjectGroup sog) | ||||
|             if (sp.InTransitScriptStates.Count > 0) | ||||
|             { | ||||
|                 sog.SetState(sp.InTransitScriptStates[i++], sp.Scene); | ||||
|                 sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0); | ||||
|                 sog.ResumeScripts(); | ||||
|             }); | ||||
|                 sp.Attachments.ForEach(delegate(SceneObjectGroup sog) | ||||
|                 { | ||||
|                     if (i < sp.InTransitScriptStates.Count) | ||||
|                     { | ||||
|                         sog.SetState(sp.InTransitScriptStates[i++], sp.Scene); | ||||
|                         sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0); | ||||
|                         sog.ResumeScripts(); | ||||
|                     } | ||||
|                     else | ||||
|                         m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}", sp.InTransitScriptStates.Count, sp.Attachments.Count); | ||||
|                 }); | ||||
| 
 | ||||
|             sp.InTransitScriptStates.Clear(); | ||||
|                 sp.InTransitScriptStates.Clear(); | ||||
|             } | ||||
|         } | ||||
|         #endregion | ||||
| 
 | ||||
|  |  | |||
|  | @ -62,8 +62,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid | |||
|         { | ||||
|             List<MapBlockData> mapBlocks = new List<MapBlockData>(); | ||||
|             List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | ||||
|                 (minX - 4) * (int)Constants.RegionSize, (maxX + 4) * (int)Constants.RegionSize,  | ||||
|                 (minY - 4) * (int)Constants.RegionSize, (maxY + 4) * (int)Constants.RegionSize); | ||||
|                 minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize,  | ||||
|                 minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize); | ||||
| 
 | ||||
|             foreach (GridRegion r in regions) | ||||
|             { | ||||
|  | @ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid | |||
|             FillInMap(mapBlocks, minX, minY, maxX, maxY); | ||||
|             // | ||||
| 
 | ||||
|             remoteClient.SendMapBlock(mapBlocks, flag); | ||||
|             remoteClient.SendMapBlock(mapBlocks, 0); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -93,7 +93,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid | |||
|                         mblock.X = (ushort)x; | ||||
|                         mblock.Y = (ushort)y; | ||||
|                         mblock.Name = ""; | ||||
|                         mblock.Access = 254; // not here??? | ||||
|                         mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's | ||||
|                         mblock.MapImageId = UUID.Zero; | ||||
|                         mapBlocks.Add(mblock); | ||||
|                     } | ||||
|  |  | |||
|  | @ -118,7 +118,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
|                 return true; | ||||
|             } | ||||
|              | ||||
|             return chain.Build(new X509Certificate2(certificate)); | ||||
|             if ((((int)sslPolicyErrors) & ~4) != 0) | ||||
|                 return false; | ||||
| 
 | ||||
|             if (ServicePointManager.CertificatePolicy != null) | ||||
|             { | ||||
|                 ServicePoint sp = Request.ServicePoint; | ||||
|                 return ServicePointManager.CertificatePolicy.CheckValidationResult (sp, certificate, Request, 0); | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|         #region IHttpRequestModule Members | ||||
| 
 | ||||
|  | @ -464,4 +472,4 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -78,7 +78,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
| 
 | ||||
|         private int m_TotalUrls = 100; | ||||
| 
 | ||||
|         private uint https_port = 0; | ||||
|         private IHttpServer m_HttpServer = null; | ||||
|         private IHttpServer m_HttpsServer = null; | ||||
| 
 | ||||
|         private string m_ExternalHostNameForLSL = ""; | ||||
| 
 | ||||
|  | @ -100,6 +102,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
|         public void Initialise(IConfigSource config) | ||||
|         { | ||||
|             m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); | ||||
|             bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); | ||||
|             if (ssl_enabled) | ||||
|             { | ||||
|                 https_port = (uint) config.Configs["Network"].GetInt("https_port",0); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void PostInitialise() | ||||
|  | @ -113,6 +120,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
|                 // There can only be one | ||||
|                 // | ||||
|                 m_HttpServer = MainServer.Instance; | ||||
|                 // | ||||
|                 // We can use the https if it is enabled | ||||
|                 if (https_port > 0) | ||||
|                 { | ||||
|                     m_HttpsServer = MainServer.GetHttpServer(https_port); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             scene.RegisterModuleInterface<IUrlModule>(this); | ||||
|  | @ -171,7 +184,40 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
|         { | ||||
|             UUID urlcode = UUID.Random(); | ||||
| 
 | ||||
|             engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); | ||||
|             if (m_HttpsServer == null) | ||||
|             { | ||||
|                 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); | ||||
|                 return urlcode; | ||||
|             } | ||||
| 
 | ||||
|             lock (m_UrlMap) | ||||
|             { | ||||
|                 if (m_UrlMap.Count >= m_TotalUrls) | ||||
|                 { | ||||
|                     engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); | ||||
|                     return urlcode; | ||||
|                 } | ||||
|                 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; | ||||
| 
 | ||||
|                 UrlData urlData = new UrlData(); | ||||
|                 urlData.hostID = host.UUID; | ||||
|                 urlData.itemID = itemID; | ||||
|                 urlData.engine = engine; | ||||
|                 urlData.url = url; | ||||
|                 urlData.urlcode = urlcode; | ||||
|                 urlData.requests = new Dictionary<UUID, RequestData>(); | ||||
| 
 | ||||
|                  | ||||
|                 m_UrlMap[url] = urlData; | ||||
|                  | ||||
|                 string uri = "/lslhttps/" + urlcode.ToString() + "/"; | ||||
|                 | ||||
|                 m_HttpsServer.AddPollServiceHTTPHandler(uri,HandleHttpPoll, | ||||
|                         new PollServiceEventArgs(HttpRequestHandler,HasEvents, GetEvents, NoEvents, | ||||
|                             urlcode)); | ||||
| 
 | ||||
|                 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); | ||||
|             } | ||||
| 
 | ||||
|             return urlcode; | ||||
|         } | ||||
|  | @ -345,7 +391,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
|         } | ||||
|         private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) | ||||
|         { | ||||
|             UrlData url = null; | ||||
|              UrlData url = null; | ||||
|             RequestData requestData = null; | ||||
| 
 | ||||
|             lock (m_RequestMap) | ||||
|  | @ -391,11 +437,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
|             lock (request) | ||||
|             { | ||||
|                 string uri = request["uri"].ToString(); | ||||
|                  | ||||
|                 bool is_ssl = uri.Contains("lslhttps"); | ||||
| 
 | ||||
|                 try | ||||
|                 { | ||||
|                     Hashtable headers = (Hashtable)request["headers"]; | ||||
|                      | ||||
| 
 | ||||
| //                    string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; | ||||
| 
 | ||||
|                     int pos1 = uri.IndexOf("/");// /lslhttp | ||||
|  | @ -409,7 +456,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
| 
 | ||||
|                     pathInfo = uri.Substring(pos3); | ||||
| 
 | ||||
|                     UrlData url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp]; | ||||
|                     UrlData url = null; | ||||
|                     if (!is_ssl) | ||||
|                         url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp]; | ||||
|                     else | ||||
|                         url = m_UrlMap["https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp]; | ||||
| 
 | ||||
|                     //for llGetHttpHeader support we need to store original URI here | ||||
|                     //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers  | ||||
|  |  | |||
|  | @ -64,19 +64,26 @@ namespace OpenSim.Region.CoreModules.World.Region | |||
|         public void AddRegion(Scene scene) | ||||
|         { | ||||
|             m_Scene = scene; | ||||
|              | ||||
|             scene.RegisterModuleInterface<IRestartModule>(this); | ||||
|             MainConsole.Instance.Commands.AddCommand("RestartModule", | ||||
|                     false, "region restart bluebox", | ||||
|                     "region restart bluebox <message> <time> ...", | ||||
|                     "Restart the region", HandleRegionRestart); | ||||
|                     "region restart bluebox <message> <delta seconds>+", | ||||
|                     "Schedule a region restart",  | ||||
|                     "Schedule a region restart after a given number of seconds.  If one delta is given then the region is restarted in delta seconds time.  A time to restart is sent to users in the region as a transient notice.  If multiple deltas are given then a notice is sent when we reach each delta.", | ||||
|                     HandleRegionRestart); | ||||
|              | ||||
|             MainConsole.Instance.Commands.AddCommand("RestartModule", | ||||
|                     false, "region restart notice", | ||||
|                     "region restart notice <message> <time> ...", | ||||
|                     "Restart the region", HandleRegionRestart); | ||||
|                     "region restart notice <message> <delta seconds>+", | ||||
|                     "Schedule a region restart",  | ||||
|                     "Schedule a region restart after a given number of seconds.  If one delta is given then the region is restarted in delta seconds time.  A time to restart is sent to users in the region as a dismissable bluebox notice.  If multiple deltas are given then a notice is sent when we reach each delta.", | ||||
|                     HandleRegionRestart); | ||||
|              | ||||
|             MainConsole.Instance.Commands.AddCommand("RestartModule", | ||||
|                     false, "region restart abort", | ||||
|                     "region restart abort [<message>]", | ||||
|                     "Restart the region", HandleRegionRestart); | ||||
|                     "Abort a region restart", HandleRegionRestart); | ||||
|         } | ||||
| 
 | ||||
|         public void RegionLoaded(Scene scene) | ||||
|  | @ -245,7 +252,7 @@ namespace OpenSim.Region.CoreModules.World.Region | |||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 MainConsole.Instance.Output("Error: restart region <mode> <name> <time> ..."); | ||||
|                 MainConsole.Instance.Output("Error: restart region <mode> <name> <delta seconds>+"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
|             client.OnMapNameRequest += OnMapNameRequest; | ||||
|         } | ||||
| 
 | ||||
|         private void OnMapNameRequest(IClientAPI remoteClient, string mapName) | ||||
|         private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) | ||||
|         { | ||||
|             if (mapName.Length < 3) | ||||
|             { | ||||
|  | @ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
|             else if (regionInfos.Count == 0 && mapName.StartsWith("http://")) | ||||
|                 remoteClient.SendAlertMessage("Hyperlink could not be established."); | ||||
| 
 | ||||
|             m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); | ||||
|             m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); | ||||
|             List<MapBlockData> blocks = new List<MapBlockData>(); | ||||
| 
 | ||||
|             MapBlockData data; | ||||
|  | @ -117,7 +117,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
|                     data = new MapBlockData(); | ||||
|                     data.Agents = 0; | ||||
|                     data.Access = info.Access; | ||||
|                     data.MapImageId = UUID.Zero; // could use info.TerrainImage but it seems to break viewer2 | ||||
|                     if (flags == 2) // V2 sends this | ||||
|                         data.MapImageId = UUID.Zero;  | ||||
|                     else | ||||
|                         data.MapImageId = info.TerrainImage; | ||||
|                     data.Name = info.RegionName; | ||||
|                     data.RegionFlags = 0; // TODO not used? | ||||
|                     data.WaterHeight = 0; // not used | ||||
|  | @ -139,9 +142,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
|             data.Y = 0; | ||||
|             blocks.Add(data); | ||||
| 
 | ||||
|             // not sure what the flags do here, but seems to be necessary | ||||
|             // to set to "2" for viewer 2 | ||||
|             remoteClient.SendMapBlock(blocks, 2); | ||||
|             // flags are agent flags sent from the viewer. | ||||
|             // they have different values depending on different viewers, apparently | ||||
|             remoteClient.SendMapBlock(blocks, flags); | ||||
|         } | ||||
| 
 | ||||
| //        private Scene GetClientScene(IClientAPI client) | ||||
|  |  | |||
|  | @ -205,8 +205,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
|         { | ||||
|             //try | ||||
|             //{ | ||||
|                 //m_log.DebugFormat("[MAPLAYER]: request: {0}, path: {1}, param: {2}, agent:{3}", | ||||
|                                   //request, path, param,agentID.ToString()); | ||||
|             //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", | ||||
|             //                  path, param, agentID.ToString()); | ||||
| 
 | ||||
|             // this is here because CAPS map requests work even beyond the 10,000 limit. | ||||
|             ScenePresence avatarPresence = null; | ||||
|  | @ -784,7 +784,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
|         /// <param name="maxY"></param> | ||||
|         public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) | ||||
|         { | ||||
|             if ((flag & 0x10000) != 0)  // user clicked on the map a tile that isn't visible | ||||
|             //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); | ||||
|             if ((flag & 0x10000) != 0)  // user clicked on qthe map a tile that isn't visible | ||||
|             { | ||||
|                 List<MapBlockData> response = new List<MapBlockData>(); | ||||
| 
 | ||||
|  | @ -819,7 +820,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
|                     MapBlockData block = new MapBlockData(); | ||||
|                     block.X = (ushort)minX; | ||||
|                     block.Y = (ushort)minY; | ||||
|                     block.Access = 254; // == not there | ||||
|                     block.Access = 254; // means 'simulator is offline' | ||||
|                     response.Add(block); | ||||
|                 } | ||||
|                 remoteClient.SendMapBlock(response, 0); | ||||
|  | @ -845,7 +846,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
|                 MapBlockFromGridRegion(block, r); | ||||
|                 mapBlocks.Add(block); | ||||
|             } | ||||
|             remoteClient.SendMapBlock(mapBlocks, flag); | ||||
|             remoteClient.SendMapBlock(mapBlocks, 0); | ||||
|         } | ||||
| 
 | ||||
|         protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r) | ||||
|  |  | |||
|  | @ -876,7 +876,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     newName = item.Name; | ||||
|                 } | ||||
| 
 | ||||
|                 if (remoteClient.AgentId == oldAgentID) | ||||
|                 if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner)) | ||||
|                 { | ||||
|                     CreateNewInventoryItem( | ||||
|                         remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, | ||||
|  | @ -1067,11 +1067,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Link an inventory item to an existing item. | ||||
|         /// </summary> | ||||
|         /// <remarks> | ||||
|         /// The linkee item id is placed in the asset id slot.  This appears to be what the viewer expects when | ||||
|         /// it receives inventory information. | ||||
|         /// </remarks> | ||||
|         /// <param name="remoteClient"></param> | ||||
|         /// <param name="transActionID"></param> | ||||
|         /// <param name="folderID"></param> | ||||
|         /// <param name="callbackID"></param> | ||||
|         /// <param name="description"></param> | ||||
|         /// <param name="name"></param> | ||||
|         /// <param name="invType"></param> | ||||
|         /// <param name="type">/param> | ||||
|         /// <param name="olditemID"></param> | ||||
|         private void HandleLinkInventoryItem(IClientAPI remoteClient, UUID transActionID, UUID folderID, | ||||
|                                              uint callbackID, string description, string name, | ||||
|                                              sbyte invType, sbyte type, UUID olditemID) | ||||
|         { | ||||
|             m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item link {0} in folder {1} pointing to {2}", name, folderID, olditemID); | ||||
|             m_log.DebugFormat( | ||||
|                 "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}", | ||||
|                 remoteClient.Name, name, folderID, olditemID); | ||||
| 
 | ||||
|             if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) | ||||
|                 return; | ||||
|  | @ -1079,7 +1097,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             ScenePresence presence; | ||||
|             if (TryGetScenePresence(remoteClient.AgentId, out presence)) | ||||
|             { | ||||
| //                byte[] data = null; | ||||
|                 bool linkAlreadyExists = false; | ||||
|                 List<InventoryItemBase> existingItems = InventoryService.GetFolderItems(remoteClient.AgentId, folderID); | ||||
|                 foreach (InventoryItemBase item in existingItems) | ||||
|                     if (item.AssetID == olditemID) | ||||
|                         linkAlreadyExists = true; | ||||
| 
 | ||||
|                 if (linkAlreadyExists) | ||||
|                 { | ||||
|                     m_log.WarnFormat( | ||||
|                         "[AGENT INVENTORY]: Ignoring request from {0} to create item link {1} in folder {2} pointing to {3} since a link already exists", | ||||
|                         remoteClient.Name, name, folderID, olditemID); | ||||
| 
 | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 AssetBase asset = new AssetBase(); | ||||
|                 asset.FullID = olditemID; | ||||
|  | @ -1514,11 +1545,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             InventoryFolderBase containingFolder = new InventoryFolderBase(folder.ID, client.AgentId); | ||||
|             containingFolder = InventoryService.GetFolder(containingFolder); | ||||
| 
 | ||||
|             //m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}", | ||||
|             //    contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName); | ||||
| //            m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}", | ||||
| //                contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName); | ||||
| 
 | ||||
|             if (containingFolder != null && containingFolder != null) | ||||
|             { | ||||
|                 // If the folder requested contains links, then we need to send those folders first, otherwise the links | ||||
|                 // will be broken in the viewer. | ||||
|                 HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>(); | ||||
|                 foreach (InventoryItemBase item in contents.Items) | ||||
|                 { | ||||
|                     if (item.AssetType == (int)AssetType.Link) | ||||
|                     { | ||||
|                         InventoryItemBase linkedItem = InventoryService.GetItem(new InventoryItemBase(item.AssetID)); | ||||
|                         linkedItemFolderIdsToSend.Add(linkedItem.Folder); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend) | ||||
|                     SendInventoryUpdate(client, new InventoryFolderBase(linkedItemFolderId), false, true); | ||||
| 
 | ||||
|                 client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, containingFolder.Version, fetchFolders, fetchItems); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  |  | |||
|  | @ -500,6 +500,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID, | ||||
|                                                     bool fetchFolders, bool fetchItems, int sortOrder) | ||||
|         { | ||||
| //            m_log.DebugFormat( | ||||
| //                "[USER INVENTORY]: HandleFetchInventoryDescendents() for {0}, folder={1}, fetchFolders={2}, fetchItems={3}, sortOrder={4}", | ||||
| //                remoteClient.Name, folderID, fetchFolders, fetchItems, sortOrder); | ||||
| 
 | ||||
|             if (folderID == UUID.Zero) | ||||
|                 return; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1044,6 +1044,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                                           "reload estate", | ||||
|                                           "Reload the estate data", HandleReloadEstate); | ||||
| 
 | ||||
|             MainConsole.Instance.Commands.AddCommand("region", false, "delete object owner", | ||||
|                                           "delete object owner <UUID>", | ||||
|                                           "Delete object by owner", HandleDeleteObject); | ||||
|             MainConsole.Instance.Commands.AddCommand("region", false, "delete object creator", | ||||
|                                           "delete object creator <UUID>", | ||||
|                                           "Delete object by creator", HandleDeleteObject); | ||||
|             MainConsole.Instance.Commands.AddCommand("region", false, "delete object uuid", | ||||
|                                           "delete object uuid <UUID>", | ||||
|                                           "Delete object by uuid", HandleDeleteObject); | ||||
|             MainConsole.Instance.Commands.AddCommand("region", false, "delete object name", | ||||
|                                           "delete object name <UUID>", | ||||
|                                           "Delete object by name", HandleDeleteObject); | ||||
| 
 | ||||
|             //Bind Storage Manager functions to some land manager functions for this scene | ||||
|             EventManager.OnLandObjectAdded += | ||||
|                 new EventManager.LandObjectAdded(simDataService.StoreLandObject); | ||||
|  | @ -1236,6 +1249,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             m_eventManager = new EventManager(this); | ||||
|             //end of DSG SYNC | ||||
| 
 | ||||
|             m_permissions = new ScenePermissions(this); | ||||
| 
 | ||||
|             m_lastUpdate = Util.EnvironmentTickCount(); | ||||
|         } | ||||
| 
 | ||||
|  | @ -5466,6 +5481,60 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void HandleDeleteObject(string module, string[] cmd) | ||||
|         { | ||||
|             if (cmd.Length < 4) | ||||
|                 return; | ||||
| 
 | ||||
|             string mode = cmd[2]; | ||||
|             string o = cmd[3]; | ||||
| 
 | ||||
|             List<SceneObjectGroup> deletes = new List<SceneObjectGroup>(); | ||||
| 
 | ||||
|             UUID match; | ||||
| 
 | ||||
|             switch (mode) | ||||
|             { | ||||
|             case "owner": | ||||
|                 if (!UUID.TryParse(o, out match)) | ||||
|                     return; | ||||
|                 ForEachSOG(delegate (SceneObjectGroup g) | ||||
|                         { | ||||
|                             if (g.OwnerID == match && !g.IsAttachment) | ||||
|                                 deletes.Add(g); | ||||
|                         }); | ||||
|                 break; | ||||
|             case "creator": | ||||
|                 if (!UUID.TryParse(o, out match)) | ||||
|                     return; | ||||
|                 ForEachSOG(delegate (SceneObjectGroup g) | ||||
|                         { | ||||
|                             if (g.RootPart.CreatorID == match && !g.IsAttachment) | ||||
|                                 deletes.Add(g); | ||||
|                         }); | ||||
|                 break; | ||||
|             case "uuid": | ||||
|                 if (!UUID.TryParse(o, out match)) | ||||
|                     return; | ||||
|                 ForEachSOG(delegate (SceneObjectGroup g) | ||||
|                         { | ||||
|                             if (g.UUID == match && !g.IsAttachment) | ||||
|                                 deletes.Add(g); | ||||
|                         }); | ||||
|                 break; | ||||
|             case "name": | ||||
|                 ForEachSOG(delegate (SceneObjectGroup g) | ||||
|                         { | ||||
|                             if (g.RootPart.Name == o && !g.IsAttachment) | ||||
|                                 deletes.Add(g); | ||||
|                         }); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             foreach (SceneObjectGroup g in deletes) | ||||
|                 DeleteSceneObject(g, false); | ||||
|         } | ||||
| 
 | ||||
|         private void HandleReloadEstate(string module, string[] cmd) | ||||
|         { | ||||
|             if (MainConsole.Instance.ConsoleScene == null || | ||||
|  |  | |||
|  | @ -2518,8 +2518,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             float speed = Velocity.Length(); | ||||
|             float velocidyDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity); | ||||
| 
 | ||||
|             // assuming 5 ms. worst case precision for timer, use 2x that  | ||||
|             // for distance error threshold | ||||
|             float distanceErrorThreshold = speed * 0.01f; | ||||
| 
 | ||||
|             if (speed < 0.01f // allow rotation updates if avatar position is unchanged | ||||
|                 || Math.Abs(distanceError) > 0.25f // arbitrary distance error threshold | ||||
|                 || Math.Abs(distanceError) > distanceErrorThreshold | ||||
|                 || velocidyDiff > 0.01f) // did velocity change from last update? | ||||
|             { | ||||
|                 m_perfMonMS = currentTick; | ||||
|  | @ -3261,7 +3265,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             { | ||||
|                 cAgent.AttachmentObjects = new List<ISceneObject>(); | ||||
|                 cAgent.AttachmentObjectStates = new List<string>(); | ||||
|                 IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||||
| //                IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||||
|                 m_InTransitScriptStates.Clear(); | ||||
|                 foreach (SceneObjectGroup sog in m_attachments) | ||||
|                 { | ||||
|  |  | |||
|  | @ -107,11 +107,10 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
| 
 | ||||
|             scene.AddCommand( | ||||
|                 this, "emergency-monitoring", | ||||
|                 "Go on/off emergency monitoring mode", | ||||
|                 "emergency-monitoring", | ||||
|                 "Go on/off emergency monitoring mode", | ||||
|                 "Go on/off emergency monitoring mode", | ||||
|                 EmergencyMonitoring);                              | ||||
| 
 | ||||
|         } | ||||
|          | ||||
|         public void RemoveRegion(Scene scene) | ||||
|  | @ -190,7 +189,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
|             int maxNameLength = 18;                                     | ||||
|             int maxRegionNameLength = 14; | ||||
|             int maxTypeLength = 4; | ||||
|             int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;                         | ||||
| //            int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;                         | ||||
|                                      | ||||
|             report.Append(GetColumnEntry("User", maxNameLength, columnPadding)); | ||||
|             report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding)); | ||||
|  |  | |||
|  | @ -0,0 +1,122 @@ | |||
| /* | ||||
|  * 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. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       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; | ||||
| using System.Collections.Generic; | ||||
| using System.Reflection; | ||||
| using System.Text; | ||||
| using log4net; | ||||
| using Mono.Addins; | ||||
| using Nini.Config; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Console; | ||||
| using OpenSim.Framework.Statistics; | ||||
| using OpenSim.Region.ClientStack.LindenUDP; | ||||
| using OpenSim.Region.Framework.Interfaces; | ||||
| using OpenSim.Region.Framework.Scenes; | ||||
| 
 | ||||
| namespace OpenSim.Region.OptionalModules.Avatar.Appearance | ||||
| { | ||||
|     /// <summary> | ||||
|     /// A module that just holds commands for inspecting avatar appearance. | ||||
|     /// </summary> | ||||
|     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AppearanceInfoModule")] | ||||
|     public class AppearanceInfoModule : ISharedRegionModule | ||||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);                 | ||||
|          | ||||
|         protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | ||||
|         protected IAvatarFactory m_avatarFactory; | ||||
|          | ||||
|         public string Name { get { return "Appearance Information Module"; } }         | ||||
|          | ||||
|         public Type ReplaceableInterface { get { return null; } } | ||||
|          | ||||
|         public void Initialise(IConfigSource source) | ||||
|         { | ||||
| //            m_log.DebugFormat("[APPEARANCE INFO MODULE]: INITIALIZED MODULE"); | ||||
|         } | ||||
|          | ||||
|         public void PostInitialise() | ||||
|         { | ||||
| //            m_log.DebugFormat("[APPEARANCE INFO MODULE]: POST INITIALIZED MODULE"); | ||||
|         } | ||||
|          | ||||
|         public void Close() | ||||
|         { | ||||
| //            m_log.DebugFormat("[APPEARANCE INFO MODULE]: CLOSED MODULE"); | ||||
|         } | ||||
|          | ||||
|         public void AddRegion(Scene scene) | ||||
|         { | ||||
| //            m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);                                      | ||||
|         } | ||||
|          | ||||
|         public void RemoveRegion(Scene scene) | ||||
|         { | ||||
| //            m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||||
|              | ||||
|             lock (m_scenes) | ||||
|                 m_scenes.Remove(scene.RegionInfo.RegionID); | ||||
|         }         | ||||
|          | ||||
|         public void RegionLoaded(Scene scene) | ||||
|         { | ||||
| //            m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||||
|              | ||||
|             lock (m_scenes) | ||||
|                 m_scenes[scene.RegionInfo.RegionID] = scene;  | ||||
|              | ||||
|             scene.AddCommand( | ||||
|                 this, "appearance show", | ||||
|                 "appearance show", | ||||
|                 "Show appearance information for each avatar in the simulator.  At the moment, ", | ||||
|                 ShowAppearanceInfo);              | ||||
|         }                  | ||||
| 
 | ||||
|         protected void ShowAppearanceInfo(string module, string[] cmd) | ||||
|         {      | ||||
|             lock (m_scenes) | ||||
|             {    | ||||
|                 foreach (Scene scene in m_scenes.Values) | ||||
|                 { | ||||
|                     scene.ForEachClient( | ||||
|                         delegate(IClientAPI client) | ||||
|                         { | ||||
|                             if (client is LLClientView && !((LLClientView)client).ChildAgentStatus()) | ||||
|                             { | ||||
|                                 bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(client); | ||||
|                                 MainConsole.Instance.OutputFormat( | ||||
|                                     "{0} baked apperance texture is {1}", client.Name, bakedTextureValid ? "OK" : "corrupt"); | ||||
|                             } | ||||
|                         }); | ||||
|                 } | ||||
|             } | ||||
|         }       | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,173 @@ | |||
| /* | ||||
|  * 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. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       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; | ||||
| using System.Reflection; | ||||
| using System.Collections.Generic; | ||||
| using log4net; | ||||
| using Mono.Addins; | ||||
| using Nini.Config; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Region.Framework.Interfaces; | ||||
| using OpenSim.Region.Framework.Scenes; | ||||
| 
 | ||||
| namespace OpenSim.Region.OptionalModules | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Enables Prim limits for parcel. | ||||
|     /// </summary> | ||||
|     /// <remarks> | ||||
|     /// This module selectivly enables parcel prim limits. | ||||
|     /// </remarks> | ||||
|     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PrimLimitsModule")] | ||||
|     public class PrimLimitsModule : INonSharedRegionModule | ||||
|     { | ||||
|         protected IDialogModule m_dialogModule; | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         private bool m_enabled; | ||||
| 
 | ||||
|         public string Name { get { return "PrimLimitsModule"; } }         | ||||
|          | ||||
|         public Type ReplaceableInterface { get { return null; } } | ||||
|          | ||||
|         public void Initialise(IConfigSource config) | ||||
|         { | ||||
|             IConfig myConfig = config.Configs["Startup"]; | ||||
| 
 | ||||
|             string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); | ||||
| 
 | ||||
|             List<string> modules=new List<string>(permissionModules.Split(',')); | ||||
| 
 | ||||
|             if(!modules.Contains("PrimLimitsModule")) | ||||
|                 return; | ||||
| 
 | ||||
|             m_log.DebugFormat("[PRIM LIMITS]: Initialized module"); | ||||
|             m_enabled = true; | ||||
|         } | ||||
|          | ||||
|         public void Close() | ||||
|         { | ||||
|         } | ||||
|          | ||||
|         public void AddRegion(Scene scene) | ||||
|         { | ||||
|             if(!m_enabled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             scene.Permissions.OnRezObject += CanRezObject; | ||||
|             scene.Permissions.OnObjectEntry += CanObjectEnter; | ||||
|             scene.Permissions.OnDuplicateObject += CanDuplicateObject; | ||||
|             m_log.DebugFormat("[PRIM LIMITS]: Region {0} added", scene.RegionInfo.RegionName); | ||||
|         } | ||||
|          | ||||
|         public void RemoveRegion(Scene scene) | ||||
|         { | ||||
|             if(m_enabled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             scene.Permissions.OnRezObject -= CanRezObject; | ||||
|             scene.Permissions.OnObjectEntry -= CanObjectEnter; | ||||
|             scene.Permissions.OnDuplicateObject -= CanDuplicateObject; | ||||
|         }         | ||||
|          | ||||
|         public void RegionLoaded(Scene scene) | ||||
|         { | ||||
|             m_dialogModule = scene.RequestModuleInterface<IDialogModule>(); | ||||
|         }                 | ||||
| 
 | ||||
|         private bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition, Scene scene) | ||||
|         { | ||||
|             // This may be a little long winded and can probably be optomized | ||||
|             int usedPrims = scene.LandChannel.GetLandObject(objectPosition.X,objectPosition.Y).PrimCounts.Total; | ||||
|             LandData landData = scene.LandChannel.GetLandObject(objectPosition.X,objectPosition.Y).LandData; | ||||
|             int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * | ||||
|                (float)scene.RegionInfo.ObjectCapacity * (float)scene.RegionInfo.RegionSettings.ObjectBonus); | ||||
| 
 | ||||
|             if(objectCount + usedPrims > simulatorCapacity) | ||||
|             { | ||||
|                 m_dialogModule.SendAlertToUser(owner, "Unable to rez object because the parcel is too full"); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
|         //OnMoveObject | ||||
|         private bool CanObjectEnter(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene) | ||||
|         { | ||||
|             SceneObjectPart obj = scene.GetSceneObjectPart(objectID); | ||||
|             Vector3 oldPoint = obj.GroupPosition; | ||||
|             int objectCount = obj.ParentGroup.PrimCount; | ||||
|             ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); | ||||
|             ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); | ||||
|              | ||||
|             int usedPrims=newParcel.PrimCounts.Total; | ||||
|             LandData landData = newParcel.LandData; | ||||
|             int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * | ||||
|                (float)scene.RegionInfo.ObjectCapacity * (float)scene.RegionInfo.RegionSettings.ObjectBonus); | ||||
|              | ||||
|             // The prim hasn't crossed a region boundry so we don't need to worry | ||||
|             // about prim counts here | ||||
|             if(oldParcel.Equals(newParcel)) | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
|             // Prim counts are determined by the location of the root prim.  if we're | ||||
|             // moving a child prim, just let it pass | ||||
|             if(!obj.IsRoot) | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
|             // Add Special Case here for temporary prims | ||||
|              | ||||
|             if(objectCount + usedPrims > simulatorCapacity) | ||||
|             { | ||||
|                 m_dialogModule.SendAlertToUser(obj.OwnerID, "Unable to move object because the destination parcel  is too full"); | ||||
|                 return false; | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|         //OnDuplicateObject | ||||
|         private bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition) | ||||
|         { | ||||
|             // This may be a little long winded and can probably be optomized | ||||
|             int usedPrims = scene.LandChannel.GetLandObject(objectPosition.X,objectPosition.Y).PrimCounts.Total; | ||||
|             LandData landData = scene.LandChannel.GetLandObject(objectPosition.X,objectPosition.Y).LandData; | ||||
|             int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * | ||||
|                (float)scene.RegionInfo.ObjectCapacity * (float)scene.RegionInfo.RegionSettings.ObjectBonus); | ||||
| 
 | ||||
|             if(objectCount + usedPrims > simulatorCapacity) | ||||
|             { | ||||
|                 m_dialogModule.SendAlertToUser(owner, "Unable to duplicate object because the parcel is too full"); | ||||
|                 return false; | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -13,5 +13,6 @@ | |||
|       <RegionModule id="Concierge"             type="OpenSim.Region.OptionalModules.Avatar.Concierge.ConciergeModule" /> | ||||
|       <RegionModule id="VivoxVoice"            type="OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice.VivoxVoiceModule" /> | ||||
|       <RegionModule id="WorldViewModule"            type="OpenSim.Region.OptionalModules.World.WorldView.WorldViewModule" /> | ||||
|       <RegionModule id="AutoBackupModule"      type="OpenSim.Region.OptionalModules.World.AutoBackup.AutoBackupModule" /> | ||||
|     </Extension> | ||||
| </Addin> | ||||
|  |  | |||
|  | @ -0,0 +1,929 @@ | |||
| /* | ||||
|  * 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. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       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; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| using System.Reflection; | ||||
| using System.Timers; | ||||
| using System.Text.RegularExpressions; | ||||
| using log4net; | ||||
| using Nini.Config; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Region.Framework.Interfaces; | ||||
| using OpenSim.Region.Framework.Scenes; | ||||
| 
 | ||||
| namespace OpenSim.Region.OptionalModules.World.AutoBackup | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Choose between ways of naming the backup files that are generated. | ||||
|     /// </summary> | ||||
|     /// <remarks>Time: OARs are named by a timestamp. | ||||
|     /// Sequential: OARs are named by counting (Region_1.oar, Region_2.oar, etc.) | ||||
|     /// Overwrite: Only one file per region is created; it's overwritten each time a backup is made.</remarks> | ||||
|     public enum NamingType | ||||
|     { | ||||
|         Time, | ||||
|         Sequential, | ||||
|         Overwrite | ||||
|     } | ||||
| 
 | ||||
|     ///<summary> | ||||
|     /// AutoBackupModule: save OAR region backups to disk periodically | ||||
|     /// </summary> | ||||
|     /// <remarks> | ||||
|     /// Config Settings Documentation. | ||||
|     /// At the TOP LEVEL, e.g. in OpenSim.ini, we have the following options: | ||||
|     /// EACH REGION, in OpenSim.ini, can have the following settings under the [AutoBackupModule] section. | ||||
|     /// IMPORTANT: You may optionally specify the key name as follows for a per-region key: [Region Name].[Key Name] | ||||
|     /// Example: My region is named Foo. | ||||
|     /// If I wanted to specify the "AutoBackupInterval" key just for this region, I would name my key "Foo.AutoBackupInterval", under the [AutoBackupModule] section of OpenSim.ini. | ||||
|     /// Instead of specifying them on a per-region basis, you can also omit the region name to specify the default setting for all regions. | ||||
|     /// Region-specific settings take precedence. | ||||
|     ///  | ||||
|     /// AutoBackupModuleEnabled: True/False. Default: False. If True, use the auto backup module. This setting does not support per-region basis. | ||||
|     ///     All other settings under [AutoBackupModule] are ignored if AutoBackupModuleEnabled is false, even per-region settings! | ||||
|     /// AutoBackup: True/False. Default: False. If True, activate auto backup functionality.  | ||||
|     /// 	This is the only required option for enabling auto-backup; the other options have sane defaults.  | ||||
|     /// 	If False for a particular region, the auto-backup module becomes a no-op for the region, and all other AutoBackup* settings are ignored. | ||||
|     /// 	If False globally (the default), only regions that specifically override this with "FooRegion.AutoBackup = true" will get AutoBackup functionality. | ||||
|     /// AutoBackupInterval: Double, non-negative value. Default: 720 (12 hours).  | ||||
|     /// 	The number of minutes between each backup attempt.  | ||||
|     /// 	If a negative or zero value is given, it is equivalent to setting AutoBackup = False. | ||||
|     /// AutoBackupBusyCheck: True/False. Default: True.  | ||||
|     /// 	If True, we will only take an auto-backup if a set of conditions are met.  | ||||
|     /// 	These conditions are heuristics to try and avoid taking a backup when the sim is busy. | ||||
|     /// AutoBackupScript: String. Default: not specified (disabled).  | ||||
|     /// 	File path to an executable script or binary to run when an automatic backup is taken. | ||||
|     ///  The file should really be (Windows) an .exe or .bat, or (Linux/Mac) a shell script or binary. | ||||
|     ///  Trying to "run" directories, or things with weird file associations on Win32, might cause unexpected results! | ||||
|     /// 	argv[1] of the executed file/script will be the file name of the generated OAR.  | ||||
|     /// 	If the process can't be spawned for some reason (file not found, no execute permission, etc), write a warning to the console. | ||||
|     /// AutoBackupNaming: string. Default: Time. | ||||
|     /// 	One of three strings (case insensitive): | ||||
|     /// 	"Time": Current timestamp is appended to file name. An existing file will never be overwritten. | ||||
|     ///  "Sequential": A number is appended to the file name. So if RegionName_x.oar exists, we'll save to RegionName_{x+1}.oar next. An existing file will never be overwritten. | ||||
|     ///  "Overwrite": Always save to file named "${AutoBackupDir}/RegionName.oar", even if we have to overwrite an existing file. | ||||
|     /// AutoBackupDir: String. Default: "." (the current directory). | ||||
|     /// 	A directory (absolute or relative) where backups should be saved. | ||||
|     /// AutoBackupDilationThreshold: float. Default: 0.5. Lower bound on time dilation required for BusyCheck heuristics to pass. | ||||
|     ///  If the time dilation is below this value, don't take a backup right now. | ||||
|     /// AutoBackupAgentThreshold: int. Default: 10. Upper bound on # of agents in region required for BusyCheck heuristics to pass. | ||||
|     ///  If the number of agents is greater than this value, don't take a backup right now | ||||
|     /// Save memory by setting low initial capacities. Minimizes impact in common cases of all regions using same interval, and instances hosting 1 ~ 4 regions. | ||||
|     /// Also helps if you don't want AutoBackup at all. | ||||
|     /// </remarks> | ||||
|     public class AutoBackupModule : ISharedRegionModule | ||||
|     { | ||||
|         private static readonly ILog m_log = | ||||
|             LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         private readonly Dictionary<Guid, IScene> m_pendingSaves = new Dictionary<Guid, IScene>(1); | ||||
|         private readonly AutoBackupModuleState m_defaultState = new AutoBackupModuleState(); | ||||
|         private readonly Dictionary<IScene, AutoBackupModuleState> m_states = | ||||
|             new Dictionary<IScene, AutoBackupModuleState>(1); | ||||
|         private readonly Dictionary<Timer, List<IScene>> m_timerMap = | ||||
|             new Dictionary<Timer, List<IScene>>(1); | ||||
|         private readonly Dictionary<double, Timer> m_timers = new Dictionary<double, Timer>(1); | ||||
| 
 | ||||
|         private delegate T DefaultGetter<T>(string settingName, T defaultValue); | ||||
|         private bool m_enabled; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState! | ||||
|         /// </summary> | ||||
|         private bool m_closed; | ||||
| 
 | ||||
|         private IConfigSource m_configSource; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Required by framework. | ||||
|         /// </summary> | ||||
|         public bool IsSharedModule | ||||
|         { | ||||
|             get { return true; } | ||||
|         } | ||||
| 
 | ||||
|         #region ISharedRegionModule Members | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Identifies the module to the system. | ||||
|         /// </summary> | ||||
|         string IRegionModuleBase.Name | ||||
|         { | ||||
|             get { return "AutoBackupModule"; } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// We don't implement an interface, this is a single-use module. | ||||
|         /// </summary> | ||||
|         Type IRegionModuleBase.ReplaceableInterface | ||||
|         { | ||||
|             get { return null; } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Called once in the lifetime of the module at startup. | ||||
|         /// </summary> | ||||
|         /// <param name="source">The input config source for OpenSim.ini.</param> | ||||
|         void IRegionModuleBase.Initialise(IConfigSource source) | ||||
|         { | ||||
|             // Determine if we have been enabled at all in OpenSim.ini -- this is part and parcel of being an optional module | ||||
|             this.m_configSource = source; | ||||
|             IConfig moduleConfig = source.Configs["AutoBackupModule"]; | ||||
|             if (moduleConfig == null) | ||||
|             { | ||||
|                 this.m_enabled = false; | ||||
|                 return; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 this.m_enabled = moduleConfig.GetBoolean("AutoBackupModuleEnabled", false); | ||||
|                 if (this.m_enabled) | ||||
|                 { | ||||
|                     m_log.Info("[AUTO BACKUP]: AutoBackupModule enabled"); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             Timer defTimer = new Timer(43200000); | ||||
|             this.m_defaultState.Timer = defTimer; | ||||
|             this.m_timers.Add(43200000, defTimer); | ||||
|             defTimer.Elapsed += this.HandleElapsed; | ||||
|             defTimer.AutoReset = true; | ||||
|             defTimer.Start(); | ||||
| 
 | ||||
|             AutoBackupModuleState abms = this.ParseConfig(null, true); | ||||
|             m_log.Debug("[AUTO BACKUP]: Here is the default config:"); | ||||
|             m_log.Debug(abms.ToString()); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Called once at de-init (sim shutting down). | ||||
|         /// </summary> | ||||
|         void IRegionModuleBase.Close() | ||||
|         { | ||||
|             if (!this.m_enabled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // We don't want any timers firing while the sim's coming down; strange things may happen. | ||||
|             this.StopAllTimers(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded. | ||||
|         /// </summary> | ||||
|         /// <param name="scene"></param> | ||||
|         void IRegionModuleBase.AddRegion(Scene scene) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Here we just clean up some resources and stop the OAR backup (if any) for the given scene. | ||||
|         /// </summary> | ||||
|         /// <param name="scene">The scene (region) to stop performing AutoBackup on.</param> | ||||
|         void IRegionModuleBase.RemoveRegion(Scene scene) | ||||
|         { | ||||
|             if (!this.m_enabled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (this.m_states.ContainsKey(scene)) | ||||
|             { | ||||
|                 AutoBackupModuleState abms = this.m_states[scene]; | ||||
| 
 | ||||
|                 // Remove this scene out of the timer map list | ||||
|                 Timer timer = abms.Timer; | ||||
|                 List<IScene> list = this.m_timerMap[timer]; | ||||
|                 list.Remove(scene); | ||||
| 
 | ||||
|                 // Shut down the timer if this was the last scene for the timer | ||||
|                 if (list.Count == 0) | ||||
|                 { | ||||
|                     this.m_timerMap.Remove(timer); | ||||
|                     this.m_timers.Remove(timer.Interval); | ||||
|                     timer.Close(); | ||||
|                 } | ||||
|                 this.m_states.Remove(scene); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Most interesting/complex code paths in AutoBackup begin here. | ||||
|         /// We read lots of Nini config, maybe set a timer, add members to state tracking Dictionaries, etc. | ||||
|         /// </summary> | ||||
|         /// <param name="scene">The scene to (possibly) perform AutoBackup on.</param> | ||||
|         void IRegionModuleBase.RegionLoaded(Scene scene) | ||||
|         { | ||||
|             if (!this.m_enabled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // This really ought not to happen, but just in case, let's pretend it didn't... | ||||
|             if (scene == null) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             AutoBackupModuleState abms = this.ParseConfig(scene, false); | ||||
|             m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName); | ||||
|             m_log.Debug((abms == null ? "DEFAULT" : abms.ToString())); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Currently a no-op. | ||||
|         /// </summary> | ||||
|         void ISharedRegionModule.PostInitialise() | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Set up internal state for a given scene. Fairly complex code. | ||||
|         /// When this method returns, we've started auto-backup timers, put members in Dictionaries, and created a State object for this scene. | ||||
|         /// </summary> | ||||
|         /// <param name="scene">The scene to look at.</param> | ||||
|         /// <param name="parseDefault">Whether this call is intended to figure out what we consider the "default" config (applied to all regions unless overridden by per-region settings).</param> | ||||
|         /// <returns>An AutoBackupModuleState contains most information you should need to know relevant to auto-backup, as applicable to a single region.</returns> | ||||
|         private AutoBackupModuleState ParseConfig(IScene scene, bool parseDefault) | ||||
|         { | ||||
|             string sRegionName; | ||||
|             string sRegionLabel; | ||||
|             string prepend; | ||||
|             AutoBackupModuleState state; | ||||
| 
 | ||||
|             if (parseDefault) | ||||
|             { | ||||
|                 sRegionName = null; | ||||
|                 sRegionLabel = "DEFAULT"; | ||||
|                 prepend = ""; | ||||
|                 state = this.m_defaultState; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 sRegionName = scene.RegionInfo.RegionName; | ||||
|                 sRegionLabel = sRegionName; | ||||
|                 prepend = sRegionName + "."; | ||||
|                 state = null; | ||||
|             } | ||||
| 
 | ||||
|             // Read the config settings and set variables. | ||||
|             IConfig regionConfig = (scene != null ? scene.Config.Configs[sRegionName] : null); | ||||
|             IConfig config = this.m_configSource.Configs["AutoBackupModule"]; | ||||
|             if (config == null) | ||||
|             { | ||||
|                 // defaultState would be disabled too if the section doesn't exist. | ||||
|                 state = this.m_defaultState; | ||||
|                 return state; | ||||
|             } | ||||
| 
 | ||||
|             bool tmpEnabled = ResolveBoolean("AutoBackup", this.m_defaultState.Enabled, config, regionConfig); | ||||
|             if (state == null && tmpEnabled != this.m_defaultState.Enabled) | ||||
|                 //Varies from default state | ||||
|             { | ||||
|                 state = new AutoBackupModuleState(); | ||||
|             } | ||||
| 
 | ||||
|             if (state != null) | ||||
|             { | ||||
|                 state.Enabled = tmpEnabled; | ||||
|             } | ||||
| 
 | ||||
|             // If you don't want AutoBackup, we stop. | ||||
|             if ((state == null && !this.m_defaultState.Enabled) || (state != null && !state.Enabled)) | ||||
|             { | ||||
|                 return state; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_log.Info("[AUTO BACKUP]: Region " + sRegionLabel + " is AutoBackup ENABLED."); | ||||
|             } | ||||
| 
 | ||||
|             // Borrow an existing timer if one exists for the same interval; otherwise, make a new one. | ||||
|             double interval = | ||||
|                 this.ResolveDouble("AutoBackupInterval", this.m_defaultState.IntervalMinutes, | ||||
|                  config, regionConfig) * 60000.0; | ||||
|             if (state == null && interval != this.m_defaultState.IntervalMinutes*60000.0) | ||||
|             { | ||||
|                 state = new AutoBackupModuleState(); | ||||
|             } | ||||
| 
 | ||||
|             if (this.m_timers.ContainsKey(interval)) | ||||
|             { | ||||
|                 if (state != null) | ||||
|                 { | ||||
|                     state.Timer = this.m_timers[interval]; | ||||
|                 } | ||||
|                 m_log.Debug("[AUTO BACKUP]: Reusing timer for " + interval + " msec for region " + | ||||
|                             sRegionLabel); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // 0 or negative interval == do nothing. | ||||
|                 if (interval <= 0.0 && state != null) | ||||
|                 { | ||||
|                     state.Enabled = false; | ||||
|                     return state; | ||||
|                 } | ||||
|                 if (state == null) | ||||
|                 { | ||||
|                     state = new AutoBackupModuleState(); | ||||
|                 } | ||||
|                 Timer tim = new Timer(interval); | ||||
|                 state.Timer = tim; | ||||
|                 //Milliseconds -> minutes | ||||
|                 this.m_timers.Add(interval, tim); | ||||
|                 tim.Elapsed += this.HandleElapsed; | ||||
|                 tim.AutoReset = true; | ||||
|                 tim.Start(); | ||||
|             } | ||||
| 
 | ||||
|             // Add the current region to the list of regions tied to this timer. | ||||
|             if (scene != null) | ||||
|             { | ||||
|                 if (state != null) | ||||
|                 { | ||||
|                     if (this.m_timerMap.ContainsKey(state.Timer)) | ||||
|                     { | ||||
|                         this.m_timerMap[state.Timer].Add(scene); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         List<IScene> scns = new List<IScene>(1); | ||||
|                         scns.Add(scene); | ||||
|                         this.m_timerMap.Add(state.Timer, scns); | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if (this.m_timerMap.ContainsKey(this.m_defaultState.Timer)) | ||||
|                     { | ||||
|                         this.m_timerMap[this.m_defaultState.Timer].Add(scene); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         List<IScene> scns = new List<IScene>(1); | ||||
|                         scns.Add(scene); | ||||
|                         this.m_timerMap.Add(this.m_defaultState.Timer, scns); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             bool tmpBusyCheck = ResolveBoolean("AutoBackupBusyCheck", | ||||
|                                                   this.m_defaultState.BusyCheck, config, regionConfig); | ||||
|             if (state == null && tmpBusyCheck != this.m_defaultState.BusyCheck) | ||||
|             { | ||||
|                 state = new AutoBackupModuleState(); | ||||
|             } | ||||
| 
 | ||||
|             if (state != null) | ||||
|             { | ||||
|                 state.BusyCheck = tmpBusyCheck; | ||||
|             } | ||||
| 
 | ||||
|             // Set file naming algorithm | ||||
|             string stmpNamingType = ResolveString("AutoBackupNaming", | ||||
|                                                      this.m_defaultState.NamingType.ToString(), config, regionConfig); | ||||
|             NamingType tmpNamingType; | ||||
|             if (stmpNamingType.Equals("Time", StringComparison.CurrentCultureIgnoreCase)) | ||||
|             { | ||||
|                 tmpNamingType = NamingType.Time; | ||||
|             } | ||||
|             else if (stmpNamingType.Equals("Sequential", StringComparison.CurrentCultureIgnoreCase)) | ||||
|             { | ||||
|                 tmpNamingType = NamingType.Sequential; | ||||
|             } | ||||
|             else if (stmpNamingType.Equals("Overwrite", StringComparison.CurrentCultureIgnoreCase)) | ||||
|             { | ||||
|                 tmpNamingType = NamingType.Overwrite; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_log.Warn("Unknown naming type specified for region " + sRegionLabel + ": " + | ||||
|                            stmpNamingType); | ||||
|                 tmpNamingType = NamingType.Time; | ||||
|             } | ||||
| 
 | ||||
|             if (state == null && tmpNamingType != this.m_defaultState.NamingType) | ||||
|             { | ||||
|                 state = new AutoBackupModuleState(); | ||||
|             } | ||||
| 
 | ||||
|             if (state != null) | ||||
|             { | ||||
|                 state.NamingType = tmpNamingType; | ||||
|             } | ||||
| 
 | ||||
|             string tmpScript = ResolveString("AutoBackupScript", | ||||
|                                                 this.m_defaultState.Script, config, regionConfig); | ||||
|             if (state == null && tmpScript != this.m_defaultState.Script) | ||||
|             { | ||||
|                 state = new AutoBackupModuleState(); | ||||
|             } | ||||
| 
 | ||||
|             if (state != null) | ||||
|             { | ||||
|                 state.Script = tmpScript; | ||||
|             } | ||||
| 
 | ||||
|             string tmpBackupDir = ResolveString("AutoBackupDir", ".", config, regionConfig); | ||||
|             if (state == null && tmpBackupDir != this.m_defaultState.BackupDir) | ||||
|             { | ||||
|                 state = new AutoBackupModuleState(); | ||||
|             } | ||||
| 
 | ||||
|             if (state != null) | ||||
|             { | ||||
|                 state.BackupDir = tmpBackupDir; | ||||
|                 // Let's give the user some convenience and auto-mkdir | ||||
|                 if (state.BackupDir != ".") | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         DirectoryInfo dirinfo = new DirectoryInfo(state.BackupDir); | ||||
|                         if (!dirinfo.Exists) | ||||
|                         { | ||||
|                             dirinfo.Create(); | ||||
|                         } | ||||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         m_log.Warn( | ||||
|                             "BAD NEWS. You won't be able to save backups to directory " + | ||||
|                             state.BackupDir + | ||||
|                             " because it doesn't exist or there's a permissions issue with it. Here's the exception.", | ||||
|                             e); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return state; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Helper function for ParseConfig. | ||||
|         /// </summary> | ||||
|         /// <param name="settingName"></param> | ||||
|         /// <param name="defaultValue"></param> | ||||
|         /// <param name="global"></param> | ||||
|         /// <param name="local"></param> | ||||
|         /// <returns></returns> | ||||
|         private bool ResolveBoolean(string settingName, bool defaultValue, IConfig global, IConfig local) | ||||
|         { | ||||
|             if(local != null) | ||||
|             { | ||||
|                 return local.GetBoolean(settingName, global.GetBoolean(settingName, defaultValue)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return global.GetBoolean(settingName, defaultValue); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Helper function for ParseConfig. | ||||
|         /// </summary> | ||||
|         /// <param name="settingName"></param> | ||||
|         /// <param name="defaultValue"></param> | ||||
|         /// <param name="global"></param> | ||||
|         /// <param name="local"></param> | ||||
|         /// <returns></returns> | ||||
|         private double ResolveDouble(string settingName, double defaultValue, IConfig global, IConfig local) | ||||
|         { | ||||
|             if (local != null) | ||||
|             { | ||||
|                 return local.GetDouble(settingName, global.GetDouble(settingName, defaultValue)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return global.GetDouble(settingName, defaultValue); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Helper function for ParseConfig. | ||||
|         /// </summary> | ||||
|         /// <param name="settingName"></param> | ||||
|         /// <param name="defaultValue"></param> | ||||
|         /// <param name="global"></param> | ||||
|         /// <param name="local"></param> | ||||
|         /// <returns></returns> | ||||
|         private int ResolveInt(string settingName, int defaultValue, IConfig global, IConfig local) | ||||
|         { | ||||
|             if (local != null) | ||||
|             { | ||||
|                 return local.GetInt(settingName, global.GetInt(settingName, defaultValue)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return global.GetInt(settingName, defaultValue); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Helper function for ParseConfig. | ||||
|         /// </summary> | ||||
|         /// <param name="settingName"></param> | ||||
|         /// <param name="defaultValue"></param> | ||||
|         /// <param name="global"></param> | ||||
|         /// <param name="local"></param> | ||||
|         /// <returns></returns> | ||||
|         private string ResolveString(string settingName, string defaultValue, IConfig global, IConfig local) | ||||
|         { | ||||
|             if (local != null) | ||||
|             { | ||||
|                 return local.GetString(settingName, global.GetString(settingName, defaultValue)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return global.GetString(settingName, defaultValue); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Called when any auto-backup timer expires. This starts the code path for actually performing a backup. | ||||
|         /// </summary> | ||||
|         /// <param name="sender"></param> | ||||
|         /// <param name="e"></param> | ||||
|         private void HandleElapsed(object sender, ElapsedEventArgs e) | ||||
|         { | ||||
|             // TODO: heuristic thresholds are per-region, so we should probably run heuristics once per region | ||||
|             // XXX: Running heuristics once per region could add undue performance penalty for something that's supposed to | ||||
|             // check whether the region is too busy! Especially on sims with LOTS of regions. | ||||
|             // Alternative: make heuristics thresholds global to the module rather than per-region. Less flexible, | ||||
|             //  but would allow us to be semantically correct while being easier on perf. | ||||
|             // Alternative 2: Run heuristics once per unique set of heuristics threshold parameters! Ay yi yi... | ||||
|             // Alternative 3: Don't support per-region heuristics at all; just accept them as a global only parameter. | ||||
|             // Since this is pretty experimental, I haven't decided which alternative makes the most sense. | ||||
|             if (this.m_closed) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             bool heuristicsRun = false; | ||||
|             bool heuristicsPassed = false; | ||||
|             if (!this.m_timerMap.ContainsKey((Timer) sender)) | ||||
|             { | ||||
|                 m_log.Debug("Code-up error: timerMap doesn't contain timer " + sender); | ||||
|             } | ||||
| 
 | ||||
|             List<IScene> tmap = this.m_timerMap[(Timer) sender]; | ||||
|             if (tmap != null && tmap.Count > 0) | ||||
|             { | ||||
|                 foreach (IScene scene in tmap) | ||||
|                 { | ||||
|                     AutoBackupModuleState state = this.m_states[scene]; | ||||
|                     bool heuristics = state.BusyCheck; | ||||
| 
 | ||||
|                     // Fast path: heuristics are on; already ran em; and sim is fine; OR, no heuristics for the region. | ||||
|                     if ((heuristics && heuristicsRun && heuristicsPassed) || !heuristics) | ||||
|                     { | ||||
|                         this.DoRegionBackup(scene); | ||||
|                         // Heuristics are on; ran but we're too busy -- keep going. Maybe another region will have heuristics off! | ||||
|                     } | ||||
|                     else if (heuristicsRun) | ||||
|                     { | ||||
|                         m_log.Info("[AUTO BACKUP]: Heuristics: too busy to backup " + | ||||
|                                    scene.RegionInfo.RegionName + " right now."); | ||||
|                         continue; | ||||
|                         // Logical Deduction: heuristics are on but haven't been run | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         heuristicsPassed = this.RunHeuristics(scene); | ||||
|                         heuristicsRun = true; | ||||
|                         if (!heuristicsPassed) | ||||
|                         { | ||||
|                             m_log.Info("[AUTO BACKUP]: Heuristics: too busy to backup " + | ||||
|                                        scene.RegionInfo.RegionName + " right now."); | ||||
|                             continue; | ||||
|                         } | ||||
|                         this.DoRegionBackup(scene); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Save an OAR, register for the callback for when it's done, then call the AutoBackupScript (if applicable). | ||||
|         /// </summary> | ||||
|         /// <param name="scene"></param> | ||||
|         private void DoRegionBackup(IScene scene) | ||||
|         { | ||||
|             if (scene.RegionStatus != RegionStatus.Up) | ||||
|             { | ||||
|                 // We won't backup a region that isn't operating normally. | ||||
|                 m_log.Warn("[AUTO BACKUP]: Not backing up region " + scene.RegionInfo.RegionName + | ||||
|                            " because its status is " + scene.RegionStatus); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             AutoBackupModuleState state = this.m_states[scene]; | ||||
|             IRegionArchiverModule iram = scene.RequestModuleInterface<IRegionArchiverModule>(); | ||||
|             string savePath = BuildOarPath(scene.RegionInfo.RegionName, | ||||
|                                                 state.BackupDir, | ||||
|                                                 state.NamingType); | ||||
|             if (savePath == null) | ||||
|             { | ||||
|                 m_log.Warn("[AUTO BACKUP]: savePath is null in HandleElapsed"); | ||||
|                 return; | ||||
|             } | ||||
|             Guid guid = Guid.NewGuid(); | ||||
|             m_pendingSaves.Add(guid, scene); | ||||
|             state.LiveRequests.Add(guid, savePath); | ||||
|             ((Scene) scene).EventManager.OnOarFileSaved += new EventManager.OarFileSaved(EventManager_OnOarFileSaved); | ||||
|             iram.ArchiveRegion(savePath, guid, null); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Called by the Event Manager when the OnOarFileSaved event is fired. | ||||
|         /// </summary> | ||||
|         /// <param name="guid"></param> | ||||
|         /// <param name="message"></param> | ||||
|         void EventManager_OnOarFileSaved(Guid guid, string message) | ||||
|         { | ||||
|             // Ignore if the OAR save is being done by some other part of the system | ||||
|             if (m_pendingSaves.ContainsKey(guid)) | ||||
|             { | ||||
|                 AutoBackupModuleState abms = m_states[(m_pendingSaves[guid])]; | ||||
|                 ExecuteScript(abms.Script, abms.LiveRequests[guid]); | ||||
|                 m_pendingSaves.Remove(guid); | ||||
|                 abms.LiveRequests.Remove(guid); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary>This format may turn out to be too unwieldy to keep... | ||||
|         /// Besides, that's what ctimes are for. But then how do I name each file uniquely without using a GUID? | ||||
|         /// Sequential numbers, right? We support those, too!</summary> | ||||
|         private static string GetTimeString() | ||||
|         { | ||||
|             StringWriter sw = new StringWriter(); | ||||
|             sw.Write("_"); | ||||
|             DateTime now = DateTime.Now; | ||||
|             sw.Write(now.Year); | ||||
|             sw.Write("y_"); | ||||
|             sw.Write(now.Month); | ||||
|             sw.Write("M_"); | ||||
|             sw.Write(now.Day); | ||||
|             sw.Write("d_"); | ||||
|             sw.Write(now.Hour); | ||||
|             sw.Write("h_"); | ||||
|             sw.Write(now.Minute); | ||||
|             sw.Write("m_"); | ||||
|             sw.Write(now.Second); | ||||
|             sw.Write("s"); | ||||
|             sw.Flush(); | ||||
|             string output = sw.ToString(); | ||||
|             sw.Close(); | ||||
|             return output; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary>Return value of true ==> not too busy; false ==> too busy to backup an OAR right now, or error.</summary> | ||||
|         private bool RunHeuristics(IScene region) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 return this.RunTimeDilationHeuristic(region) && this.RunAgentLimitHeuristic(region); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 m_log.Warn("[AUTO BACKUP]: Exception in RunHeuristics", e); | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// If the time dilation right at this instant is less than the threshold specified in AutoBackupDilationThreshold (default 0.5), | ||||
|         /// then we return false and trip the busy heuristic's "too busy" path (i.e. don't save an OAR). | ||||
|         /// AutoBackupDilationThreshold is a _LOWER BOUND_. Lower Time Dilation is bad, so if you go lower than our threshold, it's "too busy". | ||||
|         /// </summary> | ||||
|         /// <param name="region"></param> | ||||
|         /// <returns>Returns true if we're not too busy; false means we've got worse time dilation than the threshold.</returns> | ||||
|         private bool RunTimeDilationHeuristic(IScene region) | ||||
|         { | ||||
|             string regionName = region.RegionInfo.RegionName; | ||||
|             return region.TimeDilation >= | ||||
|                    this.m_configSource.Configs["AutoBackupModule"].GetFloat( | ||||
|                        regionName + ".AutoBackupDilationThreshold", 0.5f); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// If the root agent count right at this instant is less than the threshold specified in AutoBackupAgentThreshold (default 10), | ||||
|         /// then we return false and trip the busy heuristic's "too busy" path (i.e., don't save an OAR). | ||||
|         /// AutoBackupAgentThreshold is an _UPPER BOUND_. Higher Agent Count is bad, so if you go higher than our threshold, it's "too busy". | ||||
|         /// </summary> | ||||
|         /// <param name="region"></param> | ||||
|         /// <returns>Returns true if we're not too busy; false means we've got more agents on the sim than the threshold.</returns> | ||||
|         private bool RunAgentLimitHeuristic(IScene region) | ||||
|         { | ||||
|             string regionName = region.RegionInfo.RegionName; | ||||
|             try | ||||
|             { | ||||
|                 Scene scene = (Scene) region; | ||||
|                 // TODO: Why isn't GetRootAgentCount() a method in the IScene interface? Seems generally useful... | ||||
|                 return scene.GetRootAgentCount() <= | ||||
|                        this.m_configSource.Configs["AutoBackupModule"].GetInt( | ||||
|                            regionName + ".AutoBackupAgentThreshold", 10); | ||||
|             } | ||||
|             catch (InvalidCastException ice) | ||||
|             { | ||||
|                 m_log.Debug( | ||||
|                     "[AUTO BACKUP]: I NEED MAINTENANCE: IScene is not a Scene; can't get root agent count!", | ||||
|                     ice); | ||||
|                 return true; | ||||
|                 // Non-obstructionist safest answer... | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Run the script or executable specified by the "AutoBackupScript" config setting. | ||||
|         /// Of course this is a security risk if you let anyone modify OpenSim.ini and they want to run some nasty bash script. | ||||
|         /// But there are plenty of other nasty things that can be done with an untrusted OpenSim.ini, such as running high threat level scripting functions. | ||||
|         /// </summary> | ||||
|         /// <param name="scriptName"></param> | ||||
|         /// <param name="savePath"></param> | ||||
|         private static void ExecuteScript(string scriptName, string savePath) | ||||
|         { | ||||
|             // Do nothing if there's no script. | ||||
|             if (scriptName == null || scriptName.Length <= 0) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 FileInfo fi = new FileInfo(scriptName); | ||||
|                 if (fi.Exists) | ||||
|                 { | ||||
|                     ProcessStartInfo psi = new ProcessStartInfo(scriptName); | ||||
|                     psi.Arguments = savePath; | ||||
|                     psi.CreateNoWindow = true; | ||||
|                     Process proc = Process.Start(psi); | ||||
|                     proc.ErrorDataReceived += HandleProcErrorDataReceived; | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 m_log.Warn( | ||||
|                     "Exception encountered when trying to run script for oar backup " + savePath, e); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Called if a running script process writes to stderr. | ||||
|         /// </summary> | ||||
|         /// <param name="sender"></param> | ||||
|         /// <param name="e"></param> | ||||
|         private static void HandleProcErrorDataReceived(object sender, DataReceivedEventArgs e) | ||||
|         { | ||||
|             m_log.Warn("ExecuteScript hook " + ((Process) sender).ProcessName + | ||||
|                        " is yacking on stderr: " + e.Data); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Quickly stop all timers from firing. | ||||
|         /// </summary> | ||||
|         private void StopAllTimers() | ||||
|         { | ||||
|             foreach (Timer t in this.m_timerMap.Keys) | ||||
|             { | ||||
|                 t.Close(); | ||||
|             } | ||||
|             this.m_closed = true; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Determine the next unique filename by number, for "Sequential" AutoBackupNamingType. | ||||
|         /// </summary> | ||||
|         /// <param name="dirName"></param> | ||||
|         /// <param name="regionName"></param> | ||||
|         /// <returns></returns> | ||||
|         private static string GetNextFile(string dirName, string regionName) | ||||
|         { | ||||
|             FileInfo uniqueFile = null; | ||||
|             long biggestExistingFile = GetNextOarFileNumber(dirName, regionName); | ||||
|             biggestExistingFile++; | ||||
|             // We don't want to overwrite the biggest existing file; we want to write to the NEXT biggest. | ||||
|             uniqueFile = | ||||
|                 new FileInfo(dirName + Path.DirectorySeparatorChar + regionName + "_" + | ||||
|                              biggestExistingFile + ".oar"); | ||||
|             return uniqueFile.FullName; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Top-level method for creating an absolute path to an OAR backup file based on what naming scheme the user wants. | ||||
|         /// </summary> | ||||
|         /// <param name="regionName">Name of the region to save.</param> | ||||
|         /// <param name="baseDir">Absolute or relative path to the directory where the file should reside.</param> | ||||
|         /// <param name="naming">The naming scheme for the file name.</param> | ||||
|         /// <returns></returns> | ||||
|         private static string BuildOarPath(string regionName, string baseDir, NamingType naming) | ||||
|         { | ||||
|             FileInfo path = null; | ||||
|             switch (naming) | ||||
|             { | ||||
|                 case NamingType.Overwrite: | ||||
|                     path = new FileInfo(baseDir + Path.DirectorySeparatorChar + regionName + ".oar"); | ||||
|                     return path.FullName; | ||||
|                 case NamingType.Time: | ||||
|                     path = | ||||
|                         new FileInfo(baseDir + Path.DirectorySeparatorChar + regionName + | ||||
|                                      GetTimeString() + ".oar"); | ||||
|                     return path.FullName; | ||||
|                 case NamingType.Sequential: | ||||
|                     // All codepaths in GetNextFile should return a file name ending in .oar | ||||
|                     path = new FileInfo(GetNextFile(baseDir, regionName)); | ||||
|                     return path.FullName; | ||||
|                 default: | ||||
|                     m_log.Warn("VERY BAD: Unhandled case element " + naming); | ||||
|                     break; | ||||
|             } | ||||
| 
 | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Helper function for Sequential file naming type (see BuildOarPath and GetNextFile). | ||||
|         /// </summary> | ||||
|         /// <param name="dirName"></param> | ||||
|         /// <param name="regionName"></param> | ||||
|         /// <returns></returns> | ||||
|         private static long GetNextOarFileNumber(string dirName, string regionName) | ||||
|         { | ||||
|             long retval = 1; | ||||
| 
 | ||||
|             DirectoryInfo di = new DirectoryInfo(dirName); | ||||
|             FileInfo[] fi = di.GetFiles(regionName, SearchOption.TopDirectoryOnly); | ||||
|             Array.Sort(fi, (f1, f2) => StringComparer.CurrentCultureIgnoreCase.Compare(f1.Name, f2.Name)); | ||||
| 
 | ||||
|             if (fi.LongLength > 0) | ||||
|             { | ||||
|                 long subtract = 1L; | ||||
|                 bool worked = false; | ||||
|                 Regex reg = new Regex(regionName + "_([0-9])+" + ".oar"); | ||||
| 
 | ||||
|                 while (!worked && subtract <= fi.LongLength) | ||||
|                 { | ||||
|                     // Pick the file with the last natural ordering | ||||
|                     string biggestFileName = fi[fi.LongLength - subtract].Name; | ||||
|                     MatchCollection matches = reg.Matches(biggestFileName); | ||||
|                     long l = 1; | ||||
|                     if (matches.Count > 0 && matches[0].Groups.Count > 0) | ||||
|                     { | ||||
|                         try | ||||
|                         { | ||||
|                             long.TryParse(matches[0].Groups[1].Value, out l); | ||||
|                             retval = l; | ||||
|                             worked = true; | ||||
|                         } | ||||
|                         catch (FormatException fe) | ||||
|                         { | ||||
|                             m_log.Warn( | ||||
|                                 "[AUTO BACKUP]: Error: Can't parse long value from file name to determine next OAR backup file number!", | ||||
|                                 fe); | ||||
|                             subtract++; | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         subtract++; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return retval; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -0,0 +1,126 @@ | |||
| /* | ||||
|  * 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. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       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; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| 
 | ||||
| namespace OpenSim.Region.OptionalModules.World.AutoBackup | ||||
| { | ||||
|     /// <summary>AutoBackupModuleState: Auto-Backup state for one region (scene). | ||||
|     /// If you use this class in any way outside of AutoBackupModule, you should treat the class as opaque. | ||||
|     /// Since it is not part of the framework, you really should not rely upon it outside of the AutoBackupModule implementation. | ||||
|     /// </summary> | ||||
|     ///  | ||||
|     public class AutoBackupModuleState | ||||
|     { | ||||
|         private Dictionary<Guid, string> m_liveRequests = null; | ||||
| 
 | ||||
|         public AutoBackupModuleState() | ||||
|         { | ||||
|             this.Enabled = false; | ||||
|             this.BackupDir = "."; | ||||
|             this.BusyCheck = true; | ||||
|             this.Timer = null; | ||||
|             this.NamingType = NamingType.Time; | ||||
|             this.Script = null; | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<Guid, string> LiveRequests | ||||
|         { | ||||
|             get { | ||||
|                 return this.m_liveRequests ?? | ||||
|                        (this.m_liveRequests = new Dictionary<Guid, string>(1)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public bool Enabled | ||||
|         { | ||||
|             get; | ||||
|             set; | ||||
|         } | ||||
| 
 | ||||
|         public System.Timers.Timer Timer | ||||
|         { | ||||
|             get; | ||||
|             set; | ||||
|         } | ||||
| 
 | ||||
|         public double IntervalMinutes | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (this.Timer == null) | ||||
|                 { | ||||
|                     return -1.0; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return this.Timer.Interval / 60000.0; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public bool BusyCheck | ||||
|         { | ||||
|             get; | ||||
|             set; | ||||
|         } | ||||
| 
 | ||||
|         public string Script | ||||
|         { | ||||
|             get; | ||||
|             set; | ||||
|         } | ||||
| 
 | ||||
|         public string BackupDir | ||||
|         { | ||||
|             get; | ||||
|             set; | ||||
|         } | ||||
| 
 | ||||
|         public NamingType NamingType | ||||
|         { | ||||
|             get; | ||||
|             set; | ||||
|         } | ||||
| 
 | ||||
|         public new string ToString() | ||||
|         { | ||||
|             string retval = ""; | ||||
| 
 | ||||
|             retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n"; | ||||
|             retval += "[AUTO BACKUP]: Interval: " + IntervalMinutes + " minutes" + "\n"; | ||||
|             retval += "[AUTO BACKUP]: Do Busy Check: " + (BusyCheck ? "Yes" : "No") + "\n"; | ||||
|             retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n"; | ||||
|             retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n"; | ||||
|             retval += "[AUTO BACKUP]: Script: " + Script + "\n"; | ||||
|             return retval; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -97,16 +97,76 @@ namespace OpenSim.Server.Base | |||
| 
 | ||||
|             if (port == 0) | ||||
|             { | ||||
|                 System.Console.WriteLine("Port number not specified or 0, server can't start"); | ||||
| 
 | ||||
|                 Thread.CurrentThread.Abort(); | ||||
|             } | ||||
|             // | ||||
|             bool ssl_main = networkConfig.GetBoolean("https_main",false); | ||||
|             bool ssl_listener = networkConfig.GetBoolean("https_listener",false); | ||||
| 
 | ||||
|             m_consolePort = (uint)networkConfig.GetInt("ConsolePort", 0); | ||||
|             m_Port = port; | ||||
|             // | ||||
|             // This is where to make the servers: | ||||
|             // | ||||
|             // | ||||
|             // Make the base server according to the port, etc. | ||||
|             // ADD: Possibility to make main server ssl | ||||
|             // Then, check for https settings and ADD a server to | ||||
|             // m_Servers | ||||
|             // | ||||
|             if ( !ssl_main ) | ||||
|             { | ||||
|                 m_HttpServer = new BaseHttpServer(port); | ||||
| 
 | ||||
|             m_HttpServer = new BaseHttpServer(port); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 string cert_path = networkConfig.GetString("cert_path",String.Empty); | ||||
|                 if ( cert_path == String.Empty ) | ||||
|                 { | ||||
|                     System.Console.WriteLine("Path to X509 certificate is missing, server can't start."); | ||||
|                     Thread.CurrentThread.Abort(); | ||||
|                 } | ||||
|                 string cert_pass = networkConfig.GetString("cert_pass",String.Empty); | ||||
|                 if ( cert_pass == String.Empty ) | ||||
|                 { | ||||
|                     System.Console.WriteLine("Password for X509 certificate is missing, server can't start."); | ||||
|                     Thread.CurrentThread.Abort(); | ||||
|                 } | ||||
|                 m_HttpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass); | ||||
|             } | ||||
| 
 | ||||
|             MainServer.Instance = m_HttpServer; | ||||
| 
 | ||||
|             // If https_listener = true, then add an ssl listener on the https_port... | ||||
|             if ( ssl_listener == true ) { | ||||
| 
 | ||||
|                 uint https_port = (uint)networkConfig.GetInt("https_port", 0); | ||||
| 
 | ||||
|                 string cert_path = networkConfig.GetString("cert_path",String.Empty); | ||||
|                 if ( cert_path == String.Empty ) | ||||
|                 { | ||||
|                     System.Console.WriteLine("Path to X509 certificate is missing, server can't start."); | ||||
|                     Thread.CurrentThread.Abort(); | ||||
|                 } | ||||
|                 string cert_pass = networkConfig.GetString("cert_pass",String.Empty); | ||||
|                 if ( cert_pass == String.Empty ) | ||||
|                 { | ||||
|                     System.Console.WriteLine("Password for X509 certificate is missing, server can't start."); | ||||
|                     Thread.CurrentThread.Abort(); | ||||
|                 } | ||||
|                 // Add our https_server | ||||
|                 BaseHttpServer server = null; | ||||
|                 server = new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass); | ||||
|                 if (server != null) | ||||
|                 { | ||||
|                     m_Log.InfoFormat("[SERVER]: Starting HTTPS server on port {0}", https_port); | ||||
|                     m_Servers.Add(https_port,server); | ||||
|                 } | ||||
|                 else | ||||
|                     System.Console.WriteLine(String.Format("Failed to start HTTPS server on port {0}",https_port)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         protected override void Initialise() | ||||
|  | @ -114,6 +174,19 @@ namespace OpenSim.Server.Base | |||
|             m_Log.InfoFormat("[SERVER]: Starting HTTP server on port {0}", m_HttpServer.Port); | ||||
|             m_HttpServer.Start(); | ||||
| 
 | ||||
|             if (m_Servers.Count > 0) | ||||
|             { | ||||
|                 foreach (BaseHttpServer s in m_Servers.Values) | ||||
|                 { | ||||
|                     if (!s.UseSSL) | ||||
|                         m_Log.InfoFormat("[SERVER]: Starting HTTP server on port {0}", s.Port); | ||||
|                     else | ||||
|                         m_Log.InfoFormat("[SERVER]: Starting HTTPS server on port {0}", s.Port); | ||||
| 
 | ||||
|                     s.Start(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (MainConsole.Instance is RemoteConsole) | ||||
|             { | ||||
|                 if (m_consolePort == 0) | ||||
|  |  | |||
|  | @ -49,13 +49,13 @@ using log4net; | |||
| 
 | ||||
| namespace OpenSim.Server.Handlers.Hypergrid | ||||
| { | ||||
|     public class GatekeeperAgentHandler : OpenSim.Server.Handlers.Simulation.AgentHandler | ||||
|     public class GatekeeperAgentHandler : OpenSim.Server.Handlers.Simulation.AgentPostHandler | ||||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|          | ||||
|         private IGatekeeperService m_GatekeeperService; | ||||
| 
 | ||||
|         public GatekeeperAgentHandler(IGatekeeperService gatekeeper, bool proxy) | ||||
|         public GatekeeperAgentHandler(IGatekeeperService gatekeeper, bool proxy) : base("/foreignagent") | ||||
|         { | ||||
|             m_GatekeeperService = gatekeeper; | ||||
|             m_Proxy = proxy; | ||||
|  | @ -65,7 +65,5 @@ namespace OpenSim.Server.Handlers.Hypergrid | |||
|         { | ||||
|             return m_GatekeeperService.LoginAgent(aCircuit, destination, out reason); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -73,7 +73,7 @@ namespace OpenSim.Server.Handlers.Hypergrid | |||
|             server.AddXmlRPCHandler("link_region", hghandlers.LinkRegionRequest, false); | ||||
|             server.AddXmlRPCHandler("get_region", hghandlers.GetRegion, false); | ||||
| 
 | ||||
|             server.AddHTTPHandler("/foreignagent/", new GatekeeperAgentHandler(m_GatekeeperService, m_Proxy).Handler); | ||||
|             server.AddStreamHandler(new GatekeeperAgentHandler(m_GatekeeperService, m_Proxy)); | ||||
|         } | ||||
| 
 | ||||
|         public GatekeeperServiceInConnector(IConfigSource config, IHttpServer server) | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ | |||
| using System; | ||||
| using System.Collections; | ||||
| using System.IO; | ||||
| using System.IO.Compression; | ||||
| using System.Reflection; | ||||
| using System.Net; | ||||
| using System.Text; | ||||
|  | @ -53,8 +54,6 @@ namespace OpenSim.Server.Handlers.Simulation | |||
| 
 | ||||
|         private ISimulationService m_SimulationService; | ||||
| 
 | ||||
|         protected bool m_Proxy = false; | ||||
| 
 | ||||
|         public AgentHandler() { } | ||||
| 
 | ||||
|         public AgentHandler(ISimulationService sim) | ||||
|  | @ -91,17 +90,7 @@ namespace OpenSim.Server.Handlers.Simulation | |||
| 
 | ||||
|             // Next, let's parse the verb | ||||
|             string method = (string)request["http-method"]; | ||||
|             if (method.Equals("PUT")) | ||||
|             { | ||||
|                 DoAgentPut(request, responsedata); | ||||
|                 return responsedata; | ||||
|             } | ||||
|             else if (method.Equals("POST")) | ||||
|             { | ||||
|                 DoAgentPost(request, responsedata, agentID); | ||||
|                 return responsedata; | ||||
|             } | ||||
|             else if (method.Equals("GET")) | ||||
|             if (method.Equals("GET")) | ||||
|             { | ||||
|                 DoAgentGet(request, responsedata, agentID, regionID); | ||||
|                 return responsedata; | ||||
|  | @ -127,199 +116,6 @@ namespace OpenSim.Server.Handlers.Simulation | |||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         protected void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) | ||||
|         { | ||||
|             OSDMap args = Utils.GetOSDMap((string)request["body"]); | ||||
|             if (args == null) | ||||
|             { | ||||
|                 responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||||
|                 responsedata["str_response_string"] = "Bad request"; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // retrieve the input arguments | ||||
|             int x = 0, y = 0; | ||||
|             UUID uuid = UUID.Zero; | ||||
|             string regionname = string.Empty; | ||||
|             uint teleportFlags = 0; | ||||
|             if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||||
|                 Int32.TryParse(args["destination_x"].AsString(), out x); | ||||
|             else | ||||
|                 m_log.WarnFormat("  -- request didn't have destination_x"); | ||||
|             if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||||
|                 Int32.TryParse(args["destination_y"].AsString(), out y); | ||||
|             else | ||||
|                 m_log.WarnFormat("  -- request didn't have destination_y"); | ||||
|             if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||||
|                 UUID.TryParse(args["destination_uuid"].AsString(), out uuid); | ||||
|             if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||||
|                 regionname = args["destination_name"].ToString(); | ||||
|             if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null) | ||||
|                 teleportFlags = args["teleport_flags"].AsUInteger(); | ||||
| 
 | ||||
|             GridRegion destination = new GridRegion(); | ||||
|             destination.RegionID = uuid; | ||||
|             destination.RegionLocX = x; | ||||
|             destination.RegionLocY = y; | ||||
|             destination.RegionName = regionname; | ||||
| 
 | ||||
|             AgentCircuitData aCircuit = new AgentCircuitData(); | ||||
|             try | ||||
|             { | ||||
|                 aCircuit.UnpackAgentCircuitData(args); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message); | ||||
|                 responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||||
|                 responsedata["str_response_string"] = "Bad request"; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             OSDMap resp = new OSDMap(2); | ||||
|             string reason = String.Empty; | ||||
| 
 | ||||
|             // This is the meaning of POST agent | ||||
|             //m_regionClient.AdjustUserInformation(aCircuit); | ||||
|             //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||||
|             bool result = CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||||
| 
 | ||||
|             resp["reason"] = OSD.FromString(reason); | ||||
|             resp["success"] = OSD.FromBoolean(result); | ||||
|             // Let's also send out the IP address of the caller back to the caller (HG 1.5) | ||||
|             resp["your_ip"] = OSD.FromString(GetCallerIP(request)); | ||||
| 
 | ||||
|             // TODO: add reason if not String.Empty? | ||||
|             responsedata["int_response_code"] = HttpStatusCode.OK; | ||||
|             responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); | ||||
|         } | ||||
| 
 | ||||
|         private string GetCallerIP(Hashtable request) | ||||
|         { | ||||
|             if (!m_Proxy) | ||||
|                 return Util.GetCallerIP(request); | ||||
| 
 | ||||
|             // We're behind a proxy | ||||
|             Hashtable headers = (Hashtable)request["headers"]; | ||||
| 
 | ||||
|             //// DEBUG | ||||
|             //foreach (object o in headers.Keys) | ||||
|             //    m_log.DebugFormat("XXX {0} = {1}", o.ToString(), (headers[o] == null? "null" : headers[o].ToString())); | ||||
| 
 | ||||
|             string xff = "X-Forwarded-For"; | ||||
|             if (headers.ContainsKey(xff.ToLower())) | ||||
|                 xff = xff.ToLower(); | ||||
| 
 | ||||
|             if (!headers.ContainsKey(xff) || headers[xff] == null) | ||||
|             { | ||||
|                 m_log.WarnFormat("[AGENT HANDLER]: No XFF header"); | ||||
|                 return Util.GetCallerIP(request); | ||||
|             } | ||||
| 
 | ||||
|             m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]); | ||||
| 
 | ||||
|             IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]); | ||||
|             if (ep != null) | ||||
|                 return ep.Address.ToString(); | ||||
| 
 | ||||
|             // Oops | ||||
|             return Util.GetCallerIP(request); | ||||
|         } | ||||
| 
 | ||||
|         // subclasses can override this | ||||
|         protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) | ||||
|         { | ||||
|             return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||||
|         } | ||||
| 
 | ||||
|         protected void DoAgentPut(Hashtable request, Hashtable responsedata) | ||||
|         { | ||||
|             OSDMap args = Utils.GetOSDMap((string)request["body"]); | ||||
|             if (args == null) | ||||
|             { | ||||
|                 responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||||
|                 responsedata["str_response_string"] = "Bad request"; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // retrieve the input arguments | ||||
|             int x = 0, y = 0; | ||||
|             UUID uuid = UUID.Zero; | ||||
|             string regionname = string.Empty; | ||||
|             if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||||
|                 Int32.TryParse(args["destination_x"].AsString(), out x); | ||||
|             if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||||
|                 Int32.TryParse(args["destination_y"].AsString(), out y); | ||||
|             if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||||
|                 UUID.TryParse(args["destination_uuid"].AsString(), out uuid); | ||||
|             if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||||
|                 regionname = args["destination_name"].ToString(); | ||||
| 
 | ||||
|             GridRegion destination = new GridRegion(); | ||||
|             destination.RegionID = uuid; | ||||
|             destination.RegionLocX = x; | ||||
|             destination.RegionLocY = y; | ||||
|             destination.RegionName = regionname; | ||||
| 
 | ||||
|             string messageType; | ||||
|             if (args["message_type"] != null) | ||||
|                 messageType = args["message_type"].AsString(); | ||||
|             else | ||||
|             { | ||||
|                 m_log.Warn("[AGENT HANDLER]: Agent Put Message Type not found. "); | ||||
|                 messageType = "AgentData"; | ||||
|             } | ||||
| 
 | ||||
|             bool result = true; | ||||
|             if ("AgentData".Equals(messageType)) | ||||
|             { | ||||
|                 AgentData agent = new AgentData(); | ||||
|                 try | ||||
|                 { | ||||
|                     agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); | ||||
|                     responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||||
|                     responsedata["str_response_string"] = "Bad request"; | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 //agent.Dump(); | ||||
|                 // This is one of the meanings of PUT agent | ||||
|                 result = UpdateAgent(destination, agent); | ||||
| 
 | ||||
|             } | ||||
|             else if ("AgentPosition".Equals(messageType)) | ||||
|             { | ||||
|                 AgentPosition agent = new AgentPosition(); | ||||
|                 try | ||||
|                 { | ||||
|                     agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); | ||||
|                     return; | ||||
|                 } | ||||
|                 //agent.Dump(); | ||||
|                 // This is one of the meanings of PUT agent | ||||
|                 result = m_SimulationService.UpdateAgent(destination, agent); | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|             responsedata["int_response_code"] = HttpStatusCode.OK; | ||||
|             responsedata["str_response_string"] = result.ToString(); | ||||
|             //responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); ??? instead | ||||
|         } | ||||
| 
 | ||||
|         // subclasses can override this | ||||
|         protected virtual bool UpdateAgent(GridRegion destination, AgentData agent) | ||||
|         { | ||||
|             return m_SimulationService.UpdateAgent(destination, agent); | ||||
|         } | ||||
| 
 | ||||
|         protected virtual void DoQueryAccess(Hashtable request, Hashtable responsedata, UUID id, UUID regionID) | ||||
|         { | ||||
|             if (m_SimulationService == null) | ||||
|  | @ -434,4 +230,360 @@ namespace OpenSim.Server.Handlers.Simulation | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public class AgentPostHandler : BaseStreamHandler | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private ISimulationService m_SimulationService; | ||||
|         protected bool m_Proxy = false; | ||||
| 
 | ||||
|         public AgentPostHandler(ISimulationService service) : | ||||
|                 base("POST", "/agent") | ||||
|         { | ||||
|             m_SimulationService = service; | ||||
|         } | ||||
| 
 | ||||
|         public AgentPostHandler(string path) : | ||||
|                 base("POST", path) | ||||
|         { | ||||
|             m_SimulationService = null; | ||||
|         } | ||||
| 
 | ||||
|         public override byte[] Handle(string path, Stream request, | ||||
|                 OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||||
|         { | ||||
|             m_log.DebugFormat("[SIMULATION]: Stream handler called"); | ||||
| 
 | ||||
|             Hashtable keysvals = new Hashtable(); | ||||
|             Hashtable headervals = new Hashtable(); | ||||
| 
 | ||||
|             string[] querystringkeys = httpRequest.QueryString.AllKeys; | ||||
|             string[] rHeaders = httpRequest.Headers.AllKeys; | ||||
| 
 | ||||
|             keysvals.Add("uri", httpRequest.RawUrl); | ||||
|             keysvals.Add("content-type", httpRequest.ContentType); | ||||
|             keysvals.Add("http-method", httpRequest.HttpMethod); | ||||
| 
 | ||||
|             foreach (string queryname in querystringkeys) | ||||
|                 keysvals.Add(queryname, httpRequest.QueryString[queryname]); | ||||
| 
 | ||||
|             foreach (string headername in rHeaders) | ||||
|                 headervals[headername] = httpRequest.Headers[headername]; | ||||
| 
 | ||||
|             keysvals.Add("headers", headervals); | ||||
|             keysvals.Add("querystringkeys", querystringkeys); | ||||
| 
 | ||||
|             Stream inputStream; | ||||
|             if (httpRequest.ContentType == "application/x-gzip") | ||||
|                 inputStream = new GZipStream(request, CompressionMode.Decompress); | ||||
|             else | ||||
|                 inputStream = request; | ||||
| 
 | ||||
|             Encoding encoding = Encoding.UTF8; | ||||
|             StreamReader reader = new StreamReader(inputStream, encoding); | ||||
| 
 | ||||
|             string requestBody = reader.ReadToEnd(); | ||||
|             reader.Close(); | ||||
|             keysvals.Add("body", requestBody); | ||||
| 
 | ||||
|             httpResponse.StatusCode = 200; | ||||
|             httpResponse.ContentType = "text/html"; | ||||
|             httpResponse.KeepAlive = false; | ||||
| 
 | ||||
|             Hashtable responsedata = new Hashtable(); | ||||
| 
 | ||||
|             UUID agentID; | ||||
|             UUID regionID; | ||||
|             string action; | ||||
| 
 | ||||
|             if (!Utils.GetParams((string)keysvals["uri"], out agentID, out regionID, out action)) | ||||
|             { | ||||
|                 m_log.InfoFormat("[AGENT HANDLER]: Invalid parameters for agent message {0}", keysvals["uri"]); | ||||
| 
 | ||||
|                 httpResponse.StatusCode = 404; | ||||
| 
 | ||||
|                 return encoding.GetBytes("false"); | ||||
|             } | ||||
| 
 | ||||
|             DoAgentPost(keysvals, responsedata, agentID); | ||||
| 
 | ||||
|             httpResponse.StatusCode = (int)responsedata["int_response_code"]; | ||||
|             return encoding.GetBytes((string)responsedata["str_response_string"]); | ||||
|         } | ||||
| 
 | ||||
|         protected void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) | ||||
|         { | ||||
|             OSDMap args = Utils.GetOSDMap((string)request["body"]); | ||||
|             if (args == null) | ||||
|             { | ||||
|                 responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||||
|                 responsedata["str_response_string"] = "Bad request"; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // retrieve the input arguments | ||||
|             int x = 0, y = 0; | ||||
|             UUID uuid = UUID.Zero; | ||||
|             string regionname = string.Empty; | ||||
|             uint teleportFlags = 0; | ||||
|             if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||||
|                 Int32.TryParse(args["destination_x"].AsString(), out x); | ||||
|             else | ||||
|                 m_log.WarnFormat("  -- request didn't have destination_x"); | ||||
|             if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||||
|                 Int32.TryParse(args["destination_y"].AsString(), out y); | ||||
|             else | ||||
|                 m_log.WarnFormat("  -- request didn't have destination_y"); | ||||
|             if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||||
|                 UUID.TryParse(args["destination_uuid"].AsString(), out uuid); | ||||
|             if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||||
|                 regionname = args["destination_name"].ToString(); | ||||
|             if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null) | ||||
|                 teleportFlags = args["teleport_flags"].AsUInteger(); | ||||
| 
 | ||||
|             GridRegion destination = new GridRegion(); | ||||
|             destination.RegionID = uuid; | ||||
|             destination.RegionLocX = x; | ||||
|             destination.RegionLocY = y; | ||||
|             destination.RegionName = regionname; | ||||
| 
 | ||||
|             AgentCircuitData aCircuit = new AgentCircuitData(); | ||||
|             try | ||||
|             { | ||||
|                 aCircuit.UnpackAgentCircuitData(args); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message); | ||||
|                 responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||||
|                 responsedata["str_response_string"] = "Bad request"; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             OSDMap resp = new OSDMap(2); | ||||
|             string reason = String.Empty; | ||||
| 
 | ||||
|             // This is the meaning of POST agent | ||||
|             //m_regionClient.AdjustUserInformation(aCircuit); | ||||
|             //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||||
|             bool result = CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||||
| 
 | ||||
|             resp["reason"] = OSD.FromString(reason); | ||||
|             resp["success"] = OSD.FromBoolean(result); | ||||
|             // Let's also send out the IP address of the caller back to the caller (HG 1.5) | ||||
|             resp["your_ip"] = OSD.FromString(GetCallerIP(request)); | ||||
| 
 | ||||
|             // TODO: add reason if not String.Empty? | ||||
|             responsedata["int_response_code"] = HttpStatusCode.OK; | ||||
|             responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); | ||||
|         } | ||||
| 
 | ||||
|         private string GetCallerIP(Hashtable request) | ||||
|         { | ||||
|             if (!m_Proxy) | ||||
|                 return Util.GetCallerIP(request); | ||||
| 
 | ||||
|             // We're behind a proxy | ||||
|             Hashtable headers = (Hashtable)request["headers"]; | ||||
| 
 | ||||
|             //// DEBUG | ||||
|             //foreach (object o in headers.Keys) | ||||
|             //    m_log.DebugFormat("XXX {0} = {1}", o.ToString(), (headers[o] == null? "null" : headers[o].ToString())); | ||||
| 
 | ||||
|             string xff = "X-Forwarded-For"; | ||||
|             if (headers.ContainsKey(xff.ToLower())) | ||||
|                 xff = xff.ToLower(); | ||||
| 
 | ||||
|             if (!headers.ContainsKey(xff) || headers[xff] == null) | ||||
|             { | ||||
|                 m_log.WarnFormat("[AGENT HANDLER]: No XFF header"); | ||||
|                 return Util.GetCallerIP(request); | ||||
|             } | ||||
| 
 | ||||
|             m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]); | ||||
| 
 | ||||
|             IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]); | ||||
|             if (ep != null) | ||||
|                 return ep.Address.ToString(); | ||||
| 
 | ||||
|             // Oops | ||||
|             return Util.GetCallerIP(request); | ||||
|         } | ||||
| 
 | ||||
|         // subclasses can override this | ||||
|         protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) | ||||
|         { | ||||
|             return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class AgentPutHandler : BaseStreamHandler | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private ISimulationService m_SimulationService; | ||||
|         protected bool m_Proxy = false; | ||||
| 
 | ||||
|         public AgentPutHandler(ISimulationService service) : | ||||
|                 base("PUT", "/agent") | ||||
|         { | ||||
|             m_SimulationService = service; | ||||
|         } | ||||
| 
 | ||||
|         public AgentPutHandler(string path) : | ||||
|                 base("PUT", path) | ||||
|         { | ||||
|             m_SimulationService = null; | ||||
|         } | ||||
| 
 | ||||
|         public override byte[] Handle(string path, Stream request, | ||||
|                 OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||||
|         { | ||||
|             m_log.DebugFormat("[SIMULATION]: Stream handler called"); | ||||
| 
 | ||||
|             Hashtable keysvals = new Hashtable(); | ||||
|             Hashtable headervals = new Hashtable(); | ||||
| 
 | ||||
|             string[] querystringkeys = httpRequest.QueryString.AllKeys; | ||||
|             string[] rHeaders = httpRequest.Headers.AllKeys; | ||||
| 
 | ||||
|             keysvals.Add("uri", httpRequest.RawUrl); | ||||
|             keysvals.Add("content-type", httpRequest.ContentType); | ||||
|             keysvals.Add("http-method", httpRequest.HttpMethod); | ||||
| 
 | ||||
|             foreach (string queryname in querystringkeys) | ||||
|                 keysvals.Add(queryname, httpRequest.QueryString[queryname]); | ||||
| 
 | ||||
|             foreach (string headername in rHeaders) | ||||
|                 headervals[headername] = httpRequest.Headers[headername]; | ||||
| 
 | ||||
|             keysvals.Add("headers", headervals); | ||||
|             keysvals.Add("querystringkeys", querystringkeys); | ||||
| 
 | ||||
|             Stream inputStream; | ||||
|             if (httpRequest.ContentType == "application/x-gzip") | ||||
|                 inputStream = new GZipStream(request, CompressionMode.Decompress); | ||||
|             else | ||||
|                 inputStream = request; | ||||
| 
 | ||||
|             Encoding encoding = Encoding.UTF8; | ||||
|             StreamReader reader = new StreamReader(inputStream, encoding); | ||||
| 
 | ||||
|             string requestBody = reader.ReadToEnd(); | ||||
|             reader.Close(); | ||||
|             keysvals.Add("body", requestBody); | ||||
| 
 | ||||
|             httpResponse.StatusCode = 200; | ||||
|             httpResponse.ContentType = "text/html"; | ||||
|             httpResponse.KeepAlive = false; | ||||
| 
 | ||||
|             Hashtable responsedata = new Hashtable(); | ||||
| 
 | ||||
|             UUID agentID; | ||||
|             UUID regionID; | ||||
|             string action; | ||||
| 
 | ||||
|             if (!Utils.GetParams((string)keysvals["uri"], out agentID, out regionID, out action)) | ||||
|             { | ||||
|                 m_log.InfoFormat("[AGENT HANDLER]: Invalid parameters for agent message {0}", keysvals["uri"]); | ||||
| 
 | ||||
|                 httpResponse.StatusCode = 404; | ||||
| 
 | ||||
|                 return encoding.GetBytes("false"); | ||||
|             } | ||||
| 
 | ||||
|             DoAgentPut(keysvals, responsedata); | ||||
| 
 | ||||
|             httpResponse.StatusCode = (int)responsedata["int_response_code"]; | ||||
|             return encoding.GetBytes((string)responsedata["str_response_string"]); | ||||
|         } | ||||
| 
 | ||||
|         protected void DoAgentPut(Hashtable request, Hashtable responsedata) | ||||
|         { | ||||
|             OSDMap args = Utils.GetOSDMap((string)request["body"]); | ||||
|             if (args == null) | ||||
|             { | ||||
|                 responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||||
|                 responsedata["str_response_string"] = "Bad request"; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // retrieve the input arguments | ||||
|             int x = 0, y = 0; | ||||
|             UUID uuid = UUID.Zero; | ||||
|             string regionname = string.Empty; | ||||
|             if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||||
|                 Int32.TryParse(args["destination_x"].AsString(), out x); | ||||
|             if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||||
|                 Int32.TryParse(args["destination_y"].AsString(), out y); | ||||
|             if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||||
|                 UUID.TryParse(args["destination_uuid"].AsString(), out uuid); | ||||
|             if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||||
|                 regionname = args["destination_name"].ToString(); | ||||
| 
 | ||||
|             GridRegion destination = new GridRegion(); | ||||
|             destination.RegionID = uuid; | ||||
|             destination.RegionLocX = x; | ||||
|             destination.RegionLocY = y; | ||||
|             destination.RegionName = regionname; | ||||
| 
 | ||||
|             string messageType; | ||||
|             if (args["message_type"] != null) | ||||
|                 messageType = args["message_type"].AsString(); | ||||
|             else | ||||
|             { | ||||
|                 m_log.Warn("[AGENT HANDLER]: Agent Put Message Type not found. "); | ||||
|                 messageType = "AgentData"; | ||||
|             } | ||||
| 
 | ||||
|             bool result = true; | ||||
|             if ("AgentData".Equals(messageType)) | ||||
|             { | ||||
|                 AgentData agent = new AgentData(); | ||||
|                 try | ||||
|                 { | ||||
|                     agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); | ||||
|                     responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||||
|                     responsedata["str_response_string"] = "Bad request"; | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 //agent.Dump(); | ||||
|                 // This is one of the meanings of PUT agent | ||||
|                 result = UpdateAgent(destination, agent); | ||||
| 
 | ||||
|             } | ||||
|             else if ("AgentPosition".Equals(messageType)) | ||||
|             { | ||||
|                 AgentPosition agent = new AgentPosition(); | ||||
|                 try | ||||
|                 { | ||||
|                     agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); | ||||
|                     return; | ||||
|                 } | ||||
|                 //agent.Dump(); | ||||
|                 // This is one of the meanings of PUT agent | ||||
|                 result = m_SimulationService.UpdateAgent(destination, agent); | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|             responsedata["int_response_code"] = HttpStatusCode.OK; | ||||
|             responsedata["str_response_string"] = result.ToString(); | ||||
|             //responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); ??? instead | ||||
|         } | ||||
| 
 | ||||
|         // subclasses can override this | ||||
|         protected virtual bool UpdateAgent(GridRegion destination, AgentData agent) | ||||
|         { | ||||
|             return m_SimulationService.UpdateAgent(destination, agent); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -43,30 +43,16 @@ namespace OpenSim.Server.Handlers.Simulation | |||
|         public SimulationServiceInConnector(IConfigSource config, IHttpServer server, IScene scene) : | ||||
|                 base(config, server, String.Empty) | ||||
|         { | ||||
|             //IConfig serverConfig = config.Configs["SimulationService"]; | ||||
|             //if (serverConfig == null) | ||||
|             //    throw new Exception("No section 'SimulationService' in config file"); | ||||
| 
 | ||||
|             //string simService = serverConfig.GetString("LocalServiceModule", | ||||
|             //        String.Empty); | ||||
| 
 | ||||
|             //if (simService == String.Empty) | ||||
|             //    throw new Exception("No SimulationService in config file"); | ||||
| 
 | ||||
|             //Object[] args = new Object[] { config }; | ||||
|             m_LocalSimulationService = scene.RequestModuleInterface<ISimulationService>(); | ||||
|             m_LocalSimulationService = m_LocalSimulationService.GetInnerService(); | ||||
|                     //ServerUtils.LoadPlugin<ISimulationService>(simService, args); | ||||
| 
 | ||||
|             //System.Console.WriteLine("XXXXXXXXXXXXXXXXXXX m_AssetSetvice == null? " + ((m_AssetService == null) ? "yes" : "no")); | ||||
|             //server.AddStreamHandler(new AgentGetHandler(m_SimulationService, m_AuthenticationService)); | ||||
|             //server.AddStreamHandler(new AgentPostHandler(m_SimulationService, m_AuthenticationService)); | ||||
|             //server.AddStreamHandler(new AgentPutHandler(m_SimulationService, m_AuthenticationService)); | ||||
|             //server.AddStreamHandler(new AgentDeleteHandler(m_SimulationService, m_AuthenticationService)); | ||||
|             // This one MUST be a stream handler because compressed fatpacks | ||||
|             // are pure binary and shoehorning that into a string with UTF-8 | ||||
|             // encoding breaks it | ||||
|             server.AddStreamHandler(new AgentPostHandler(m_LocalSimulationService)); | ||||
|             server.AddStreamHandler(new AgentPutHandler(m_LocalSimulationService)); | ||||
|             server.AddHTTPHandler("/agent/", new AgentHandler(m_LocalSimulationService).Handler); | ||||
|             server.AddHTTPHandler("/object/", new ObjectHandler(m_LocalSimulationService).Handler); | ||||
| 
 | ||||
|             //server.AddStreamHandler(new ObjectPostHandler(m_SimulationService, authentication)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -26,6 +26,8 @@ | |||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Reflection; | ||||
| using Nini.Config; | ||||
| using log4net; | ||||
|  | @ -60,6 +62,13 @@ namespace OpenSim.Services.AssetService | |||
|                         "delete asset", | ||||
|                         "delete asset <ID>", | ||||
|                         "Delete asset from database", HandleDeleteAsset); | ||||
|                  | ||||
|                 MainConsole.Instance.Commands.AddCommand("kfs", false, | ||||
|                         "dump asset", | ||||
|                         "dump asset <ID>", | ||||
|                         "Dump asset to a file",  | ||||
|                         "The filename is the same as the ID given.",  | ||||
|                         HandleDumpAsset); | ||||
| 
 | ||||
|                 if (m_AssetLoader != null) | ||||
|                 { | ||||
|  | @ -189,6 +198,43 @@ namespace OpenSim.Services.AssetService | |||
| 
 | ||||
|             return false; | ||||
|         } | ||||
|          | ||||
|         void HandleDumpAsset(string module, string[] args) | ||||
|         { | ||||
|             if (args.Length < 3) | ||||
|             { | ||||
|                 MainConsole.Instance.Output("Usage is dump asset <ID>"); | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             string rawAssetId = args[2]; | ||||
|             UUID assetId; | ||||
|              | ||||
|             if (!UUID.TryParse(rawAssetId, out assetId)) | ||||
|             { | ||||
|                 MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId); | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             AssetBase asset = m_Database.GetAsset(assetId); | ||||
|             if (asset == null) | ||||
|             {                 | ||||
|                 MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId); | ||||
|                 return;                 | ||||
|             } | ||||
|              | ||||
|             string fileName = rawAssetId; | ||||
|              | ||||
|             using (FileStream fs = new FileStream(fileName, FileMode.CreateNew)) | ||||
|             { | ||||
|                 using (BinaryWriter bw = new BinaryWriter(fs)) | ||||
|                 { | ||||
|                     bw.Write(asset.Data); | ||||
|                 } | ||||
|             }    | ||||
|              | ||||
|             MainConsole.Instance.OutputFormat("Asset dumped to file {0}", fileName); | ||||
|         } | ||||
| 
 | ||||
|         void HandleShowDigest(string module, string[] args) | ||||
|         { | ||||
|  | @ -208,11 +254,11 @@ namespace OpenSim.Services.AssetService | |||
| 
 | ||||
|             int i; | ||||
| 
 | ||||
|             MainConsole.Instance.Output(String.Format("Name: {0}", asset.Name)); | ||||
|             MainConsole.Instance.Output(String.Format("Description: {0}", asset.Description)); | ||||
|             MainConsole.Instance.Output(String.Format("Type: {0}", asset.Type)); | ||||
|             MainConsole.Instance.Output(String.Format("Content-type: {0}", asset.Metadata.ContentType)); | ||||
|             MainConsole.Instance.Output(String.Format("Flags: {0}", asset.Metadata.Flags.ToString())); | ||||
|             MainConsole.Instance.OutputFormat("Name: {0}", asset.Name); | ||||
|             MainConsole.Instance.OutputFormat("Description: {0}", asset.Description); | ||||
|             MainConsole.Instance.OutputFormat("Type: {0} (type number = {1})", (AssetType)asset.Type, asset.Type); | ||||
|             MainConsole.Instance.OutputFormat("Content-type: {0}", asset.Metadata.ContentType); | ||||
|             MainConsole.Instance.OutputFormat("Flags: {0}", asset.Metadata.Flags); | ||||
| 
 | ||||
|             for (i = 0 ; i < 5 ; i++) | ||||
|             { | ||||
|  |  | |||
|  | @ -102,12 +102,21 @@ namespace OpenSim.Services.Connectors.Simulation | |||
|                 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); | ||||
|                 args["teleport_flags"] = OSD.FromString(flags.ToString()); | ||||
| 
 | ||||
|                 OSDMap result = WebUtil.PostToService(uri, args, 20000); | ||||
|                 OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000); | ||||
|                 if (result["Success"].AsBoolean()) | ||||
|                     return true; | ||||
|                  | ||||
|                 result = WebUtil.PostToService(uri, args, 30000); | ||||
| 
 | ||||
|                 if (result["Success"].AsBoolean()) | ||||
|                 { | ||||
|                     m_log.WarnFormat( | ||||
|                     "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName); | ||||
|                     return true; | ||||
|                 } | ||||
|                  | ||||
|                 m_log.WarnFormat( | ||||
|                     "[REMOTE SIMULATION CONNECTOR]: Failed to create agent {0} {1} at remote simulator {1}",  | ||||
|                     "[REMOTE SIMULATION CONNECTOR]: Failed to create agent {0} {1} at remote simulator {2}",  | ||||
|                     aCircuit.firstname, aCircuit.lastname, destination.RegionName);                        | ||||
|                 reason = result["Message"] != null ? result["Message"].AsString() : "error"; | ||||
|                 return false; | ||||
|  | @ -207,7 +216,12 @@ namespace OpenSim.Services.Connectors.Simulation | |||
|                 args["destination_name"] = OSD.FromString(destination.RegionName); | ||||
|                 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); | ||||
| 
 | ||||
|                 OSDMap result = WebUtil.PutToService(uri, args, timeout); | ||||
|                 OSDMap result = WebUtil.PutToServiceCompressed(uri, args, timeout); | ||||
|                 if (result["Success"].AsBoolean()) | ||||
|                     return true; | ||||
| 
 | ||||
|                 result = WebUtil.PutToService(uri, args, timeout); | ||||
| 
 | ||||
|                 return result["Success"].AsBoolean(); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|  | @ -274,7 +288,7 @@ namespace OpenSim.Services.Connectors.Simulation | |||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000); | ||||
|                 OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000, false); | ||||
|                 bool success = result["success"].AsBoolean(); | ||||
|                 if (result.ContainsKey("_Result")) | ||||
|                 { | ||||
|  | @ -326,7 +340,7 @@ namespace OpenSim.Services.Connectors.Simulation | |||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000); | ||||
|                 WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|  | @ -346,7 +360,7 @@ namespace OpenSim.Services.Connectors.Simulation | |||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000); | ||||
|                 WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ | |||
|       <layout type="log4net.Layout.PatternLayout"> | ||||
|         <conversionPattern value="%date{HH:mm:ss} - %message" /> | ||||
|         <!-- console log with milliseconds.  Useful for debugging --> | ||||
|         <!-- <conversionPattern value="%date{HH:mm:ss.fff} - %message" /> --> | ||||
| <!--        <conversionPattern value="%date{HH:mm:ss.fff} - %message" /> --> | ||||
|       </layout> | ||||
|     </appender> | ||||
| 
 | ||||
|  |  | |||
|  | @ -736,6 +736,10 @@ | |||
|     ;; Enable media on a prim facilities | ||||
|     ; Enabled = true; | ||||
| 
 | ||||
| [PrimLimitsModule] | ||||
|     ;# {EnforcePrimLimits} {} {Enforce parcel prim limits} {true false} false | ||||
|     ;; Enable parcel prim limits.  Off by default to emulate pre-existing behavior. | ||||
|     ; EnforcePrimLimits = false | ||||
| 
 | ||||
| [Architecture] | ||||
|     ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini | ||||
|  |  | |||
|  | @ -291,6 +291,20 @@ | |||
|     http_listener_sslport = 9001 ; Use this port for SSL connections | ||||
|     http_listener_ssl_cert = "" ; Currently unused, but will be used for OSHttpServer | ||||
| 
 | ||||
|     ; HTTPS for "Out of band" management applications such as the remote  | ||||
|     ; admin module | ||||
|     ; | ||||
|     ; Create https_listener = "True" will create a listener on the port | ||||
|     ; specified. Provide the path to your server certificate along with it's | ||||
|     ; password | ||||
|     ; https_listener = False | ||||
|     ; Set our listener to this port | ||||
|     ; https_port = 0 | ||||
|     ; Path to X509 certificate | ||||
|     ; cert_path = "path/to/cert.p12" | ||||
|     ; Password for cert | ||||
|     ; cert_pass = "password" | ||||
| 
 | ||||
|     ; Hostname to use in llRequestURL/llRequestSecureURL | ||||
|     ; if not defined - default machine name is being used | ||||
|     ; (on Windows this mean NETBIOS name - useably only inside local network) | ||||
|  | @ -1352,6 +1366,10 @@ | |||
| [GridService] | ||||
|     ;; default standalone, overridable in StandaloneCommon.ini | ||||
|     StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" | ||||
| 	 | ||||
| [AutoBackupModule] | ||||
| 	;; default is module is disabled at the top level | ||||
| 	AutoBackupModuleEnabled = false | ||||
| 
 | ||||
| [Modules] | ||||
|     Include-modules = "addon-modules/*/config/*.ini" | ||||
|  |  | |||
|  | @ -29,6 +29,26 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 | |||
| [Network] | ||||
|     port = 8003 | ||||
| 
 | ||||
|     ; HTTPS for "Out of band" management applications such as the remote admin | ||||
|     ; module. May specify https_main = True to make the main http server | ||||
|     ; use https or "False" to make the main server HTTP | ||||
|     ; https_main = False | ||||
|     ; | ||||
|     ; Create https_listener = "True" will create a listener on the port | ||||
|     ; specified. Provide the path to your server certificate along with it's | ||||
|     ; password | ||||
|     ; https_listener = False | ||||
|     ; | ||||
|     ; Set our listener to this port | ||||
|     ; https_port = 0 | ||||
|     ; | ||||
|     ; Path to X509 certificate | ||||
|     ; cert_path = "path/to/cert.p12" | ||||
|     ; | ||||
|     ; Password for cert | ||||
|     ; cert_pass = "password" | ||||
| 
 | ||||
| 
 | ||||
| ; * The following are for the remote console | ||||
| ; * They have no effect for the local or basic console types | ||||
| ; * Leave commented to diable logins to the console | ||||
|  |  | |||
|  | @ -21,6 +21,27 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 | |||
| [Network] | ||||
|     port = 8003 | ||||
| 
 | ||||
| 
 | ||||
|     ; HTTPS for "Out of band" management applications such as the remote admin | ||||
|     ; module. May specify https_main = True to make the main http server | ||||
|     ; use https or "False" to make the main server HTTP | ||||
|     ; https_main = False | ||||
|     ; | ||||
|     ; Create https_listener = "True" will create a listener on the port | ||||
|     ; specified. Provide the path to your server certificate along with it's | ||||
|     ; password | ||||
|     ; https_listener = False | ||||
|     ; | ||||
|     ; Set our listener to this port | ||||
|     ; https_port = 0 | ||||
|     ; | ||||
|     ; Path to X509 certificate | ||||
|     ; cert_path = "path/to/cert.p12" | ||||
|     ; | ||||
|     ; Password for cert | ||||
|     ; cert_pass = "password" | ||||
| 
 | ||||
| 
 | ||||
| ; * The following are for the remote console | ||||
| ; * They have no effect for the local or basic console types | ||||
| ; * Leave commented to diable logins to the console | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Huaiyu (Kitty) Liu
						Huaiyu (Kitty) Liu