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
|
public class Caps
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
// private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private string m_httpListenerHostName;
|
private string m_httpListenerHostName;
|
||||||
private uint m_httpListenPort;
|
private uint m_httpListenPort;
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
string textureStr = query.GetOne("texture_id");
|
string textureStr = query.GetOne("texture_id");
|
||||||
string format = query.GetOne("format");
|
string format = query.GetOne("format");
|
||||||
|
|
||||||
m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
||||||
|
|
||||||
if (m_assetService == null)
|
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>,
|
public class MySQLAvatarData : MySQLGenericTableHandler<AvatarBaseData>,
|
||||||
IAvatarData
|
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) :
|
public MySQLAvatarData(string connectionString, string realm) :
|
||||||
base(connectionString, realm, "Avatar")
|
base(connectionString, realm, "Avatar")
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace OpenSim.Data.MySQL
|
||||||
private string m_connectionString;
|
private string m_connectionString;
|
||||||
private long m_waitTimeout;
|
private long m_waitTimeout;
|
||||||
private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond;
|
private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond;
|
||||||
private long m_lastConnectionUse;
|
// private long m_lastConnectionUse;
|
||||||
|
|
||||||
private FieldInfo[] m_Fields;
|
private FieldInfo[] m_Fields;
|
||||||
private Dictionary<string, FieldInfo> m_FieldMap =
|
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(
|
m_log.DebugFormat(
|
||||||
"[REGION DB]: Connection wait timeout {0} seconds",
|
"[REGION DB]: Connection wait timeout {0} seconds",
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new()
|
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 =
|
protected Dictionary<string, FieldInfo> m_Fields =
|
||||||
new Dictionary<string, FieldInfo>();
|
new Dictionary<string, FieldInfo>();
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace OpenSim.Data.MySQL
|
||||||
public class MySQLPresenceData : MySQLGenericTableHandler<PresenceData>,
|
public class MySQLPresenceData : MySQLGenericTableHandler<PresenceData>,
|
||||||
IPresenceData
|
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) :
|
public MySQLPresenceData(string connectionString, string realm) :
|
||||||
base(connectionString, realm, "Presence")
|
base(connectionString, realm, "Presence")
|
||||||
|
|
|
@ -189,7 +189,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ using System.Reflection;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using log4net;
|
|
||||||
#if CSharpSqlite
|
#if CSharpSqlite
|
||||||
using Community.CsharpSqlite.Sqlite;
|
using Community.CsharpSqlite.Sqlite;
|
||||||
#else
|
#else
|
||||||
|
@ -49,7 +49,6 @@ namespace OpenSim.Data.SQLite
|
||||||
private string m_Realm;
|
private string m_Realm;
|
||||||
private List<string> m_ColumnNames;
|
private List<string> m_ColumnNames;
|
||||||
private int m_LastExpire;
|
private int m_LastExpire;
|
||||||
private string m_connectionString;
|
|
||||||
|
|
||||||
protected static SqliteConnection m_Connection;
|
protected static SqliteConnection m_Connection;
|
||||||
private static bool m_initialized = false;
|
private static bool m_initialized = false;
|
||||||
|
@ -58,7 +57,6 @@ namespace OpenSim.Data.SQLite
|
||||||
: base(connectionString)
|
: base(connectionString)
|
||||||
{
|
{
|
||||||
m_Realm = realm;
|
m_Realm = realm;
|
||||||
m_connectionString = connectionString;
|
|
||||||
|
|
||||||
if (!m_initialized)
|
if (!m_initialized)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite
|
||||||
public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>,
|
public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>,
|
||||||
IAvatarData
|
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) :
|
public SQLiteAvatarData(string connectionString, string realm) :
|
||||||
base(connectionString, realm, "Avatar")
|
base(connectionString, realm, "Avatar")
|
||||||
|
|
|
@ -460,7 +460,7 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
info["state"] = OSD.FromString(AttachmentObjectStates[i++]);
|
info["state"] = OSD.FromString(AttachmentObjectStates[i++]);
|
||||||
}
|
}
|
||||||
catch (IndexOutOfRangeException e)
|
catch (IndexOutOfRangeException)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[CHILD AGENT DATA]: scripts list is shorter than object list.");
|
m_log.WarnFormat("[CHILD AGENT DATA]: scripts list is shorter than object list.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,113 +29,13 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public class ConfigSettings
|
public class ConfigSettings
|
||||||
{
|
{
|
||||||
private string m_physicsEngine;
|
public string PhysicsEngine { get; set; }
|
||||||
|
public string MeshEngineName { get; set; }
|
||||||
public string PhysicsEngine
|
public bool See_into_region_from_neighbor { get; set; }
|
||||||
{
|
public string StorageDll { get; set; }
|
||||||
get { return m_physicsEngine; }
|
public string ClientstackDll { get; set; }
|
||||||
set { m_physicsEngine = value; }
|
public bool PhysicalPrim { get; set; }
|
||||||
}
|
public string LibrariesXMLFile { get; set; }
|
||||||
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 const uint DefaultAssetServerHttpPort = 8003;
|
public const uint DefaultAssetServerHttpPort = 8003;
|
||||||
public const uint DefaultRegionHttpPort = 9000;
|
public const uint DefaultRegionHttpPort = 9000;
|
||||||
|
|
|
@ -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 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(
|
public delegate void TeleportLocationRequest(
|
||||||
IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags);
|
IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags);
|
||||||
|
|
|
@ -52,6 +52,11 @@ namespace OpenSim.Framework
|
||||||
return GetHttpServer(port,null);
|
return GetHttpServer(port,null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AddHttpServer(BaseHttpServer server)
|
||||||
|
{
|
||||||
|
m_Servers.Add(server.Port, server);
|
||||||
|
}
|
||||||
|
|
||||||
public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
|
public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
|
||||||
{
|
{
|
||||||
if (port == 0)
|
if (port == 0)
|
||||||
|
|
|
@ -49,6 +49,12 @@ namespace OpenSim.Framework
|
||||||
public string HttpSSLCN = "";
|
public string HttpSSLCN = "";
|
||||||
public uint httpSSLPort = 9001;
|
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 string MessagingURL = String.Empty;
|
||||||
|
|
||||||
public NetworkServersInfo()
|
public NetworkServersInfo()
|
||||||
|
@ -86,6 +92,15 @@ namespace OpenSim.Framework
|
||||||
secureInventoryServer = config.Configs["Network"].GetBoolean("secure_inventory_server", true);
|
secureInventoryServer = config.Configs["Network"].GetBoolean("secure_inventory_server", true);
|
||||||
|
|
||||||
MessagingURL = config.Configs["Network"].GetString("messaging_server_url", string.Empty);
|
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
|
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);
|
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
|
public class RegionInfo
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
|
@ -32,6 +32,7 @@ using System.Collections.Specialized;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -72,6 +73,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
protected uint m_port;
|
protected uint m_port;
|
||||||
protected uint m_sslport;
|
protected uint m_sslport;
|
||||||
protected bool m_ssl;
|
protected bool m_ssl;
|
||||||
|
private X509Certificate2 m_cert;
|
||||||
protected bool m_firstcaps = true;
|
protected bool m_firstcaps = true;
|
||||||
protected string m_SSLCommonName = "";
|
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>
|
/// <summary>
|
||||||
/// Add a stream handler to the http server. If the handler already exists, then nothing happens.
|
/// Add a stream handler to the http server. If the handler already exists, then nothing happens.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1683,6 +1693,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//m_httpListener = new HttpListener();
|
//m_httpListener = new HttpListener();
|
||||||
|
|
||||||
NotSocketErrors = 0;
|
NotSocketErrors = 0;
|
||||||
if (!m_ssl)
|
if (!m_ssl)
|
||||||
{
|
{
|
||||||
|
@ -1702,6 +1713,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
//m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/");
|
//m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/");
|
||||||
//m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
|
//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;
|
m_httpListener2.RequestReceived += OnRequest;
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Security;
|
using System.Net.Security;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -140,22 +141,32 @@ namespace OpenSim.Framework
|
||||||
/// PUT JSON-encoded data to a web service that returns LLSD or
|
/// PUT JSON-encoded data to a web service that returns LLSD or
|
||||||
/// JSON data
|
/// JSON data
|
||||||
/// </summary>
|
/// </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)
|
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)
|
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)
|
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++;
|
int reqnum = m_requestNumber++;
|
||||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
@ -180,11 +191,32 @@ namespace OpenSim.Framework
|
||||||
string strBuffer = OSDParser.SerializeJsonString(data);
|
string strBuffer = OSDParser.SerializeJsonString(data);
|
||||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
||||||
|
|
||||||
|
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.ContentType = "application/json";
|
||||||
request.ContentLength = buffer.Length; //Count bytes to send
|
request.ContentLength = buffer.Length; //Count bytes to send
|
||||||
using (Stream requestStream = request.GetRequestStream())
|
using (Stream requestStream = request.GetRequestStream())
|
||||||
requestStream.Write(buffer, 0, buffer.Length); //Send it
|
requestStream.Write(buffer, 0, buffer.Length); //Send it
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// capture how much time was spent writing, this may seem silly
|
// capture how much time was spent writing, this may seem silly
|
||||||
// but with the number concurrent requests, this often blocks
|
// but with the number concurrent requests, this often blocks
|
||||||
|
@ -809,7 +841,7 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
if ((verb == "POST") || (verb == "PUT"))
|
if ((verb == "POST") || (verb == "PUT"))
|
||||||
{
|
{
|
||||||
request.ContentType = "text/www-form-urlencoded";
|
request.ContentType = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
int length = 0;
|
int length = 0;
|
||||||
using (StreamWriter writer = new StreamWriter(buffer))
|
using (StreamWriter writer = new StreamWriter(buffer))
|
||||||
|
@ -886,6 +918,10 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public class SynchronousRestObjectRequester
|
public class SynchronousRestObjectRequester
|
||||||
{
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(
|
||||||
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform a synchronous REST request.
|
/// Perform a synchronous REST request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -929,8 +965,9 @@ namespace OpenSim.Framework
|
||||||
requestStream = request.GetRequestStream();
|
requestStream = request.GetRequestStream();
|
||||||
requestStream.Write(buffer.ToArray(), 0, length);
|
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;
|
return deserial;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@ -944,19 +981,28 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
using (WebResponse resp = request.GetResponse())
|
using (WebResponse resp = request.GetResponse())
|
||||||
{
|
{
|
||||||
if (resp.ContentLength > 0)
|
if (resp.ContentLength != 0)
|
||||||
{
|
{
|
||||||
Stream respStream = resp.GetResponseStream();
|
Stream respStream = resp.GetResponseStream();
|
||||||
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
||||||
deserial = (TResponse)deserializer.Deserialize(respStream);
|
deserial = (TResponse)deserializer.Deserialize(respStream);
|
||||||
respStream.Close();
|
respStream.Close();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (System.InvalidOperationException)
|
catch (System.InvalidOperationException)
|
||||||
{
|
{
|
||||||
// This is what happens when there is invalid XML
|
// 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;
|
return deserial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,20 +372,6 @@ namespace OpenSim
|
||||||
= startupConfig.GetString("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
|
= 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);
|
m_networkServersInfo.loadFromConfiguration(m_config.Source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1436,7 +1436,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public void SendMapBlock(List<MapBlockData> mapBlocks, uint flag)
|
public void SendMapBlock(List<MapBlockData> mapBlocks, uint flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
MapBlockData[] mapBlocks2 = mapBlocks.ToArray();
|
MapBlockData[] mapBlocks2 = mapBlocks.ToArray();
|
||||||
|
|
||||||
int maxsend = 10;
|
int maxsend = 10;
|
||||||
|
@ -1686,15 +1685,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]);
|
currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID);
|
||||||
OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
|
OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
|
||||||
currentPacket = null;
|
currentPacket = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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);
|
OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder)
|
private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder)
|
||||||
{
|
{
|
||||||
|
@ -6087,7 +6091,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
AvatarWearingArgs wearingArgs = new AvatarWearingArgs();
|
AvatarWearingArgs wearingArgs = new AvatarWearingArgs();
|
||||||
for (int i = 0; i < nowWearing.WearableData.Length; i++)
|
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 =
|
AvatarWearingArgs.Wearable wearable =
|
||||||
new AvatarWearingArgs.Wearable(nowWearing.WearableData[i].ItemID,
|
new AvatarWearingArgs.Wearable(nowWearing.WearableData[i].ItemID,
|
||||||
nowWearing.WearableData[i].WearableType);
|
nowWearing.WearableData[i].WearableType);
|
||||||
|
@ -8369,13 +8373,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
string mapName = Util.UTF8.GetString(map.NameData.Name, 0,
|
string mapName = Util.UTF8.GetString(map.NameData.Name, 0,
|
||||||
map.NameData.Name.Length - 1);
|
map.NameData.Name.Length - 1);
|
||||||
RequestMapName handlerMapNameRequest = OnMapNameRequest;
|
RequestMapName handlerMapNameRequest = OnMapNameRequest;
|
||||||
if (handlerMapNameRequest != null)
|
if (handlerMapNameRequest != null)
|
||||||
{
|
{
|
||||||
handlerMapNameRequest(this, mapName);
|
handlerMapNameRequest(this, mapName, map.AgentData.Flags);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,22 @@ namespace OpenSim.Region.ClientStack
|
||||||
|
|
||||||
MainServer.Instance = m_httpServer;
|
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();
|
base.StartupSpecific();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,12 +162,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
// one and we're done otherwise, ask for a rebake
|
// one and we're done otherwise, ask for a rebake
|
||||||
if (checkonly) return false;
|
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);
|
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
|
// If we only found default textures, then the appearance is not cached
|
||||||
return (defonly ? false : true);
|
return (defonly ? false : true);
|
||||||
|
|
|
@ -178,6 +178,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||||
List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
|
List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
|
||||||
"POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
|
"POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
|
||||||
|
|
||||||
|
if (msglist == null)
|
||||||
|
m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list.");
|
||||||
|
|
||||||
foreach (GridInstantMessage im in msglist)
|
foreach (GridInstantMessage im in msglist)
|
||||||
{
|
{
|
||||||
// client.SendInstantMessage(im);
|
// client.SendInstantMessage(im);
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
|
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
|
||||||
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
|
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
|
||||||
"show capabilities",
|
"show caps",
|
||||||
"Shows all registered capabilities", CapabilitiesCommand);
|
"Shows all registered capabilities", CapabilitiesCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -395,6 +395,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest");
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID);
|
"[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))
|
if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
|
||||||
{
|
{
|
||||||
// region doesn't take it
|
// region doesn't take it
|
||||||
|
ReInstantiateScripts(agent);
|
||||||
ResetFromTransit(agent.UUID);
|
ResetFromTransit(agent.UUID);
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
|
@ -1763,15 +1766,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
protected void ReInstantiateScripts(ScenePresence sp)
|
protected void ReInstantiateScripts(ScenePresence sp)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
if (sp.InTransitScriptStates.Count > 0)
|
||||||
|
{
|
||||||
sp.Attachments.ForEach(delegate(SceneObjectGroup sog)
|
sp.Attachments.ForEach(delegate(SceneObjectGroup sog)
|
||||||
|
{
|
||||||
|
if (i < sp.InTransitScriptStates.Count)
|
||||||
{
|
{
|
||||||
sog.SetState(sp.InTransitScriptStates[i++], sp.Scene);
|
sog.SetState(sp.InTransitScriptStates[i++], sp.Scene);
|
||||||
sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0);
|
sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0);
|
||||||
sog.ResumeScripts();
|
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
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid
|
||||||
{
|
{
|
||||||
List<MapBlockData> mapBlocks = new List<MapBlockData>();
|
List<MapBlockData> mapBlocks = new List<MapBlockData>();
|
||||||
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
||||||
(minX - 4) * (int)Constants.RegionSize, (maxX + 4) * (int)Constants.RegionSize,
|
minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize,
|
||||||
(minY - 4) * (int)Constants.RegionSize, (maxY + 4) * (int)Constants.RegionSize);
|
minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize);
|
||||||
|
|
||||||
foreach (GridRegion r in regions)
|
foreach (GridRegion r in regions)
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
|
||||||
FillInMap(mapBlocks, minX, minY, maxX, maxY);
|
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.X = (ushort)x;
|
||||||
mblock.Y = (ushort)y;
|
mblock.Y = (ushort)y;
|
||||||
mblock.Name = "";
|
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;
|
mblock.MapImageId = UUID.Zero;
|
||||||
mapBlocks.Add(mblock);
|
mapBlocks.Add(mblock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
||||||
return true;
|
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
|
#region IHttpRequestModule Members
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
private int m_TotalUrls = 100;
|
private int m_TotalUrls = 100;
|
||||||
|
|
||||||
|
private uint https_port = 0;
|
||||||
private IHttpServer m_HttpServer = null;
|
private IHttpServer m_HttpServer = null;
|
||||||
|
private IHttpServer m_HttpsServer = null;
|
||||||
|
|
||||||
private string m_ExternalHostNameForLSL = "";
|
private string m_ExternalHostNameForLSL = "";
|
||||||
|
|
||||||
|
@ -100,6 +102,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
public void Initialise(IConfigSource config)
|
public void Initialise(IConfigSource config)
|
||||||
{
|
{
|
||||||
m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName);
|
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()
|
public void PostInitialise()
|
||||||
|
@ -113,6 +120,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
// There can only be one
|
// There can only be one
|
||||||
//
|
//
|
||||||
m_HttpServer = MainServer.Instance;
|
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);
|
scene.RegisterModuleInterface<IUrlModule>(this);
|
||||||
|
@ -171,7 +184,40 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
{
|
{
|
||||||
UUID urlcode = UUID.Random();
|
UUID urlcode = UUID.Random();
|
||||||
|
|
||||||
|
if (m_HttpsServer == null)
|
||||||
|
{
|
||||||
engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
|
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;
|
return urlcode;
|
||||||
}
|
}
|
||||||
|
@ -391,6 +437,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
lock (request)
|
lock (request)
|
||||||
{
|
{
|
||||||
string uri = request["uri"].ToString();
|
string uri = request["uri"].ToString();
|
||||||
|
bool is_ssl = uri.Contains("lslhttps");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -409,7 +456,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
pathInfo = uri.Substring(pos3);
|
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
|
//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
|
//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)
|
public void AddRegion(Scene scene)
|
||||||
{
|
{
|
||||||
m_Scene = scene;
|
m_Scene = scene;
|
||||||
|
|
||||||
scene.RegisterModuleInterface<IRestartModule>(this);
|
scene.RegisterModuleInterface<IRestartModule>(this);
|
||||||
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||||
false, "region restart bluebox",
|
false, "region restart bluebox",
|
||||||
"region restart bluebox <message> <time> ...",
|
"region restart bluebox <message> <delta seconds>+",
|
||||||
"Restart the region", HandleRegionRestart);
|
"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",
|
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||||
false, "region restart notice",
|
false, "region restart notice",
|
||||||
"region restart notice <message> <time> ...",
|
"region restart notice <message> <delta seconds>+",
|
||||||
"Restart the region", HandleRegionRestart);
|
"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",
|
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||||
false, "region restart abort",
|
false, "region restart abort",
|
||||||
"region restart abort [<message>]",
|
"region restart abort [<message>]",
|
||||||
"Restart the region", HandleRegionRestart);
|
"Abort a region restart", HandleRegionRestart);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
client.OnMapNameRequest += OnMapNameRequest;
|
client.OnMapNameRequest += OnMapNameRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapNameRequest(IClientAPI remoteClient, string mapName)
|
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
|
||||||
{
|
{
|
||||||
if (mapName.Length < 3)
|
if (mapName.Length < 3)
|
||||||
{
|
{
|
||||||
|
@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
else if (regionInfos.Count == 0 && mapName.StartsWith("http://"))
|
else if (regionInfos.Count == 0 && mapName.StartsWith("http://"))
|
||||||
remoteClient.SendAlertMessage("Hyperlink could not be established.");
|
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>();
|
List<MapBlockData> blocks = new List<MapBlockData>();
|
||||||
|
|
||||||
MapBlockData data;
|
MapBlockData data;
|
||||||
|
@ -117,7 +117,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
data = new MapBlockData();
|
data = new MapBlockData();
|
||||||
data.Agents = 0;
|
data.Agents = 0;
|
||||||
data.Access = info.Access;
|
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.Name = info.RegionName;
|
||||||
data.RegionFlags = 0; // TODO not used?
|
data.RegionFlags = 0; // TODO not used?
|
||||||
data.WaterHeight = 0; // not used
|
data.WaterHeight = 0; // not used
|
||||||
|
@ -139,9 +142,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
data.Y = 0;
|
data.Y = 0;
|
||||||
blocks.Add(data);
|
blocks.Add(data);
|
||||||
|
|
||||||
// not sure what the flags do here, but seems to be necessary
|
// flags are agent flags sent from the viewer.
|
||||||
// to set to "2" for viewer 2
|
// they have different values depending on different viewers, apparently
|
||||||
remoteClient.SendMapBlock(blocks, 2);
|
remoteClient.SendMapBlock(blocks, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// private Scene GetClientScene(IClientAPI client)
|
// private Scene GetClientScene(IClientAPI client)
|
||||||
|
|
|
@ -205,8 +205,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
{
|
{
|
||||||
//try
|
//try
|
||||||
//{
|
//{
|
||||||
//m_log.DebugFormat("[MAPLAYER]: request: {0}, path: {1}, param: {2}, agent:{3}",
|
//m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
|
||||||
//request, path, param,agentID.ToString());
|
// path, param, agentID.ToString());
|
||||||
|
|
||||||
// this is here because CAPS map requests work even beyond the 10,000 limit.
|
// this is here because CAPS map requests work even beyond the 10,000 limit.
|
||||||
ScenePresence avatarPresence = null;
|
ScenePresence avatarPresence = null;
|
||||||
|
@ -784,7 +784,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
/// <param name="maxY"></param>
|
/// <param name="maxY"></param>
|
||||||
public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
|
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>();
|
List<MapBlockData> response = new List<MapBlockData>();
|
||||||
|
|
||||||
|
@ -819,7 +820,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
MapBlockData block = new MapBlockData();
|
MapBlockData block = new MapBlockData();
|
||||||
block.X = (ushort)minX;
|
block.X = (ushort)minX;
|
||||||
block.Y = (ushort)minY;
|
block.Y = (ushort)minY;
|
||||||
block.Access = 254; // == not there
|
block.Access = 254; // means 'simulator is offline'
|
||||||
response.Add(block);
|
response.Add(block);
|
||||||
}
|
}
|
||||||
remoteClient.SendMapBlock(response, 0);
|
remoteClient.SendMapBlock(response, 0);
|
||||||
|
@ -845,7 +846,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
MapBlockFromGridRegion(block, r);
|
MapBlockFromGridRegion(block, r);
|
||||||
mapBlocks.Add(block);
|
mapBlocks.Add(block);
|
||||||
}
|
}
|
||||||
remoteClient.SendMapBlock(mapBlocks, flag);
|
remoteClient.SendMapBlock(mapBlocks, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r)
|
protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r)
|
||||||
|
|
|
@ -876,7 +876,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
newName = item.Name;
|
newName = item.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remoteClient.AgentId == oldAgentID)
|
if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner))
|
||||||
{
|
{
|
||||||
CreateNewInventoryItem(
|
CreateNewInventoryItem(
|
||||||
remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
|
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,
|
private void HandleLinkInventoryItem(IClientAPI remoteClient, UUID transActionID, UUID folderID,
|
||||||
uint callbackID, string description, string name,
|
uint callbackID, string description, string name,
|
||||||
sbyte invType, sbyte type, UUID olditemID)
|
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))
|
if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
|
||||||
return;
|
return;
|
||||||
|
@ -1079,7 +1097,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScenePresence presence;
|
ScenePresence presence;
|
||||||
if (TryGetScenePresence(remoteClient.AgentId, out 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();
|
AssetBase asset = new AssetBase();
|
||||||
asset.FullID = olditemID;
|
asset.FullID = olditemID;
|
||||||
|
@ -1518,8 +1549,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
|
// contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
|
||||||
|
|
||||||
if (containingFolder != null && containingFolder != null)
|
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);
|
client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, containingFolder.Version, fetchFolders, fetchItems);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update an item in a prim (task) inventory.
|
/// Update an item in a prim (task) inventory.
|
||||||
|
|
|
@ -500,6 +500,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID,
|
public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID,
|
||||||
bool fetchFolders, bool fetchItems, int sortOrder)
|
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)
|
if (folderID == UUID.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -1044,6 +1044,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
"reload estate",
|
"reload estate",
|
||||||
"Reload the estate data", HandleReloadEstate);
|
"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
|
//Bind Storage Manager functions to some land manager functions for this scene
|
||||||
EventManager.OnLandObjectAdded +=
|
EventManager.OnLandObjectAdded +=
|
||||||
new EventManager.LandObjectAdded(simDataService.StoreLandObject);
|
new EventManager.LandObjectAdded(simDataService.StoreLandObject);
|
||||||
|
@ -1236,6 +1249,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_eventManager = new EventManager(this);
|
m_eventManager = new EventManager(this);
|
||||||
//end of DSG SYNC
|
//end of DSG SYNC
|
||||||
|
|
||||||
|
m_permissions = new ScenePermissions(this);
|
||||||
|
|
||||||
m_lastUpdate = Util.EnvironmentTickCount();
|
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)
|
private void HandleReloadEstate(string module, string[] cmd)
|
||||||
{
|
{
|
||||||
if (MainConsole.Instance.ConsoleScene == null ||
|
if (MainConsole.Instance.ConsoleScene == null ||
|
||||||
|
|
|
@ -2518,8 +2518,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
float speed = Velocity.Length();
|
float speed = Velocity.Length();
|
||||||
float velocidyDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity);
|
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
|
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?
|
|| velocidyDiff > 0.01f) // did velocity change from last update?
|
||||||
{
|
{
|
||||||
m_perfMonMS = currentTick;
|
m_perfMonMS = currentTick;
|
||||||
|
@ -3261,7 +3265,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
cAgent.AttachmentObjects = new List<ISceneObject>();
|
cAgent.AttachmentObjects = new List<ISceneObject>();
|
||||||
cAgent.AttachmentObjectStates = new List<string>();
|
cAgent.AttachmentObjectStates = new List<string>();
|
||||||
IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
||||||
m_InTransitScriptStates.Clear();
|
m_InTransitScriptStates.Clear();
|
||||||
foreach (SceneObjectGroup sog in m_attachments)
|
foreach (SceneObjectGroup sog in m_attachments)
|
||||||
{
|
{
|
||||||
|
|
|
@ -107,11 +107,10 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
|
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
this, "emergency-monitoring",
|
this, "emergency-monitoring",
|
||||||
"Go on/off emergency monitoring mode",
|
"emergency-monitoring",
|
||||||
"Go on/off emergency monitoring mode",
|
"Go on/off emergency monitoring mode",
|
||||||
"Go on/off emergency monitoring mode",
|
"Go on/off emergency monitoring mode",
|
||||||
EmergencyMonitoring);
|
EmergencyMonitoring);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -190,7 +189,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
int maxNameLength = 18;
|
int maxNameLength = 18;
|
||||||
int maxRegionNameLength = 14;
|
int maxRegionNameLength = 14;
|
||||||
int maxTypeLength = 4;
|
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("User", maxNameLength, columnPadding));
|
||||||
report.Append(GetColumnEntry("Region", maxRegionNameLength, 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="Concierge" type="OpenSim.Region.OptionalModules.Avatar.Concierge.ConciergeModule" />
|
||||||
<RegionModule id="VivoxVoice" type="OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice.VivoxVoiceModule" />
|
<RegionModule id="VivoxVoice" type="OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice.VivoxVoiceModule" />
|
||||||
<RegionModule id="WorldViewModule" type="OpenSim.Region.OptionalModules.World.WorldView.WorldViewModule" />
|
<RegionModule id="WorldViewModule" type="OpenSim.Region.OptionalModules.World.WorldView.WorldViewModule" />
|
||||||
|
<RegionModule id="AutoBackupModule" type="OpenSim.Region.OptionalModules.World.AutoBackup.AutoBackupModule" />
|
||||||
</Extension>
|
</Extension>
|
||||||
</Addin>
|
</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)
|
if (port == 0)
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("Port number not specified or 0, server can't start");
|
|
||||||
Thread.CurrentThread.Abort();
|
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_consolePort = (uint)networkConfig.GetInt("ConsolePort", 0);
|
||||||
m_Port = port;
|
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;
|
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()
|
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_Log.InfoFormat("[SERVER]: Starting HTTP server on port {0}", m_HttpServer.Port);
|
||||||
m_HttpServer.Start();
|
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 (MainConsole.Instance is RemoteConsole)
|
||||||
{
|
{
|
||||||
if (m_consolePort == 0)
|
if (m_consolePort == 0)
|
||||||
|
|
|
@ -49,13 +49,13 @@ using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Server.Handlers.Hypergrid
|
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 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private IGatekeeperService m_GatekeeperService;
|
private IGatekeeperService m_GatekeeperService;
|
||||||
|
|
||||||
public GatekeeperAgentHandler(IGatekeeperService gatekeeper, bool proxy)
|
public GatekeeperAgentHandler(IGatekeeperService gatekeeper, bool proxy) : base("/foreignagent")
|
||||||
{
|
{
|
||||||
m_GatekeeperService = gatekeeper;
|
m_GatekeeperService = gatekeeper;
|
||||||
m_Proxy = proxy;
|
m_Proxy = proxy;
|
||||||
|
@ -65,7 +65,5 @@ namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
{
|
{
|
||||||
return m_GatekeeperService.LoginAgent(aCircuit, destination, out reason);
|
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("link_region", hghandlers.LinkRegionRequest, false);
|
||||||
server.AddXmlRPCHandler("get_region", hghandlers.GetRegion, 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)
|
public GatekeeperServiceInConnector(IConfigSource config, IHttpServer server)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -53,8 +54,6 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
|
|
||||||
private ISimulationService m_SimulationService;
|
private ISimulationService m_SimulationService;
|
||||||
|
|
||||||
protected bool m_Proxy = false;
|
|
||||||
|
|
||||||
public AgentHandler() { }
|
public AgentHandler() { }
|
||||||
|
|
||||||
public AgentHandler(ISimulationService sim)
|
public AgentHandler(ISimulationService sim)
|
||||||
|
@ -91,17 +90,7 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
|
|
||||||
// Next, let's parse the verb
|
// Next, let's parse the verb
|
||||||
string method = (string)request["http-method"];
|
string method = (string)request["http-method"];
|
||||||
if (method.Equals("PUT"))
|
if (method.Equals("GET"))
|
||||||
{
|
|
||||||
DoAgentPut(request, responsedata);
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
else if (method.Equals("POST"))
|
|
||||||
{
|
|
||||||
DoAgentPost(request, responsedata, agentID);
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
else if (method.Equals("GET"))
|
|
||||||
{
|
{
|
||||||
DoAgentGet(request, responsedata, agentID, regionID);
|
DoAgentGet(request, responsedata, agentID, regionID);
|
||||||
return responsedata;
|
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)
|
protected virtual void DoQueryAccess(Hashtable request, Hashtable responsedata, UUID id, UUID regionID)
|
||||||
{
|
{
|
||||||
if (m_SimulationService == null)
|
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) :
|
public SimulationServiceInConnector(IConfigSource config, IHttpServer server, IScene scene) :
|
||||||
base(config, server, String.Empty)
|
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 = scene.RequestModuleInterface<ISimulationService>();
|
||||||
m_LocalSimulationService = m_LocalSimulationService.GetInnerService();
|
m_LocalSimulationService = m_LocalSimulationService.GetInnerService();
|
||||||
//ServerUtils.LoadPlugin<ISimulationService>(simService, args);
|
|
||||||
|
|
||||||
//System.Console.WriteLine("XXXXXXXXXXXXXXXXXXX m_AssetSetvice == null? " + ((m_AssetService == null) ? "yes" : "no"));
|
// This one MUST be a stream handler because compressed fatpacks
|
||||||
//server.AddStreamHandler(new AgentGetHandler(m_SimulationService, m_AuthenticationService));
|
// are pure binary and shoehorning that into a string with UTF-8
|
||||||
//server.AddStreamHandler(new AgentPostHandler(m_SimulationService, m_AuthenticationService));
|
// encoding breaks it
|
||||||
//server.AddStreamHandler(new AgentPutHandler(m_SimulationService, m_AuthenticationService));
|
server.AddStreamHandler(new AgentPostHandler(m_LocalSimulationService));
|
||||||
//server.AddStreamHandler(new AgentDeleteHandler(m_SimulationService, m_AuthenticationService));
|
server.AddStreamHandler(new AgentPutHandler(m_LocalSimulationService));
|
||||||
server.AddHTTPHandler("/agent/", new AgentHandler(m_LocalSimulationService).Handler);
|
server.AddHTTPHandler("/agent/", new AgentHandler(m_LocalSimulationService).Handler);
|
||||||
server.AddHTTPHandler("/object/", new ObjectHandler(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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -61,6 +63,13 @@ namespace OpenSim.Services.AssetService
|
||||||
"delete asset <ID>",
|
"delete asset <ID>",
|
||||||
"Delete asset from database", HandleDeleteAsset);
|
"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)
|
if (m_AssetLoader != null)
|
||||||
{
|
{
|
||||||
IConfig assetConfig = config.Configs["AssetService"];
|
IConfig assetConfig = config.Configs["AssetService"];
|
||||||
|
@ -190,6 +199,43 @@ namespace OpenSim.Services.AssetService
|
||||||
return false;
|
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)
|
void HandleShowDigest(string module, string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length < 3)
|
if (args.Length < 3)
|
||||||
|
@ -208,11 +254,11 @@ namespace OpenSim.Services.AssetService
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
MainConsole.Instance.Output(String.Format("Name: {0}", asset.Name));
|
MainConsole.Instance.OutputFormat("Name: {0}", asset.Name);
|
||||||
MainConsole.Instance.Output(String.Format("Description: {0}", asset.Description));
|
MainConsole.Instance.OutputFormat("Description: {0}", asset.Description);
|
||||||
MainConsole.Instance.Output(String.Format("Type: {0}", asset.Type));
|
MainConsole.Instance.OutputFormat("Type: {0} (type number = {1})", (AssetType)asset.Type, asset.Type);
|
||||||
MainConsole.Instance.Output(String.Format("Content-type: {0}", asset.Metadata.ContentType));
|
MainConsole.Instance.OutputFormat("Content-type: {0}", asset.Metadata.ContentType);
|
||||||
MainConsole.Instance.Output(String.Format("Flags: {0}", asset.Metadata.Flags.ToString()));
|
MainConsole.Instance.OutputFormat("Flags: {0}", asset.Metadata.Flags);
|
||||||
|
|
||||||
for (i = 0 ; i < 5 ; i++)
|
for (i = 0 ; i < 5 ; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,12 +102,21 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
|
args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
|
||||||
args["teleport_flags"] = OSD.FromString(flags.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())
|
if (result["Success"].AsBoolean())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
result = WebUtil.PostToService(uri, args, 30000);
|
||||||
|
|
||||||
|
if (result["Success"].AsBoolean())
|
||||||
|
{
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[REMOTE SIMULATION CONNECTOR]: Failed to create agent {0} {1} at remote simulator {1}",
|
"[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 {2}",
|
||||||
aCircuit.firstname, aCircuit.lastname, destination.RegionName);
|
aCircuit.firstname, aCircuit.lastname, destination.RegionName);
|
||||||
reason = result["Message"] != null ? result["Message"].AsString() : "error";
|
reason = result["Message"] != null ? result["Message"].AsString() : "error";
|
||||||
return false;
|
return false;
|
||||||
|
@ -207,7 +216,12 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
args["destination_name"] = OSD.FromString(destination.RegionName);
|
args["destination_name"] = OSD.FromString(destination.RegionName);
|
||||||
args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
|
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();
|
return result["Success"].AsBoolean();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -274,7 +288,7 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000);
|
OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000, false);
|
||||||
bool success = result["success"].AsBoolean();
|
bool success = result["success"].AsBoolean();
|
||||||
if (result.ContainsKey("_Result"))
|
if (result.ContainsKey("_Result"))
|
||||||
{
|
{
|
||||||
|
@ -326,7 +340,7 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000);
|
WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -346,7 +360,7 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000);
|
WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -736,6 +736,10 @@
|
||||||
;; Enable media on a prim facilities
|
;; Enable media on a prim facilities
|
||||||
; Enabled = true;
|
; 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]
|
[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
|
;# {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_sslport = 9001 ; Use this port for SSL connections
|
||||||
http_listener_ssl_cert = "" ; Currently unused, but will be used for OSHttpServer
|
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
|
; Hostname to use in llRequestURL/llRequestSecureURL
|
||||||
; if not defined - default machine name is being used
|
; if not defined - default machine name is being used
|
||||||
; (on Windows this mean NETBIOS name - useably only inside local network)
|
; (on Windows this mean NETBIOS name - useably only inside local network)
|
||||||
|
@ -1353,5 +1367,9 @@
|
||||||
;; default standalone, overridable in StandaloneCommon.ini
|
;; default standalone, overridable in StandaloneCommon.ini
|
||||||
StorageProvider = "OpenSim.Data.Null.dll:NullRegionData"
|
StorageProvider = "OpenSim.Data.Null.dll:NullRegionData"
|
||||||
|
|
||||||
|
[AutoBackupModule]
|
||||||
|
;; default is module is disabled at the top level
|
||||||
|
AutoBackupModuleEnabled = false
|
||||||
|
|
||||||
[Modules]
|
[Modules]
|
||||||
Include-modules = "addon-modules/*/config/*.ini"
|
Include-modules = "addon-modules/*/config/*.ini"
|
||||||
|
|
|
@ -29,6 +29,26 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
|
||||||
[Network]
|
[Network]
|
||||||
port = 8003
|
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
|
; * The following are for the remote console
|
||||||
; * They have no effect for the local or basic console types
|
; * They have no effect for the local or basic console types
|
||||||
; * Leave commented to diable logins to the console
|
; * Leave commented to diable logins to the console
|
||||||
|
|
|
@ -21,6 +21,27 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
|
||||||
[Network]
|
[Network]
|
||||||
port = 8003
|
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
|
; * The following are for the remote console
|
||||||
; * They have no effect for the local or basic console types
|
; * They have no effect for the local or basic console types
|
||||||
; * Leave commented to diable logins to the console
|
; * Leave commented to diable logins to the console
|
||||||
|
|
Loading…
Reference in New Issue