Merge branch 'master' into presence-refactor

This was a large, heavily conflicted merge and things MAY have got broken.
Please check!
slimupdates
Melanie 2010-02-08 15:53:20 +00:00
commit baaf660511
63 changed files with 5627 additions and 3494 deletions

View File

@ -56,7 +56,7 @@ namespace OpenSim.Client.MXP.PacketHandler
private readonly Dictionary<UUID, Scene> m_scenes;
private readonly Transmitter m_transmitter;
private readonly Thread m_clientThread;
// private readonly Thread m_clientThread;
private readonly IList<Session> m_sessions = new List<Session>();
private readonly IList<Session> m_sessionsToClient = new List<Session>();

View File

@ -82,9 +82,11 @@ namespace OpenSim.ConsoleClient
private static void SendCommand(string module, string[] cmd)
{
string sendCmd = cmd[0];
string sendCmd = "";
if (cmd.Length > 1)
{
sendCmd = cmd[0];
Array.Copy(cmd, 1, cmd, 0, cmd.Length-1);
Array.Resize(ref cmd, cmd.Length-1);
sendCmd += "\"" + String.Join("\" \"", cmd) + "\"";

View File

@ -43,10 +43,13 @@ namespace OpenSim.Data.MySQL
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private MySQLManager _dbConnection;
private string m_connectionString;
private object m_dbLock = new object();
#region IPlugin Members
public override string Version { get { return "1.0.0.0"; } }
/// <summary>
/// <para>Initialises Asset interface</para>
/// <para>
@ -58,62 +61,28 @@ namespace OpenSim.Data.MySQL
/// </para>
/// </summary>
/// <param name="connect">connect string</param>
override public void Initialise(string connect)
public override void Initialise(string connect)
{
// TODO: This will let you pass in the connect string in
// the config, though someone will need to write that.
if (connect == String.Empty)
{
// This is old seperate config file
m_log.Warn("no connect string, using old mysql_connection.ini instead");
Initialise();
}
else
{
_dbConnection = new MySQLManager(connect);
}
m_connectionString = connect;
// This actually does the roll forward assembly stuff
Assembly assem = GetType().Assembly;
Migration m = new Migration(_dbConnection.Connection, assem, "AssetStore");
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Migration m = new Migration(dbcon, assem, "AssetStore");
m.Update();
}
}
/// <summary>
/// <para>Initialises Asset interface</para>
/// <para>
/// <list type="bullet">
/// <item>Loads and initialises the MySQL storage plugin</item>
/// <item>uses the obsolete mysql_connection.ini</item>
/// </list>
/// </para>
/// </summary>
/// <remarks>DEPRECATED and shouldn't be used</remarks>
public override void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string hostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string database = GridDataMySqlFile.ParseFileReadValue("database");
string username = GridDataMySqlFile.ParseFileReadValue("username");
string password = GridDataMySqlFile.ParseFileReadValue("password");
string pooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string port = GridDataMySqlFile.ParseFileReadValue("port");
_dbConnection = new MySQLManager(hostname, database, username, password, pooling, port);
throw new NotImplementedException();
}
public override void Dispose() { }
/// <summary>
/// Database provider version
/// </summary>
override public string Version
{
get { return _dbConnection.getVersion(); }
}
/// <summary>
/// The name of this DB provider
/// </summary>
@ -135,14 +104,16 @@ namespace OpenSim.Data.MySQL
override public AssetBase GetAsset(UUID assetID)
{
AssetBase asset = null;
lock (_dbConnection)
lock (m_dbLock)
{
_dbConnection.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand(
using (MySqlCommand cmd = new MySqlCommand(
"SELECT name, description, assetType, local, temporary, data FROM assets WHERE id=?id",
_dbConnection.Connection);
dbcon))
{
cmd.Parameters.AddWithValue("?id", assetID.ToString());
try
@ -152,8 +123,8 @@ namespace OpenSim.Data.MySQL
if (dbReader.Read())
{
asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"]);
asset.Data = (byte[]) dbReader["data"];
asset.Description = (string) dbReader["description"];
asset.Data = (byte[])dbReader["data"];
asset.Description = (string)dbReader["description"];
string local = dbReader["local"].ToString();
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
@ -163,18 +134,13 @@ namespace OpenSim.Data.MySQL
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
}
dbReader.Close();
cmd.Dispose();
}
if (asset != null)
UpdateAccessTime(asset);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString()
+ Environment.NewLine + "Reconnecting", assetID);
_dbConnection.Reconnect();
m_log.Error("[ASSETS DB]: MySql failure fetching asset " + assetID + ": " + e.Message);
}
}
}
}
return asset;
@ -187,15 +153,17 @@ namespace OpenSim.Data.MySQL
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
override public void StoreAsset(AssetBase asset)
{
lock (_dbConnection)
lock (m_dbLock)
{
_dbConnection.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand(
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, data)" +
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?data)",
_dbConnection.Connection);
dbcon);
string assetName = asset.Name;
if (asset.Name.Length > 64)
@ -233,9 +201,9 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Attempting reconnect. Error: {2}",
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
_dbConnection.Reconnect();
}
}
}
}
@ -245,13 +213,14 @@ namespace OpenSim.Data.MySQL
// Writing to the database every time Get() is called on an asset is killing us. Seriously. -jph
return;
lock (_dbConnection)
lock (m_dbLock)
{
_dbConnection.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand("update assets set access_time=?access_time where id=?id",
_dbConnection.Connection);
dbcon);
// need to ensure we dispose
try
@ -272,7 +241,7 @@ namespace OpenSim.Data.MySQL
"[ASSETS DB]: " +
"MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
+ Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
_dbConnection.Reconnect();
}
}
}
@ -287,15 +256,13 @@ namespace OpenSim.Data.MySQL
{
bool assetExists = false;
lock (_dbConnection)
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM assets WHERE id=?id", dbcon))
{
_dbConnection.CheckConnection();
MySqlCommand cmd =
new MySqlCommand(
"SELECT id FROM assets WHERE id=?id",
_dbConnection.Connection);
cmd.Parameters.AddWithValue("?id", uuid.ToString());
try
@ -303,20 +270,15 @@ namespace OpenSim.Data.MySQL
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
assetExists = true;
}
dbReader.Close();
cmd.Dispose();
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString()
+ Environment.NewLine + "Attempting reconnection", uuid);
_dbConnection.Reconnect();
"[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid);
}
}
}
}
@ -335,11 +297,12 @@ namespace OpenSim.Data.MySQL
{
List<AssetMetadata> retList = new List<AssetMetadata>(count);
lock (_dbConnection)
lock (m_dbLock)
{
_dbConnection.CheckConnection();
MySqlCommand cmd = new MySqlCommand("SELECT name,description,assetType,temporary,id FROM assets LIMIT ?start, ?count", _dbConnection.Connection);
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("SELECT name,description,assetType,temporary,id FROM assets LIMIT ?start, ?count", dbcon);
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
@ -350,14 +313,14 @@ namespace OpenSim.Data.MySQL
while (dbReader.Read())
{
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string) dbReader["name"];
metadata.Description = (string) dbReader["description"];
metadata.Type = (sbyte) dbReader["assetType"];
metadata.Name = (string)dbReader["name"];
metadata.Description = (string)dbReader["description"];
metadata.Type = (sbyte)dbReader["assetType"];
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
metadata.FullID = new UUID((string) dbReader["id"]);
metadata.FullID = new UUID((string)dbReader["id"]);
// Current SHA1s are not stored/computed.
metadata.SHA1 = new byte[] {};
metadata.SHA1 = new byte[] { };
retList.Add(metadata);
}
@ -365,8 +328,8 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString() + Environment.NewLine + "Attempting reconnection");
_dbConnection.Reconnect();
m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
}
}
}
@ -374,7 +337,5 @@ namespace OpenSim.Data.MySQL
}
#endregion
}
}

View File

@ -38,30 +38,36 @@ namespace OpenSim.Data.MySQL
public class MySqlAuthenticationData : MySqlFramework, IAuthenticationData
{
private string m_Realm;
private List<string> m_ColumnNames = null;
private int m_LastExpire = 0;
private List<string> m_ColumnNames;
private int m_LastExpire;
// private string m_connectionString;
public MySqlAuthenticationData(string connectionString, string realm)
: base(connectionString)
{
m_Realm = realm;
m_connectionString = connectionString;
Migration m = new Migration(m_Connection, GetType().Assembly, "AuthStore");
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Migration m = new Migration(dbcon, GetType().Assembly, "AuthStore");
m.Update();
}
}
public AuthenticationData Get(UUID principalID)
{
AuthenticationData ret = new AuthenticationData();
ret.Data = new Dictionary<string, object>();
MySqlCommand cmd = new MySqlCommand(
"select * from `"+m_Realm+"` where UUID = ?principalID"
);
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon);
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
IDataReader result = ExecuteReader(cmd);
IDataReader result = cmd.ExecuteReader();
if (result.Read())
{
@ -84,17 +90,14 @@ namespace OpenSim.Data.MySQL
ret.Data[s] = result[s].ToString();
}
result.Close();
CloseReaderCommand(cmd);
return ret;
}
result.Close();
CloseReaderCommand(cmd);
else
{
return null;
}
}
}
public bool Store(AuthenticationData data)
{

View File

@ -44,7 +44,6 @@ namespace OpenSim.Data.MySQL
private const string m_waitTimeoutSelect = "select @@wait_timeout";
private MySqlConnection m_connection;
private string m_connectionString;
private long m_waitTimeout;
private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond;
@ -67,13 +66,14 @@ namespace OpenSim.Data.MySQL
m_log.Debug("Exception: password not found in connection string\n" + e.ToString());
}
m_connection = new MySqlConnection(m_connectionString);
m_connection.Open();
GetWaitTimeout();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Assembly assem = GetType().Assembly;
Migration m = new Migration(m_connection, assem, "EstateStore");
Migration m = new Migration(dbcon, assem, "EstateStore");
m.Update();
Type t = typeof(EstateSettings);
@ -87,6 +87,7 @@ namespace OpenSim.Data.MySQL
m_FieldMap[f.Name.Substring(2)] = f;
}
}
}
private string[] FieldList
{
@ -95,11 +96,13 @@ namespace OpenSim.Data.MySQL
protected void GetWaitTimeout()
{
MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect,
m_connection);
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlDataReader dbReader =
cmd.ExecuteReader(CommandBehavior.SingleRow))
using (MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon))
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
@ -107,9 +110,7 @@ namespace OpenSim.Data.MySQL
= Convert.ToInt32(dbReader["@@wait_timeout"]) *
TimeSpan.TicksPerSecond + m_waitTimeoutLeeway;
}
dbReader.Close();
cmd.Dispose();
}
}
m_lastConnectionUse = DateTime.Now.Ticks;
@ -118,24 +119,6 @@ namespace OpenSim.Data.MySQL
"[REGION DB]: Connection wait timeout {0} seconds",
m_waitTimeout / TimeSpan.TicksPerSecond);
}
protected void CheckConnection()
{
long timeNow = DateTime.Now.Ticks;
if (timeNow - m_lastConnectionUse > m_waitTimeout ||
m_connection.State != ConnectionState.Open)
{
m_log.DebugFormat("[REGION DB]: Database connection has gone away - reconnecting");
lock (m_connection)
{
m_connection.Close();
m_connection = new MySqlConnection(m_connectionString);
m_connection.Open();
}
}
m_lastConnectionUse = timeNow;
}
public EstateSettings LoadEstateSettings(UUID regionID)
@ -143,19 +126,26 @@ namespace OpenSim.Data.MySQL
EstateSettings es = new EstateSettings();
es.OnSave += StoreEstateSettings;
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID";
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) +
" from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID";
CheckConnection();
bool migration = true;
MySqlCommand cmd = m_connection.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
IDataReader r = cmd.ExecuteReader();
using (IDataReader r = cmd.ExecuteReader())
{
if (r.Read())
{
migration = false;
foreach (string name in FieldList)
{
if (m_FieldMap[name].GetValue(es) is bool)
@ -178,20 +168,21 @@ namespace OpenSim.Data.MySQL
m_FieldMap[name].SetValue(es, r[name]);
}
}
r.Close();
}
else
}
}
if (migration)
{
// Migration case
//
r.Close();
List<string> names = new List<string>(FieldList);
names.Remove("EstateID");
sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")";
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.Clear();
@ -215,43 +206,32 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = "select LAST_INSERT_ID() as id";
cmd.Parameters.Clear();
r = cmd.ExecuteReader();
using (IDataReader r = cmd.ExecuteReader())
{
r.Read();
es.EstateID = Convert.ToUInt32(r["id"]);
r.Close();
}
cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
// This will throw on dupe key
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
}
try { cmd.ExecuteNonQuery(); }
catch (Exception) { }
// Munge and transfer the ban list
//
cmd.Parameters.Clear();
cmd.CommandText = "insert into estateban select " + es.EstateID.ToString() + ", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = ?UUID";
cmd.Parameters.AddWithValue("?UUID", regionID.ToString());
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
}
try { cmd.ExecuteNonQuery(); }
catch (Exception) { }
es.Save();
}
}
}
LoadBanList(es);
@ -265,10 +245,12 @@ namespace OpenSim.Data.MySQL
{
string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")";
CheckConnection();
MySqlCommand cmd = m_connection.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = sql;
foreach (string name in FieldList)
@ -287,6 +269,8 @@ namespace OpenSim.Data.MySQL
}
cmd.ExecuteNonQuery();
}
}
SaveBanList(es);
SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
@ -298,15 +282,17 @@ namespace OpenSim.Data.MySQL
{
es.ClearBans();
CheckConnection();
MySqlCommand cmd = m_connection.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID";
cmd.Parameters.AddWithValue("?EstateID", es.EstateID);
IDataReader r = cmd.ExecuteReader();
using (IDataReader r = cmd.ExecuteReader())
{
while (r.Read())
{
EstateBan eb = new EstateBan();
@ -319,15 +305,19 @@ namespace OpenSim.Data.MySQL
eb.BannedHostIPMask = "0.0.0.0";
es.AddBan(eb);
}
r.Close();
}
}
}
}
private void SaveBanList(EstateSettings es)
{
CheckConnection();
MySqlCommand cmd = m_connection.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from estateban where EstateID = ?EstateID";
cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
@ -346,13 +336,17 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear();
}
}
}
}
void SaveUUIDList(uint EstateID, string table, UUID[] data)
{
CheckConnection();
MySqlCommand cmd = m_connection.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID";
cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString());
@ -371,20 +365,24 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear();
}
}
}
}
UUID[] LoadUUIDList(uint EstateID, string table)
{
List<UUID> uuids = new List<UUID>();
CheckConnection();
MySqlCommand cmd = m_connection.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID";
cmd.Parameters.AddWithValue("?EstateID", EstateID);
IDataReader r = cmd.ExecuteReader();
using (IDataReader r = cmd.ExecuteReader())
{
while (r.Read())
{
// EstateBan eb = new EstateBan();
@ -394,7 +392,9 @@ namespace OpenSim.Data.MySQL
uuids.Add(uuid);
}
r.Close();
}
}
}
return uuids.ToArray();
}

View File

@ -40,12 +40,16 @@ namespace OpenSim.Data.MySQL
/// </summary>
public class MySqlFramework
{
protected MySqlConnection m_Connection;
private static readonly log4net.ILog m_log =
log4net.LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected string m_connectionString;
protected object m_dbLock = new object();
protected MySqlFramework(string connectionString)
{
m_Connection = new MySqlConnection(connectionString);
m_Connection.Open();
m_connectionString = connectionString;
}
//////////////////////////////////////////////////////////////
@ -55,64 +59,24 @@ namespace OpenSim.Data.MySQL
//
protected int ExecuteNonQuery(MySqlCommand cmd)
{
lock (m_Connection)
lock (m_dbLock)
{
cmd.Connection = m_Connection;
bool errorSeen = false;
while (true)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
cmd.Connection = dbcon;
try
{
return cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
if (errorSeen)
throw;
// This is "Server has gone away" and "Server lost"
//
if (e.Number == 2006 || e.Number == 2013)
{
errorSeen = true;
m_Connection.Close();
MySqlConnection newConnection =
(MySqlConnection)((ICloneable)m_Connection).Clone();
m_Connection.Dispose();
m_Connection = newConnection;
m_Connection.Open();
cmd.Connection = m_Connection;
}
else
throw;
}
catch (Exception e)
{
m_log.Error(e.Message, e);
return 0;
}
}
}
}
protected IDataReader ExecuteReader(MySqlCommand cmd)
{
MySqlConnection newConnection =
(MySqlConnection)((ICloneable)m_Connection).Clone();
newConnection.Open();
cmd.Connection = newConnection;
return cmd.ExecuteReader();
}
protected void CloseReaderCommand(MySqlCommand cmd)
{
cmd.Connection.Close();
cmd.Connection.Dispose();
cmd.Dispose();
}
}
}

View File

@ -54,13 +54,17 @@ namespace OpenSim.Data.MySQL
string realm, string storeName) : base(connectionString)
{
m_Realm = realm;
m_connectionString = connectionString;
if (storeName != String.Empty)
{
Assembly assem = GetType().Assembly;
Migration m = new Migration(m_Connection, assem, storeName);
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Migration m = new Migration(dbcon, GetType().Assembly, storeName);
m.Update();
}
}
Type t = typeof(T);
FieldInfo[] fields = t.GetFields(BindingFlags.Public |
@ -107,8 +111,8 @@ namespace OpenSim.Data.MySQL
List<string> terms = new List<string>();
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
for (int i = 0 ; i < fields.Length ; i++)
{
cmd.Parameters.AddWithValue(fields[i], keys[i]);
@ -124,17 +128,24 @@ namespace OpenSim.Data.MySQL
return DoQuery(cmd);
}
}
protected T[] DoQuery(MySqlCommand cmd)
{
IDataReader reader = ExecuteReader(cmd);
List<T> result = new List<T>();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
cmd.Connection = dbcon;
using (IDataReader reader = cmd.ExecuteReader())
{
if (reader == null)
return new T[0];
CheckColumnNames(reader);
List<T> result = new List<T>();
while (reader.Read())
{
T row = new T();
@ -181,17 +192,16 @@ namespace OpenSim.Data.MySQL
result.Add(row);
}
reader.Close();
CloseReaderCommand(cmd);
}
}
return result.ToArray();
}
public virtual T[] Get(string where)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
string query = String.Format("select * from {0} where {1}",
m_Realm, where);
@ -200,10 +210,12 @@ namespace OpenSim.Data.MySQL
return DoQuery(cmd);
}
}
public virtual bool Store(T row)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
string query = "";
List<String> names = new List<String>();
@ -238,10 +250,12 @@ namespace OpenSim.Data.MySQL
return false;
}
}
public virtual bool Delete(string field, string val)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("delete from {0} where `{1}` = ?{1}", m_Realm, field);
cmd.Parameters.AddWithValue(field, val);
@ -252,4 +266,5 @@ namespace OpenSim.Data.MySQL
return false;
}
}
}
}

View File

@ -31,6 +31,7 @@ using System.Data;
using System.Reflection;
using System.Threading;
using log4net;
using MySql.Data.MySqlClient;
using OpenMetaverse;
using OpenSim.Framework;
@ -43,49 +44,9 @@ namespace OpenSim.Data.MySQL
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// MySQL Database Manager
/// </summary>
private MySQLManager database;
/// <summary>
/// Better DB manager. Swap-in replacement too.
/// </summary>
public Dictionary<int, MySQLSuperManager> m_dbconnections = new Dictionary<int, MySQLSuperManager>();
public int m_maxConnections = 10;
public int m_lastConnect;
public MySQLSuperManager GetLockedConnection()
{
int lockedCons = 0;
while (true)
{
m_lastConnect++;
// Overflow protection
if (m_lastConnect == int.MaxValue)
m_lastConnect = 0;
MySQLSuperManager x = m_dbconnections[m_lastConnect % m_maxConnections];
if (!x.Locked)
{
x.GetLock();
return x;
}
lockedCons++;
if (lockedCons > m_maxConnections)
{
lockedCons = 0;
Thread.Sleep(1000); // Wait some time before searching them again.
m_log.Debug(
"WARNING: All threads are in use. Probable cause: Something didnt release a mutex properly, or high volume of requests inbound.");
}
}
}
private MySQLManager m_database;
private object m_dbLock = new object();
private string m_connectionString;
override public void Initialise()
{
@ -106,57 +67,24 @@ namespace OpenSim.Data.MySQL
/// <param name="connect">connect string.</param>
override public void Initialise(string connect)
{
if (connect != String.Empty)
{
database = new MySQLManager(connect);
m_log.Info("Creating " + m_maxConnections + " DB connections...");
for (int i = 0; i < m_maxConnections; i++)
{
m_log.Info("Connecting to DB... [" + i + "]");
MySQLSuperManager msm = new MySQLSuperManager();
msm.Manager = new MySQLManager(connect);
m_dbconnections.Add(i, msm);
}
}
else
{
m_log.Warn("Using deprecated mysql_connection.ini. Please update database_connect in GridServer_Config.xml and we'll use that instead");
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword,
settingPooling, settingPort);
m_log.Info("Creating " + m_maxConnections + " DB connections...");
for (int i = 0; i < m_maxConnections; i++)
{
m_log.Info("Connecting to DB... [" + i + "]");
MySQLSuperManager msm = new MySQLSuperManager();
msm.Manager = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword,
settingPooling, settingPort);
m_dbconnections.Add(i, msm);
}
}
m_connectionString = connect;
m_database = new MySQLManager(connect);
// This actually does the roll forward assembly stuff
Assembly assem = GetType().Assembly;
Migration m = new Migration(database.Connection, assem, "GridStore");
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
Migration m = new Migration(dbcon, assem, "GridStore");
m.Update();
}
}
/// <summary>
/// Shuts down the grid interface
/// </summary>
override public void Dispose()
{
database.Close();
}
/// <summary>
@ -187,8 +115,6 @@ namespace OpenSim.Data.MySQL
/// <returns>Array of sim profiles</returns>
override public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax)
{
MySQLSuperManager dbm = GetLockedConnection();
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
@ -197,35 +123,33 @@ namespace OpenSim.Data.MySQL
param["?xmax"] = xmax.ToString();
param["?ymax"] = ymax.ToString();
IDbCommand result =
dbm.Manager.Query(
"SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax",
param);
IDataReader reader = result.ExecuteReader();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon,
"SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax",
param))
{
using (IDataReader reader = result.ExecuteReader())
{
RegionProfileData row;
List<RegionProfileData> rows = new List<RegionProfileData>();
while ((row = dbm.Manager.readSimRow(reader)) != null)
{
while ((row = m_database.readSimRow(reader)) != null)
rows.Add(row);
}
reader.Close();
result.Dispose();
return rows.ToArray();
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
/// <summary>
@ -236,42 +160,38 @@ namespace OpenSim.Data.MySQL
/// <returns>A list of sim profiles</returns>
override public List<RegionProfileData> GetRegionsByName(string namePrefix, uint maxNum)
{
MySQLSuperManager dbm = GetLockedConnection();
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?name"] = namePrefix + "%";
IDbCommand result =
dbm.Manager.Query(
"SELECT * FROM regions WHERE regionName LIKE ?name",
param);
IDataReader reader = result.ExecuteReader();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon,
"SELECT * FROM regions WHERE regionName LIKE ?name",
param))
{
using (IDataReader reader = result.ExecuteReader())
{
RegionProfileData row;
List<RegionProfileData> rows = new List<RegionProfileData>();
while (rows.Count < maxNum && (row = dbm.Manager.readSimRow(reader)) != null)
{
while (rows.Count < maxNum && (row = m_database.readSimRow(reader)) != null)
rows.Add(row);
}
reader.Close();
result.Dispose();
return rows;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
/// <summary>
@ -281,32 +201,30 @@ namespace OpenSim.Data.MySQL
/// <returns>Sim profile</returns>
override public RegionProfileData GetProfileByHandle(ulong handle)
{
MySQLSuperManager dbm = GetLockedConnection();
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?handle"] = handle.ToString();
IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = dbm.Manager.readSimRow(reader);
reader.Close();
result.Dispose();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM regions WHERE regionHandle = ?handle", param))
{
using (IDataReader reader = result.ExecuteReader())
{
RegionProfileData row = m_database.readSimRow(reader);
return row;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
/// <summary>
@ -316,30 +234,29 @@ namespace OpenSim.Data.MySQL
/// <returns>The sim profile</returns>
override public RegionProfileData GetProfileByUUID(UUID uuid)
{
MySQLSuperManager dbm = GetLockedConnection();
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?uuid"] = uuid.ToString();
IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE uuid = ?uuid", param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = dbm.Manager.readSimRow(reader);
reader.Close();
result.Dispose();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM regions WHERE uuid = ?uuid", param))
{
using (IDataReader reader = result.ExecuteReader())
{
RegionProfileData row = m_database.readSimRow(reader);
return row;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
} finally
{
dbm.Release();
}
}
@ -351,37 +268,36 @@ namespace OpenSim.Data.MySQL
{
if (regionName.Length > 2)
{
MySQLSuperManager dbm = GetLockedConnection();
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
// Add % because this is a like query.
param["?regionName"] = regionName + "%";
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
// Order by statement will return shorter matches first. Only returns one record or no record.
IDbCommand result =
dbm.Manager.Query(
using (IDbCommand result = m_database.Query(dbcon,
"SELECT * FROM regions WHERE regionName like ?regionName order by LENGTH(regionName) asc LIMIT 1",
param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = dbm.Manager.readSimRow(reader);
reader.Close();
result.Dispose();
param))
{
using (IDataReader reader = result.ExecuteReader())
{
RegionProfileData row = m_database.readSimRow(reader);
return row;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters");
return null;
}
@ -393,17 +309,16 @@ namespace OpenSim.Data.MySQL
/// <returns>Successful?</returns>
override public DataResponse StoreProfile(RegionProfileData profile)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
if (dbm.Manager.insertRegion(profile))
try
{
if (m_database.insertRegion(profile))
return DataResponse.RESPONSE_OK;
}
else
return DataResponse.RESPONSE_ERROR;
}
finally
catch
{
dbm.Release();
return DataResponse.RESPONSE_ERROR;
}
}
@ -415,18 +330,16 @@ namespace OpenSim.Data.MySQL
//public DataResponse DeleteProfile(RegionProfileData profile)
override public DataResponse DeleteProfile(string uuid)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
if (dbm.Manager.deleteRegion(uuid))
try
{
if (m_database.deleteRegion(uuid))
return DataResponse.RESPONSE_OK;
}
else
return DataResponse.RESPONSE_ERROR;
} finally
}
catch
{
dbm.Release();
return DataResponse.RESPONSE_ERROR;
}
}
@ -477,33 +390,32 @@ namespace OpenSim.Data.MySQL
/// <returns></returns>
override public ReservationData GetReservationAtPoint(uint x, uint y)
{
MySQLSuperManager dbm = GetLockedConnection();
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?x"] = x.ToString();
param["?y"] = y.ToString();
IDbCommand result =
dbm.Manager.Query(
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon,
"SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y",
param);
IDataReader reader = result.ExecuteReader();
ReservationData row = dbm.Manager.readReservationRow(reader);
reader.Close();
result.Dispose();
param))
{
using (IDataReader reader = result.ExecuteReader())
{
ReservationData row = m_database.readReservationRow(reader);
return row;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
} finally
{
dbm.Release();
}
}
}

View File

@ -26,7 +26,6 @@
*/
using System;
using System.IO;
using System.Collections.Generic;
using System.Reflection;
using log4net;
@ -44,14 +43,10 @@ namespace OpenSim.Data.MySQL
private static readonly ILog m_log
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The database manager
/// </summary>
private MySQLManager database;
private string m_connectionString;
private object m_dbLock = new object();
private bool rollbackStore = false;
private bool opengridmode = false;
private string rollbackDir = "";
public string Version { get { return "1.0.0.0"; } }
public void Initialise()
{
@ -72,38 +67,18 @@ namespace OpenSim.Data.MySQL
/// <param name="connect">connect string</param>
public void Initialise(string connect)
{
if (connect != String.Empty)
{
database = new MySQLManager(connect);
}
else
{
m_log.Warn("Reverting to deprecated mysql_connection.ini file for connection info");
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
rollbackDir = GridDataMySqlFile.ParseFileReadValue("rollbackdir");
rollbackStore = GridDataMySqlFile.ParseFileReadValue("rollback") == "true";
opengridmode = GridDataMySqlFile.ParseFileReadValue("opengridmode") == "true";
if (rollbackStore)
m_log.Warn("[MysqlInventory] Enabling rollback mode in: " + rollbackDir);
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
}
m_connectionString = connect;
// This actually does the roll forward assembly stuff
Assembly assem = GetType().Assembly;
Migration m = new Migration(database.Connection, assem, "InventoryStore");
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Migration m = new Migration(dbcon, assem, "InventoryStore");
m.Update();
}
}
/// <summary>
/// The name of this DB provider
@ -123,15 +98,6 @@ namespace OpenSim.Data.MySQL
// Do nothing.
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the DB provider version</returns>
public string Version
{
get { return database.getVersion(); }
}
/// <summary>
/// Returns a list of items in a specified folder
/// </summary>
@ -141,18 +107,20 @@ namespace OpenSim.Data.MySQL
{
try
{
lock (database)
lock (m_dbLock)
{
List<InventoryItemBase> items = new List<InventoryItemBase>();
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid",
database.Connection);
using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", folderID.ToString());
MySqlDataReader reader = result.ExecuteReader();
using (MySqlDataReader reader = result.ExecuteReader())
{
while (reader.Read())
{
// A null item (because something went wrong) breaks everything in the folder
@ -161,16 +129,15 @@ namespace OpenSim.Data.MySQL
items.Add(item);
}
reader.Close();
result.Dispose();
return items;
}
}
}
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
}
@ -184,33 +151,33 @@ namespace OpenSim.Data.MySQL
{
try
{
lock (database)
lock (m_dbLock)
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand result =
new MySqlCommand(
"SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid",
database.Connection);
using (MySqlCommand result = new MySqlCommand(
"SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", user.ToString());
result.Parameters.AddWithValue("?zero", UUID.Zero.ToString());
MySqlDataReader reader = result.ExecuteReader();
using (MySqlDataReader reader = result.ExecuteReader())
{
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
return items;
}
}
}
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
}
@ -225,19 +192,20 @@ namespace OpenSim.Data.MySQL
{
try
{
lock (database)
lock (m_dbLock)
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand result =
new MySqlCommand(
"SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid",
database.Connection);
using (MySqlCommand result = new MySqlCommand(
"SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", user.ToString());
result.Parameters.AddWithValue("?zero", UUID.Zero.ToString());
MySqlDataReader reader = result.ExecuteReader();
using (MySqlDataReader reader = result.ExecuteReader())
{
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
@ -250,21 +218,18 @@ namespace OpenSim.Data.MySQL
// to put such a message out, and it's too minor right now to spare the time to
// suitably refactor.
if (items.Count > 0)
{
rootFolder = items[0];
}
reader.Close();
result.Dispose();
return rootFolder;
}
}
}
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
throw;
m_log.Error(e.Message, e);
return null;
}
}
@ -279,31 +244,31 @@ namespace OpenSim.Data.MySQL
{
try
{
lock (database)
lock (m_dbLock)
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid",
database.Connection);
using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", parentID.ToString());
MySqlDataReader reader = result.ExecuteReader();
using (MySqlDataReader reader = result.ExecuteReader())
{
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
return items;
}
}
}
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
}
@ -378,29 +343,31 @@ namespace OpenSim.Data.MySQL
{
try
{
lock (database)
lock (m_dbLock)
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection);
using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", itemID.ToString());
MySqlDataReader reader = result.ExecuteReader();
using (MySqlDataReader reader = result.ExecuteReader())
{
InventoryItemBase item = null;
if (reader.Read())
item = readInventoryItem(reader);
reader.Close();
result.Dispose();
return item;
}
}
}
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
}
return null;
}
@ -425,7 +392,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
}
return null;
@ -441,151 +408,35 @@ namespace OpenSim.Data.MySQL
{
try
{
lock (database)
lock (m_dbLock)
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection);
using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", folderID.ToString());
MySqlDataReader reader = result.ExecuteReader();
using (MySqlDataReader reader = result.ExecuteReader())
{
InventoryFolderBase folder = null;
if (reader.Read())
folder = readInventoryFolder(reader);
reader.Close();
result.Dispose();
return folder;
}
}
}
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
}
#region Inventory Rollback-via-.sql Support
/// <summary>
/// Not a good SQL escape function, but it'll do the job (if mutilate the data.)
/// Someone may want to write something better here.
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private static string cheapSQLescape(string str)
{
str = str.Replace("\\", "");
str = str.Replace("'", "");
str = str.Replace("\"", "");
return "'" + str + "'";
}
private static string InventoryItemToSql(InventoryItemBase item)
{
string sql =
"REPLACE /*! INVITEM AT ***$SUBS$*** */ INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName"
+ ", inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType"
+ ", creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, inventoryGroupPermissions, salePrice, saleType"
+ ", creationDate, groupID, groupOwned, flags) VALUES ";
sql +=
"(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription"
+ ", ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID"
+ ", ?inventoryBasePermissions, ?inventoryEveryOnePermissions, ?inventoryGroupPermissions, ?salePrice, ?saleType, ?creationDate"
+ ", ?groupID, ?groupOwned, ?flags);\r\n";
string itemName = item.Name;
string itemDesc = item.Description;
sql = sql.Replace("$SUBS$", Util.UnixTimeSinceEpoch().ToString());
sql = sql.Replace("?inventoryID", cheapSQLescape(item.ID.ToString()));
sql = sql.Replace("?assetID", cheapSQLescape(item.AssetID.ToString()));
sql = sql.Replace("?assetType", cheapSQLescape(item.AssetType.ToString()));
sql = sql.Replace("?parentFolderID", cheapSQLescape(item.Folder.ToString()));
sql = sql.Replace("?avatarID", cheapSQLescape(item.Owner.ToString()));
sql = sql.Replace("?inventoryName", cheapSQLescape(itemName));
sql = sql.Replace("?inventoryDescription", cheapSQLescape(itemDesc));
sql = sql.Replace("?inventoryNextPermissions", cheapSQLescape(item.NextPermissions.ToString()));
sql = sql.Replace("?inventoryCurrentPermissions", cheapSQLescape(item.CurrentPermissions.ToString()));
sql = sql.Replace("?invType", cheapSQLescape(item.InvType.ToString()));
sql = sql.Replace("?creatorID", cheapSQLescape(item.CreatorId));
sql = sql.Replace("?inventoryBasePermissions", cheapSQLescape(item.BasePermissions.ToString()));
sql = sql.Replace("?inventoryEveryOnePermissions", cheapSQLescape(item.EveryOnePermissions.ToString()));
sql = sql.Replace("?inventoryGroupPermissions", cheapSQLescape(item.GroupPermissions.ToString()));
sql = sql.Replace("?salePrice", cheapSQLescape(item.SalePrice.ToString()));
sql = sql.Replace("?saleType", cheapSQLescape(unchecked((sbyte)item.SaleType).ToString()));
sql = sql.Replace("?creationDate", cheapSQLescape(item.CreationDate.ToString()));
sql = sql.Replace("?groupID", cheapSQLescape(item.GroupID.ToString()));
sql = sql.Replace("?groupOwned", cheapSQLescape(item.GroupOwned.ToString()));
sql = sql.Replace("?flags", cheapSQLescape(item.Flags.ToString()));
return sql;
}
private static string InventoryFolderToSql(InventoryFolderBase folder)
{
string sql =
"REPLACE /*! INVFOLDER AT ***$SUBS$*** */ INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES ";
sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version);\r\n";
string folderName = folder.Name;
sql = sql.Replace("$SUBS$", Util.UnixTimeSinceEpoch().ToString());
sql = sql.Replace("?folderID", cheapSQLescape(folder.ID.ToString()));
sql = sql.Replace("?agentID", cheapSQLescape(folder.Owner.ToString()));
sql = sql.Replace("?parentFolderID", cheapSQLescape(folder.ParentID.ToString()));
sql = sql.Replace("?folderName", cheapSQLescape(folderName));
sql = sql.Replace("?type", cheapSQLescape(folder.Type.ToString()));
sql = sql.Replace("?version", cheapSQLescape(folder.Version.ToString()));
return sql;
}
private static string getRollbackFolderDate()
{
return DateTime.UtcNow.Year.ToString() + "-" + DateTime.UtcNow.Month.ToString() + "-" +
DateTime.UtcNow.Day.ToString();
}
private void StoreRollbackItem(UUID ItemID)
{
if (rollbackStore == true)
{
string todaysPath = RollbackGetTodaysPath();
InventoryItemBase imb = getInventoryItem(ItemID);
string sql = InventoryItemToSql(imb);
File.AppendAllText(Path.Combine(todaysPath, imb.Owner.ToString()), sql);
}
}
private void StoreRollbackFolder(UUID FolderID)
{
if (rollbackStore == true)
{
string todaysPath = RollbackGetTodaysPath();
InventoryFolderBase ifb = getInventoryFolder(FolderID);
string sql = InventoryFolderToSql(ifb);
File.AppendAllText(Path.Combine(todaysPath, ifb.Owner.ToString()), sql);
}
}
private string RollbackGetTodaysPath()
{
if (!Directory.Exists(rollbackDir))
Directory.CreateDirectory(rollbackDir);
string todaysPath = Path.Combine(rollbackDir, getRollbackFolderDate());
if (!Directory.Exists(todaysPath))
Directory.CreateDirectory(todaysPath);
return todaysPath;
}
#endregion
/// <summary>
/// Adds a specified item to the database
/// </summary>
@ -619,9 +470,11 @@ namespace OpenSim.Data.MySQL
try
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand result = new MySqlCommand(sql, database.Connection);
MySqlCommand result = new MySqlCommand(sql, dbcon);
result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
@ -644,22 +497,22 @@ namespace OpenSim.Data.MySQL
result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
result.Parameters.AddWithValue("?flags", item.Flags);
lock (database)
lock (m_dbLock)
{
result.ExecuteNonQuery();
}
result.Dispose();
result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", database.Connection);
result.Parameters.AddWithValue("?folderID", item.Folder.ToString
());
lock (database)
result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon);
result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
lock (m_dbLock)
{
result.ExecuteNonQuery();
}
result.Dispose();
}
}
catch (MySqlException e)
{
m_log.Error(e.ToString());
@ -672,8 +525,6 @@ namespace OpenSim.Data.MySQL
/// <param name="item">Inventory item to update</param>
public void updateInventoryItem(InventoryItemBase item)
{
StoreRollbackItem(item.ID);
addInventoryItem(item);
}
@ -683,25 +534,24 @@ namespace OpenSim.Data.MySQL
/// <param name="item">The inventory item UUID to delete</param>
public void deleteInventoryItem(UUID itemID)
{
StoreRollbackItem(itemID);
try
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", database.Connection);
MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon);
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
lock (database)
lock (m_dbLock)
{
cmd.ExecuteNonQuery();
}
}
}
catch (MySqlException e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
}
}
@ -732,9 +582,11 @@ namespace OpenSim.Data.MySQL
m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length + " to " + folderName.Length + " characters on add folder");
}
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand(sql, database.Connection);
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
@ -744,7 +596,7 @@ namespace OpenSim.Data.MySQL
try
{
lock (database)
lock (m_dbLock)
{
cmd.ExecuteNonQuery();
}
@ -754,6 +606,7 @@ namespace OpenSim.Data.MySQL
m_log.Error(e.ToString());
}
}
}
/// <summary>
/// Updates an inventory folder
@ -761,7 +614,6 @@ namespace OpenSim.Data.MySQL
/// <param name="folder">Folder to update</param>
public void updateInventoryFolder(InventoryFolderBase folder)
{
StoreRollbackFolder(folder.ID);
addInventoryFolder(folder);
}
@ -772,20 +624,20 @@ namespace OpenSim.Data.MySQL
/// <remarks>UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID</remarks>
public void moveInventoryFolder(InventoryFolderBase folder)
{
StoreRollbackFolder(folder.ID);
string sql =
"UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID";
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand(sql, database.Connection);
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
try
{
lock (database)
lock (m_dbLock)
{
cmd.ExecuteNonQuery();
}
@ -795,6 +647,7 @@ namespace OpenSim.Data.MySQL
m_log.Error(e.ToString());
}
}
}
/// <summary>
/// Append a list of all the child folders of a parent folder
@ -836,54 +689,60 @@ namespace OpenSim.Data.MySQL
try
{
List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
Dictionary<UUID, List<InventoryFolderBase>> hashtable
= new Dictionary<UUID, List<InventoryFolderBase>>(); ;
Dictionary<UUID, List<InventoryFolderBase>> hashtable = new Dictionary<UUID, List<InventoryFolderBase>>(); ;
List<InventoryFolderBase> parentFolder = new List<InventoryFolderBase>();
lock (database)
{
MySqlCommand result;
MySqlDataReader reader;
bool buildResultsFromHashTable = false;
database.CheckConnection();
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
/* Fetch the parent folder from the database to determine the agent ID, and if
* we're querying the root of the inventory folder tree */
result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid",
database.Connection);
using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", parentID.ToString());
reader = result.ExecuteReader();
while (reader.Read()) // Should be at most 1 result
using (MySqlDataReader reader = result.ExecuteReader())
{
// Should be at most 1 result
while (reader.Read())
parentFolder.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
}
}
if (parentFolder.Count >= 1) // No result means parent folder does not exist
{
if (parentFolder[0].ParentID == UUID.Zero) // We are querying the root folder
{
/* Get all of the agent's folders from the database, put them in a list and return it */
result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid",
database.Connection);
using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString());
reader = result.ExecuteReader();
using (MySqlDataReader reader = result.ExecuteReader())
{
while (reader.Read())
{
InventoryFolderBase curFolder = readInventoryFolder(reader);
if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list
folders.Add(curFolder);
}
reader.Close();
result.Dispose();
}
}
} // if we are querying the root folder
else // else we are querying a subtree of the inventory folder tree
{
/* Get all of the agent's folders from the database, put them all in a hash table
* indexed by their parent ID */
result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid",
database.Connection);
using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", dbcon))
{
result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString());
reader = result.ExecuteReader();
using (MySqlDataReader reader = result.ExecuteReader())
{
while (reader.Read())
{
InventoryFolderBase curFolder = readInventoryFolder(reader);
@ -897,8 +756,8 @@ namespace OpenSim.Data.MySQL
hashtable.Add(curFolder.ParentID, siblingList);
}
} // while more items to read from the database
reader.Close();
result.Dispose();
}
}
// Set flag so we know we need to build the results from the hash table after
// we unlock the database
@ -918,13 +777,14 @@ namespace OpenSim.Data.MySQL
if (hashtable.ContainsKey(folders[i].ID))
folders.AddRange(hashtable[folders[i].ID]);
}
}
} // lock (database)
return folders;
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
}
@ -935,25 +795,24 @@ namespace OpenSim.Data.MySQL
/// <param name="folderID">the folder UUID</param>
protected void deleteOneFolder(UUID folderID)
{
StoreRollbackFolder(folderID);
try
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection);
using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", dbcon))
{
cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
lock (database)
{
lock (m_dbLock)
cmd.ExecuteNonQuery();
}
}
}
catch (MySqlException e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
}
}
@ -963,30 +822,23 @@ namespace OpenSim.Data.MySQL
/// <param name="folderID">the folder UUID</param>
protected void deleteItemsInFolder(UUID folderID)
{
if (rollbackStore)
{
foreach (InventoryItemBase itemBase in getInventoryInFolder(folderID))
{
StoreRollbackItem(itemBase.ID);
}
}
try
{
database.CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection);
using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", dbcon))
{
cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
lock (database)
{
lock (m_dbLock)
cmd.ExecuteNonQuery();
}
}
}
catch (MySqlException e)
{
database.Reconnect();
m_log.Error(e.ToString());
}
}
@ -999,60 +851,36 @@ namespace OpenSim.Data.MySQL
{
List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
// Dont delete in OGM - makes for easier restores if someone sends a malcious command. (just restore the folder entry)
if (opengridmode == false)
{
//Delete all sub-folders
foreach (InventoryFolderBase f in subFolders)
{
StoreRollbackFolder(f.ID);
deleteOneFolder(f.ID);
if (rollbackStore)
{
foreach (InventoryItemBase itemBase in getInventoryInFolder(f.ID))
{
StoreRollbackItem(itemBase.ID);
}
}
deleteItemsInFolder(f.ID);
}
}
StoreRollbackFolder(folderID);
//Delete the actual row
deleteOneFolder(folderID);
// Just delete the folder context in OGM
if (opengridmode == false)
{
if (rollbackStore)
{
foreach (InventoryItemBase itemBase in getInventoryInFolder(folderID))
{
StoreRollbackItem(itemBase.ID);
}
}
deleteItemsInFolder(folderID);
}
}
public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
{
MySqlDataReader result = null;
MySqlCommand sqlCmd = null;
lock (database)
lock (m_dbLock)
{
try
{
database.CheckConnection();
sqlCmd = new MySqlCommand(
"SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags = 1",
database.Connection);
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand sqlCmd = new MySqlCommand(
"SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags = 1", dbcon))
{
sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString());
sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture);
result = sqlCmd.ExecuteReader();
using (MySqlDataReader result = sqlCmd.ExecuteReader())
{
List<InventoryItemBase> list = new List<InventoryItemBase>();
while (result.Read())
{
@ -1062,17 +890,14 @@ namespace OpenSim.Data.MySQL
}
return list;
}
}
}
}
catch (Exception e)
{
database.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
if (result != null) result.Close();
if (sqlCmd != null) sqlCmd.Dispose();
}
}
}
}

View File

@ -48,109 +48,70 @@ namespace OpenSim.Data.MySQL
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_ConnectionString;
private MySqlConnection m_Connection = null;
private string m_connectionString;
private object m_dbLock = new object();
public void Initialise(string connectionString)
{
m_ConnectionString = connectionString;
m_connectionString = connectionString;
m_Connection = new MySqlConnection(m_ConnectionString);
m_Connection.Open();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
// Apply new Migrations
//
Assembly assem = GetType().Assembly;
Migration m = new Migration(m_Connection, assem, "RegionStore");
Migration m = new Migration(dbcon, assem, "RegionStore");
m.Update();
// NOTE: This is a very slow query that times out on regions with a lot of prims.
// I'm told that it is no longer relevant so it's commented out now, but if it
// is relevant it should be added as a console command instead of part of the
// startup phase
// Clean dropped attachments
//
//try
//{
// using (MySqlCommand cmd = m_Connection.CreateCommand())
// {
// cmd.CommandText = "delete from prims, primshapes using prims " +
// "left join primshapes on prims.uuid = primshapes.uuid " +
// "where PCode = 9 and State <> 0";
// ExecuteNonQuery(cmd);
// }
//}
//catch (MySqlException ex)
//{
// m_log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
//}
try
{
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from prims, primshapes using prims " +
"left join primshapes on prims.uuid = primshapes.uuid " +
"where PCode = 9 and State <> 0";
ExecuteNonQuery(cmd);
}
}
catch (MySqlException ex)
{
m_log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
}
}
}
private IDataReader ExecuteReader(MySqlCommand c)
{
IDataReader r = null;
bool errorSeen = false;
while (true)
{
try
{
r = c.ExecuteReader();
}
catch (Exception)
catch (Exception e)
{
Thread.Sleep(500);
m_Connection.Close();
m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone();
m_Connection.Open();
c.Connection = m_Connection;
if (!errorSeen)
{
errorSeen = true;
continue;
}
m_log.Error("[REGION DB]: MySQL error in ExecuteReader: " + e.Message);
throw;
}
break;
}
return r;
}
private void ExecuteNonQuery(MySqlCommand c)
{
bool errorSeen = false;
while (true)
{
try
{
c.ExecuteNonQuery();
}
catch (Exception)
catch (Exception e)
{
Thread.Sleep(500);
m_Connection.Close();
m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone();
m_Connection.Open();
c.Connection = m_Connection;
if (!errorSeen)
{
errorSeen = true;
continue;
}
m_log.Error("[REGION DB]: MySQL error in ExecuteNonQuery: " + e.Message);
throw;
}
break;
}
}
public void Dispose() {}
@ -166,80 +127,83 @@ namespace OpenSim.Data.MySQL
if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
return;
lock (m_Connection)
lock (m_dbLock)
{
MySqlCommand cmd = m_Connection.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = dbcon.CreateCommand();
foreach (SceneObjectPart prim in obj.Children.Values)
{
cmd.Parameters.Clear();
cmd.CommandText = "replace into prims ("+
"UUID, CreationDate, "+
"Name, Text, Description, "+
"SitName, TouchName, ObjectFlags, "+
"OwnerMask, NextOwnerMask, GroupMask, "+
"EveryoneMask, BaseMask, PositionX, "+
"PositionY, PositionZ, GroupPositionX, "+
"GroupPositionY, GroupPositionZ, VelocityX, "+
"VelocityY, VelocityZ, AngularVelocityX, "+
"AngularVelocityY, AngularVelocityZ, "+
"AccelerationX, AccelerationY, "+
"AccelerationZ, RotationX, "+
"RotationY, RotationZ, "+
"RotationW, SitTargetOffsetX, "+
"SitTargetOffsetY, SitTargetOffsetZ, "+
"SitTargetOrientW, SitTargetOrientX, "+
"SitTargetOrientY, SitTargetOrientZ, "+
"RegionUUID, CreatorID, "+
"OwnerID, GroupID, "+
"LastOwnerID, SceneGroupID, "+
"PayPrice, PayButton1, "+
"PayButton2, PayButton3, "+
"PayButton4, LoopedSound, "+
"LoopedSoundGain, TextureAnimation, "+
"OmegaX, OmegaY, OmegaZ, "+
"CameraEyeOffsetX, CameraEyeOffsetY, "+
"CameraEyeOffsetZ, CameraAtOffsetX, "+
"CameraAtOffsetY, CameraAtOffsetZ, "+
"ForceMouselook, ScriptAccessPin, "+
"AllowedDrop, DieAtEdge, "+
"SalePrice, SaleType, "+
"ColorR, ColorG, ColorB, ColorA, "+
"ParticleSystem, ClickAction, Material, "+
"CollisionSound, CollisionSoundVolume, "+
"PassTouches, "+
"LinkNumber) values (" + "?UUID, "+
"?CreationDate, ?Name, ?Text, "+
"?Description, ?SitName, ?TouchName, "+
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, "+
"?GroupMask, ?EveryoneMask, ?BaseMask, "+
"?PositionX, ?PositionY, ?PositionZ, "+
"?GroupPositionX, ?GroupPositionY, "+
"?GroupPositionZ, ?VelocityX, "+
"?VelocityY, ?VelocityZ, ?AngularVelocityX, "+
"?AngularVelocityY, ?AngularVelocityZ, "+
"?AccelerationX, ?AccelerationY, "+
"?AccelerationZ, ?RotationX, "+
"?RotationY, ?RotationZ, "+
"?RotationW, ?SitTargetOffsetX, "+
"?SitTargetOffsetY, ?SitTargetOffsetZ, "+
"?SitTargetOrientW, ?SitTargetOrientX, "+
"?SitTargetOrientY, ?SitTargetOrientZ, "+
"?RegionUUID, ?CreatorID, ?OwnerID, "+
"?GroupID, ?LastOwnerID, ?SceneGroupID, "+
"?PayPrice, ?PayButton1, ?PayButton2, "+
"?PayButton3, ?PayButton4, ?LoopedSound, "+
"?LoopedSoundGain, ?TextureAnimation, "+
"?OmegaX, ?OmegaY, ?OmegaZ, "+
"?CameraEyeOffsetX, ?CameraEyeOffsetY, "+
"?CameraEyeOffsetZ, ?CameraAtOffsetX, "+
"?CameraAtOffsetY, ?CameraAtOffsetZ, "+
"?ForceMouselook, ?ScriptAccessPin, "+
"?AllowedDrop, ?DieAtEdge, ?SalePrice, "+
"?SaleType, ?ColorR, ?ColorG, "+
"?ColorB, ?ColorA, ?ParticleSystem, "+
"?ClickAction, ?Material, ?CollisionSound, "+
cmd.CommandText = "replace into prims (" +
"UUID, CreationDate, " +
"Name, Text, Description, " +
"SitName, TouchName, ObjectFlags, " +
"OwnerMask, NextOwnerMask, GroupMask, " +
"EveryoneMask, BaseMask, PositionX, " +
"PositionY, PositionZ, GroupPositionX, " +
"GroupPositionY, GroupPositionZ, VelocityX, " +
"VelocityY, VelocityZ, AngularVelocityX, " +
"AngularVelocityY, AngularVelocityZ, " +
"AccelerationX, AccelerationY, " +
"AccelerationZ, RotationX, " +
"RotationY, RotationZ, " +
"RotationW, SitTargetOffsetX, " +
"SitTargetOffsetY, SitTargetOffsetZ, " +
"SitTargetOrientW, SitTargetOrientX, " +
"SitTargetOrientY, SitTargetOrientZ, " +
"RegionUUID, CreatorID, " +
"OwnerID, GroupID, " +
"LastOwnerID, SceneGroupID, " +
"PayPrice, PayButton1, " +
"PayButton2, PayButton3, " +
"PayButton4, LoopedSound, " +
"LoopedSoundGain, TextureAnimation, " +
"OmegaX, OmegaY, OmegaZ, " +
"CameraEyeOffsetX, CameraEyeOffsetY, " +
"CameraEyeOffsetZ, CameraAtOffsetX, " +
"CameraAtOffsetY, CameraAtOffsetZ, " +
"ForceMouselook, ScriptAccessPin, " +
"AllowedDrop, DieAtEdge, " +
"SalePrice, SaleType, " +
"ColorR, ColorG, ColorB, ColorA, " +
"ParticleSystem, ClickAction, Material, " +
"CollisionSound, CollisionSoundVolume, " +
"PassTouches, " +
"LinkNumber) values (" + "?UUID, " +
"?CreationDate, ?Name, ?Text, " +
"?Description, ?SitName, ?TouchName, " +
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
"?GroupMask, ?EveryoneMask, ?BaseMask, " +
"?PositionX, ?PositionY, ?PositionZ, " +
"?GroupPositionX, ?GroupPositionY, " +
"?GroupPositionZ, ?VelocityX, " +
"?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
"?AngularVelocityY, ?AngularVelocityZ, " +
"?AccelerationX, ?AccelerationY, " +
"?AccelerationZ, ?RotationX, " +
"?RotationY, ?RotationZ, " +
"?RotationW, ?SitTargetOffsetX, " +
"?SitTargetOffsetY, ?SitTargetOffsetZ, " +
"?SitTargetOrientW, ?SitTargetOrientX, " +
"?SitTargetOrientY, ?SitTargetOrientZ, " +
"?RegionUUID, ?CreatorID, ?OwnerID, " +
"?GroupID, ?LastOwnerID, ?SceneGroupID, " +
"?PayPrice, ?PayButton1, ?PayButton2, " +
"?PayButton3, ?PayButton4, ?LoopedSound, " +
"?LoopedSoundGain, ?TextureAnimation, " +
"?OmegaX, ?OmegaY, ?OmegaZ, " +
"?CameraEyeOffsetX, ?CameraEyeOffsetY, " +
"?CameraEyeOffsetZ, ?CameraAtOffsetX, " +
"?CameraAtOffsetY, ?CameraAtOffsetZ, " +
"?ForceMouselook, ?ScriptAccessPin, " +
"?AllowedDrop, ?DieAtEdge, ?SalePrice, " +
"?SaleType, ?ColorR, ?ColorG, " +
"?ColorB, ?ColorA, ?ParticleSystem, " +
"?ClickAction, ?Material, ?CollisionSound, " +
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
@ -248,26 +212,26 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.Clear();
cmd.CommandText = "replace into primshapes ("+
"UUID, Shape, ScaleX, ScaleY, "+
"ScaleZ, PCode, PathBegin, PathEnd, "+
"PathScaleX, PathScaleY, PathShearX, "+
"PathShearY, PathSkew, PathCurve, "+
"PathRadiusOffset, PathRevolutions, "+
"PathTaperX, PathTaperY, PathTwist, "+
"PathTwistBegin, ProfileBegin, ProfileEnd, "+
"ProfileCurve, ProfileHollow, Texture, "+
"ExtraParams, State) values (?UUID, "+
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, "+
"?PCode, ?PathBegin, ?PathEnd, "+
"?PathScaleX, ?PathScaleY, "+
"?PathShearX, ?PathShearY, "+
"?PathSkew, ?PathCurve, ?PathRadiusOffset, "+
"?PathRevolutions, ?PathTaperX, "+
"?PathTaperY, ?PathTwist, "+
"?PathTwistBegin, ?ProfileBegin, "+
"?ProfileEnd, ?ProfileCurve, "+
"?ProfileHollow, ?Texture, ?ExtraParams, "+
cmd.CommandText = "replace into primshapes (" +
"UUID, Shape, ScaleX, ScaleY, " +
"ScaleZ, PCode, PathBegin, PathEnd, " +
"PathScaleX, PathScaleY, PathShearX, " +
"PathShearY, PathSkew, PathCurve, " +
"PathRadiusOffset, PathRevolutions, " +
"PathTaperX, PathTaperY, PathTwist, " +
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
"ProfileCurve, ProfileHollow, Texture, " +
"ExtraParams, State) values (?UUID, " +
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
"?PCode, ?PathBegin, ?PathEnd, " +
"?PathScaleX, ?PathScaleY, " +
"?PathShearX, ?PathShearY, " +
"?PathSkew, ?PathCurve, ?PathRadiusOffset, " +
"?PathRevolutions, ?PathTaperX, " +
"?PathTaperY, ?PathTwist, " +
"?PathTwistBegin, ?ProfileBegin, " +
"?ProfileEnd, ?ProfileCurve, " +
"?ProfileHollow, ?Texture, ?ExtraParams, " +
"?State)";
FillShapeCommand(cmd, prim);
@ -277,6 +241,7 @@ namespace OpenSim.Data.MySQL
cmd.Dispose();
}
}
}
public void RemoveObject(UUID obj, UUID regionUUID)
{
@ -290,9 +255,13 @@ namespace OpenSim.Data.MySQL
// cause the loss of a prim, but is cleaner.
// It's also faster because it uses the primary key.
//
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select UUID from prims where SceneGroupID= ?UUID";
cmd.Parameters.AddWithValue("UUID", obj.ToString());
@ -308,6 +277,7 @@ namespace OpenSim.Data.MySQL
ExecuteNonQuery(cmd);
}
}
}
// there is no way this should be < 1 unless there is
// a very corrupt database, but in that case be extra
@ -326,9 +296,13 @@ namespace OpenSim.Data.MySQL
/// <param name="uuid">the Item UUID</param>
private void RemoveItems(UUID uuid)
{
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from primitems where PrimID = ?PrimID";
cmd.Parameters.AddWithValue("PrimID", uuid.ToString());
@ -337,6 +311,7 @@ namespace OpenSim.Data.MySQL
}
}
}
}
/// <summary>
/// Remove all persisted shapes for a list of prims
@ -345,11 +320,14 @@ namespace OpenSim.Data.MySQL
/// <param name="uuids">the list of UUIDs</param>
private void RemoveShapes(List<UUID> uuids)
{
lock (m_Connection)
lock (m_dbLock)
{
string sql = "delete from primshapes where ";
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlCommand cmd = dbcon.CreateCommand())
{
for (int i = 0; i < uuids.Count; i++)
{
@ -371,6 +349,7 @@ namespace OpenSim.Data.MySQL
}
}
}
}
/// <summary>
/// Remove all persisted items for a list of prims
@ -379,11 +358,14 @@ namespace OpenSim.Data.MySQL
/// <param name="uuids">the list of UUIDs</param>
private void RemoveItems(List<UUID> uuids)
{
lock (m_Connection)
lock (m_dbLock)
{
string sql = "delete from primitems where ";
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlCommand cmd = dbcon.CreateCommand())
{
for (int i = 0; i < uuids.Count; i++)
{
@ -406,6 +388,7 @@ namespace OpenSim.Data.MySQL
}
}
}
}
public List<SceneObjectGroup> LoadObjects(UUID regionID)
{
@ -417,9 +400,13 @@ namespace OpenSim.Data.MySQL
#region Prim Loading
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText =
"SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID";
@ -448,6 +435,7 @@ namespace OpenSim.Data.MySQL
}
}
}
}
#endregion Prim Loading
@ -497,9 +485,13 @@ namespace OpenSim.Data.MySQL
// list from DB of all prims which have items and
// LoadItems only on those
List<SceneObjectPart> primsWithInventory = new List<SceneObjectPart>();
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand itemCmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand itemCmd = dbcon.CreateCommand())
{
itemCmd.CommandText = "SELECT DISTINCT primID FROM primitems";
using (IDataReader itemReader = ExecuteReader(itemCmd))
@ -516,6 +508,7 @@ namespace OpenSim.Data.MySQL
}
}
}
}
foreach (SceneObjectPart prim in primsWithInventory)
{
@ -535,11 +528,15 @@ namespace OpenSim.Data.MySQL
/// <param name="prim">The prim</param>
private void LoadItems(SceneObjectPart prim)
{
lock (m_Connection)
lock (m_dbLock)
{
List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select * from primitems where PrimID = ?PrimID";
cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString());
@ -555,6 +552,7 @@ namespace OpenSim.Data.MySQL
}
}
}
}
prim.Inventory.RestoreInventoryItems(inventory);
}
@ -564,9 +562,13 @@ namespace OpenSim.Data.MySQL
{
m_log.Info("[REGION DB]: Storing terrain");
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
@ -583,14 +585,19 @@ namespace OpenSim.Data.MySQL
}
}
}
}
public double[,] LoadTerrain(UUID regionID)
{
double[,] terrain = null;
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select RegionUUID, Revision, Heightfield " +
"from terrain where RegionUUID = ?RegionUUID " +
@ -625,15 +632,20 @@ namespace OpenSim.Data.MySQL
}
}
}
}
return terrain;
}
public void RemoveLandObject(UUID globalID)
{
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from land where UUID = ?UUID";
cmd.Parameters.AddWithValue("UUID", globalID.ToString());
@ -642,12 +654,17 @@ namespace OpenSim.Data.MySQL
}
}
}
}
public void StoreLandObject(ILandObject parcel)
{
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "replace into land (UUID, RegionUUID, " +
"LocalLandID, Bitmap, Name, Description, " +
@ -692,14 +709,19 @@ namespace OpenSim.Data.MySQL
}
}
}
}
public RegionSettings LoadRegionSettings(UUID regionUUID)
{
RegionSettings rs = null;
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select * from regionsettings where regionUUID = ?RegionUUID";
cmd.Parameters.AddWithValue("regionUUID", regionUUID);
@ -722,15 +744,20 @@ namespace OpenSim.Data.MySQL
}
}
}
}
return rs;
}
public void StoreRegionSettings(RegionSettings rs)
{
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "replace into regionsettings (regionUUID, " +
"block_terraform, block_fly, allow_damage, " +
@ -771,14 +798,19 @@ namespace OpenSim.Data.MySQL
}
}
}
}
public List<LandData> LoadLandObjects(UUID regionUUID)
{
List<LandData> landData = new List<LandData>();
lock (m_Connection)
lock (m_dbLock)
{
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select * from land where RegionUUID = ?RegionUUID";
cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString());
@ -793,7 +825,7 @@ namespace OpenSim.Data.MySQL
}
}
using (MySqlCommand cmd = m_Connection.CreateCommand())
using (MySqlCommand cmd = dbcon.CreateCommand())
{
foreach (LandData land in landData)
{
@ -811,6 +843,7 @@ namespace OpenSim.Data.MySQL
}
}
}
}
return landData;
}
@ -1513,29 +1546,33 @@ namespace OpenSim.Data.MySQL
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
{
lock (m_Connection)
lock (m_dbLock)
{
RemoveItems(primID);
MySqlCommand cmd = m_Connection.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = dbcon.CreateCommand();
if (items.Count == 0)
return;
cmd.CommandText = "insert into primitems ("+
"invType, assetType, name, "+
"description, creationDate, nextPermissions, "+
"currentPermissions, basePermissions, "+
"everyonePermissions, groupPermissions, "+
"flags, itemID, primID, assetID, "+
"parentFolderID, creatorID, ownerID, "+
"groupID, lastOwnerID) values (?invType, "+
"?assetType, ?name, ?description, "+
"?creationDate, ?nextPermissions, "+
"?currentPermissions, ?basePermissions, "+
"?everyonePermissions, ?groupPermissions, "+
"?flags, ?itemID, ?primID, ?assetID, "+
"?parentFolderID, ?creatorID, ?ownerID, "+
cmd.CommandText = "insert into primitems (" +
"invType, assetType, name, " +
"description, creationDate, nextPermissions, " +
"currentPermissions, basePermissions, " +
"everyonePermissions, groupPermissions, " +
"flags, itemID, primID, assetID, " +
"parentFolderID, creatorID, ownerID, " +
"groupID, lastOwnerID) values (?invType, " +
"?assetType, ?name, ?description, " +
"?creationDate, ?nextPermissions, " +
"?currentPermissions, ?basePermissions, " +
"?everyonePermissions, ?groupPermissions, " +
"?flags, ?itemID, ?primID, ?assetID, " +
"?parentFolderID, ?creatorID, ?ownerID, " +
"?groupID, ?lastOwnerID)";
foreach (TaskInventoryItem item in items)
@ -1551,4 +1588,5 @@ namespace OpenSim.Data.MySQL
}
}
}
}
}

View File

@ -79,14 +79,19 @@ namespace OpenSim.Data.MySQL
// This actually does the roll forward assembly stuff
Assembly assem = GetType().Assembly;
Migration m = new Migration(database.Connection, assem, "LogStore");
using (MySql.Data.MySqlClient.MySqlConnection dbcon = new MySql.Data.MySqlClient.MySqlConnection(connect))
{
dbcon.Open();
Migration m = new Migration(dbcon, assem, "LogStore");
// TODO: After rev 6000, remove this. People should have
// been rolled onto the new migration code by then.
TestTables(m);
m.Update();
}
}
/// <summary></summary>
@ -128,7 +133,6 @@ namespace OpenSim.Data.MySQL
}
catch
{
database.Reconnect();
}
}

View File

@ -45,16 +45,13 @@ namespace OpenSim.Data.MySQL
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The database connection object
/// </summary>
private MySqlConnection dbcon;
/// <summary>
/// Connection string for ADO.net
/// </summary>
private string connectionString;
private object m_dbLock = new object();
private const string m_waitTimeoutSelect = "select @@wait_timeout";
/// <summary>
@ -109,11 +106,11 @@ namespace OpenSim.Data.MySQL
try
{
connectionString = connect;
dbcon = new MySqlConnection(connectionString);
//dbcon = new MySqlConnection(connectionString);
try
{
dbcon.Open();
//dbcon.Open();
}
catch(Exception e)
{
@ -134,8 +131,12 @@ namespace OpenSim.Data.MySQL
/// </summary>
protected void GetWaitTimeout()
{
MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon);
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon))
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
@ -143,9 +144,8 @@ namespace OpenSim.Data.MySQL
m_waitTimeout
= Convert.ToInt32(dbReader["@@wait_timeout"]) * TimeSpan.TicksPerSecond + m_waitTimeoutLeeway;
}
dbReader.Close();
cmd.Dispose();
}
}
}
m_lastConnectionUse = DateTime.Now.Ticks;
@ -154,66 +154,9 @@ namespace OpenSim.Data.MySQL
"[REGION DB]: Connection wait timeout {0} seconds", m_waitTimeout / TimeSpan.TicksPerSecond);
}
/// <summary>
/// Should be called before any db operation. This checks to see if the connection has not timed out
/// </summary>
public void CheckConnection()
public string ConnectionString
{
//m_log.Debug("[REGION DB]: Checking connection");
long timeNow = DateTime.Now.Ticks;
if (timeNow - m_lastConnectionUse > m_waitTimeout || dbcon.State != ConnectionState.Open)
{
m_log.DebugFormat("[REGION DB]: Database connection has gone away - reconnecting");
Reconnect();
}
// Strictly, we should set this after the actual db operation. But it's more convenient to set here rather
// than require the code to call another method - the timeout leeway should be large enough to cover the
// inaccuracy.
m_lastConnectionUse = timeNow;
}
/// <summary>
/// Get the connection being used
/// </summary>
/// <returns>MySqlConnection Object</returns>
public MySqlConnection Connection
{
get { return dbcon; }
}
/// <summary>
/// Shuts down the database connection
/// </summary>
public void Close()
{
dbcon.Close();
dbcon = null;
}
/// <summary>
/// Reconnects to the database
/// </summary>
public void Reconnect()
{
m_log.Info("[REGION DB] Reconnecting database");
lock (dbcon)
{
try
{
// Close the DB connection
dbcon.Close();
// Try reopen it
dbcon = new MySqlConnection(connectionString);
dbcon.Open();
}
catch (Exception e)
{
m_log.Error("Unable to reconnect to database " + e.ToString());
}
}
get { return connectionString; }
}
/// <summary>
@ -264,10 +207,14 @@ namespace OpenSim.Data.MySQL
/// <param name="name">name of embedded resource</param>
public void ExecuteResourceSql(string name)
{
CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand(getResourceString(name), dbcon);
cmd.ExecuteNonQuery();
}
}
/// <summary>
/// Execute a MySqlCommand
@ -275,14 +222,20 @@ namespace OpenSim.Data.MySQL
/// <param name="sql">sql string to execute</param>
public void ExecuteSql(string sql)
{
CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
cmd.ExecuteNonQuery();
}
}
public void ExecuteParameterizedSql(string sql, Dictionary<string, string> parameters)
{
CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand();
cmd.CommandText = sql;
@ -292,6 +245,7 @@ namespace OpenSim.Data.MySQL
}
cmd.ExecuteNonQuery();
}
}
/// <summary>
/// Given a list of tables, return the version of the tables, as seen in the database
@ -299,14 +253,15 @@ namespace OpenSim.Data.MySQL
/// <param name="tableList"></param>
public void GetTableVersion(Dictionary<string, string> tableList)
{
lock (dbcon)
lock (m_dbLock)
{
CheckConnection();
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
MySqlCommand tablesCmd =
new MySqlCommand(
"SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname",
dbcon);
using (MySqlCommand tablesCmd = new MySqlCommand(
"SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname", dbcon))
{
tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database);
using (MySqlDataReader tables = tablesCmd.ExecuteReader())
@ -315,8 +270,8 @@ namespace OpenSim.Data.MySQL
{
try
{
string tableName = (string) tables["TABLE_NAME"];
string comment = (string) tables["TABLE_COMMENT"];
string tableName = (string)tables["TABLE_NAME"];
string comment = (string)tables["TABLE_COMMENT"];
if (tableList.ContainsKey(tableName))
{
tableList[tableName] = comment;
@ -324,10 +279,11 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
}
}
}
}
tables.Close();
}
}
}
@ -337,28 +293,27 @@ namespace OpenSim.Data.MySQL
/// <summary>
/// Runs a query with protection against SQL Injection by using parameterised input.
/// </summary>
/// <param name="dbcon">Database connection</param>
/// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
/// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param>
/// <returns>A MySQL DB Command</returns>
public IDbCommand Query(string sql, Dictionary<string, object> parameters)
public IDbCommand Query(MySqlConnection dbcon, string sql, Dictionary<string, object> parameters)
{
try
{
CheckConnection(); // Not sure if this one is necessary
MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand();
MySqlCommand dbcommand = (MySqlCommand)dbcon.CreateCommand();
dbcommand.CommandText = sql;
foreach (KeyValuePair<string, object> param in parameters)
{
dbcommand.Parameters.AddWithValue(param.Key, param.Value);
}
return (IDbCommand) dbcommand;
return (IDbCommand)dbcommand;
}
catch (Exception e)
{
// Return null if it fails.
m_log.Error("Failed during Query generation: " + e.ToString());
m_log.Error("Failed during Query generation: " + e.Message, e);
return null;
}
}
@ -694,8 +649,6 @@ namespace OpenSim.Data.MySQL
ret.Add(attachpoint, item);
}
r.Close();
return ret;
}
@ -727,13 +680,18 @@ namespace OpenSim.Data.MySQL
try
{
IDbCommand result = Query(sql, parameters);
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
IDbCommand result = Query(dbcon, sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
@ -828,13 +786,18 @@ namespace OpenSim.Data.MySQL
try
{
IDbCommand result = Query(sql, parameters);
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
IDbCommand result = Query(dbcon, sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
@ -927,13 +890,18 @@ namespace OpenSim.Data.MySQL
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
IDbCommand result = Query(dbcon, sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
@ -1030,7 +998,11 @@ namespace OpenSim.Data.MySQL
try
{
IDbCommand result = Query(sql, parameters);
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
IDbCommand result = Query(dbcon, sql, parameters);
// int x;
// if ((x = result.ExecuteNonQuery()) > 0)
@ -1043,6 +1015,7 @@ namespace OpenSim.Data.MySQL
}
result.Dispose();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
@ -1070,7 +1043,11 @@ namespace OpenSim.Data.MySQL
{
parameters["?uuid"] = uuid;
IDbCommand result = Query(sql, parameters);
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
IDbCommand result = Query(dbcon, sql, parameters);
// int x;
// if ((x = result.ExecuteNonQuery()) > 0)
@ -1083,6 +1060,7 @@ namespace OpenSim.Data.MySQL
}
result.Dispose();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
@ -1122,7 +1100,11 @@ namespace OpenSim.Data.MySQL
try
{
IDbCommand result = Query(sql, parameters);
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
IDbCommand result = Query(dbcon, sql, parameters);
// int x;
// if ((x = result.ExecuteNonQuery()) > 0)
@ -1135,6 +1117,7 @@ namespace OpenSim.Data.MySQL
}
result.Dispose();
}
}
catch (Exception e)
{
m_log.Error(e.ToString());
@ -1167,8 +1150,14 @@ namespace OpenSim.Data.MySQL
bool returnval = false;
// we want to send in byte data, which means we can't just pass down strings
try {
MySqlCommand cmd = (MySqlCommand) dbcon.CreateCommand();
try
{
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("?owner", appearance.Owner.ToString());
cmd.Parameters.AddWithValue("?serial", appearance.Serial);
@ -1204,8 +1193,8 @@ namespace OpenSim.Data.MySQL
if (cmd.ExecuteNonQuery() > 0)
returnval = true;
cmd.Dispose();
}
}
}
catch (Exception e)
{
@ -1221,7 +1210,11 @@ namespace OpenSim.Data.MySQL
{
string sql = "delete from avatarattachments where UUID = ?uuid";
MySqlCommand cmd = (MySqlCommand) dbcon.CreateCommand();
using (MySqlConnection dbcon = new MySqlConnection(connectionString))
{
dbcon.Open();
MySqlCommand cmd = (MySqlCommand)dbcon.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("?uuid", agentID.ToString());
@ -1232,7 +1225,7 @@ namespace OpenSim.Data.MySQL
sql = "insert into avatarattachments (UUID, attachpoint, item, asset) values (?uuid, ?attachpoint, ?item, ?asset)";
cmd = (MySqlCommand) dbcon.CreateCommand();
cmd = (MySqlCommand)dbcon.CreateCommand();
cmd.CommandText = sql;
foreach (DictionaryEntry e in data)
@ -1251,4 +1244,5 @@ namespace OpenSim.Data.MySQL
}
}
}
}
}

View File

@ -123,7 +123,8 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?UserID", userID);
IDataReader reader = ExecuteReader(cmd);
using (IDataReader reader = cmd.ExecuteReader())
{
List<UUID> deleteSessions = new List<UUID>();
int online = 0;
@ -139,11 +140,9 @@ namespace OpenSim.Data.MySQL
if (online == 0 && deleteSessions.Count > 0)
deleteSessions.RemoveAt(0);
reader.Close();
CloseReaderCommand(cmd);
foreach (UUID s in deleteSessions)
Delete("SessionID", s.ToString());
}
}
}
}

View File

@ -38,17 +38,22 @@ namespace OpenSim.Data.MySQL
public class MySqlRegionData : MySqlFramework, IRegionData
{
private string m_Realm;
private List<string> m_ColumnNames = null;
// private int m_LastExpire = 0;
private List<string> m_ColumnNames;
//private string m_connectionString;
public MySqlRegionData(string connectionString, string realm)
: base(connectionString)
{
m_Realm = realm;
m_connectionString = connectionString;
Migration m = new Migration(m_Connection, GetType().Assembly, "GridStore");
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Migration m = new Migration(dbcon, GetType().Assembly, "GridStore");
m.Update();
}
}
public List<RegionData> Get(string regionName, UUID scopeID)
{
@ -56,13 +61,14 @@ namespace OpenSim.Data.MySQL
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
MySqlCommand cmd = new MySqlCommand(command);
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?regionName", regionName);
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
return RunCommand(cmd);
}
}
public RegionData Get(int posX, int posY, UUID scopeID)
{
@ -70,8 +76,8 @@ namespace OpenSim.Data.MySQL
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
MySqlCommand cmd = new MySqlCommand(command);
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?posX", posX.ToString());
cmd.Parameters.AddWithValue("?posY", posY.ToString());
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
@ -82,6 +88,7 @@ namespace OpenSim.Data.MySQL
return ret[0];
}
}
public RegionData Get(UUID regionID, UUID scopeID)
{
@ -89,8 +96,8 @@ namespace OpenSim.Data.MySQL
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
MySqlCommand cmd = new MySqlCommand(command);
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
@ -100,6 +107,7 @@ namespace OpenSim.Data.MySQL
return ret[0];
}
}
public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
{
@ -107,8 +115,8 @@ namespace OpenSim.Data.MySQL
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
MySqlCommand cmd = new MySqlCommand(command);
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?startX", startX.ToString());
cmd.Parameters.AddWithValue("?startY", startY.ToString());
cmd.Parameters.AddWithValue("?endX", endX.ToString());
@ -117,13 +125,19 @@ namespace OpenSim.Data.MySQL
return RunCommand(cmd);
}
}
public List<RegionData> RunCommand(MySqlCommand cmd)
{
List<RegionData> retList = new List<RegionData>();
IDataReader result = ExecuteReader(cmd);
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
cmd.Connection = dbcon;
using (IDataReader result = cmd.ExecuteReader())
{
while (result.Read())
{
RegionData ret = new RegionData();
@ -171,9 +185,8 @@ namespace OpenSim.Data.MySQL
retList.Add(ret);
}
result.Close();
CloseReaderCommand(cmd);
}
}
return retList;
}
@ -201,15 +214,15 @@ namespace OpenSim.Data.MySQL
string[] fields = new List<string>(data.Data.Keys).ToArray();
MySqlCommand cmd = new MySqlCommand();
string update = "update `"+m_Realm+"` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY";
using (MySqlCommand cmd = new MySqlCommand())
{
string update = "update `" + m_Realm + "` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY";
foreach (string field in fields)
{
update += ", ";
update += "`" + field + "` = ?"+field;
update += "`" + field + "` = ?" + field;
cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
cmd.Parameters.AddWithValue("?" + field, data.Data[field]);
}
update += " where uuid = ?regionID";
@ -236,41 +249,37 @@ namespace OpenSim.Data.MySQL
if (ExecuteNonQuery(cmd) < 1)
{
cmd.Dispose();
return false;
}
}
cmd.Dispose();
}
return true;
}
public bool SetDataItem(UUID regionID, string item, string value)
{
MySqlCommand cmd = new MySqlCommand("update `" + m_Realm +
"` set `" + item + "` = ?" + item + " where uuid = ?UUID");
cmd.Parameters.AddWithValue("?"+item, value);
using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where uuid = ?UUID"))
{
cmd.Parameters.AddWithValue("?" + item, value);
cmd.Parameters.AddWithValue("?UUID", regionID.ToString());
if (ExecuteNonQuery(cmd) > 0)
return true;
}
return false;
}
public bool Delete(UUID regionID)
{
MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm +
"` where uuid = ?UUID");
using (MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + "` where uuid = ?UUID"))
{
cmd.Parameters.AddWithValue("?UUID", regionID.ToString());
if (ExecuteNonQuery(cmd) > 0)
return true;
}
return false;
}

View File

@ -33,6 +33,7 @@ using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using log4net;
using MySql.Data.MySqlClient;
using OpenMetaverse;
using OpenSim.Framework;
@ -45,15 +46,9 @@ namespace OpenSim.Data.MySQL
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Database manager for MySQL
/// </summary>
public MySQLManager database;
/// <summary>
/// Better DB manager. Swap-in replacement too.
/// </summary>
public Dictionary<int, MySQLSuperManager> m_dbconnections = new Dictionary<int, MySQLSuperManager>();
private MySQLManager m_database;
private string m_connectionString;
private object m_dbLock = new object();
public int m_maxConnections = 10;
public int m_lastConnect;
@ -63,7 +58,6 @@ namespace OpenSim.Data.MySQL
private string m_userFriendsTableName = "userfriends";
private string m_appearanceTableName = "avatarappearance";
private string m_attachmentsTableName = "avatarattachments";
private string m_connectString;
public override void Initialise()
{
@ -71,41 +65,6 @@ namespace OpenSim.Data.MySQL
throw new PluginNotInitialisedException(Name);
}
public MySQLSuperManager GetLockedConnection(string why)
{
int lockedCons = 0;
while (true)
{
m_lastConnect++;
// Overflow protection
if (m_lastConnect == int.MaxValue)
m_lastConnect = 0;
MySQLSuperManager x = m_dbconnections[m_lastConnect%m_maxConnections];
if (!x.Locked)
{
x.GetLock();
x.Running = why;
return x;
}
lockedCons++;
if (lockedCons > m_maxConnections)
{
lockedCons = 0;
Thread.Sleep(1000); // Wait some time before searching them again.
m_log.Debug(
"WARNING: All threads are in use. Probable cause: Something didnt release a mutex properly, or high volume of requests inbound.");
m_log.Debug("Current connections-in-use dump:");
foreach (KeyValuePair<int, MySQLSuperManager> kvp in m_dbconnections)
{
m_log.Debug(kvp.Value.Running);
}
}
}
}
/// <summary>
/// Initialise User Interface
/// Loads and initialises the MySQL storage plugin
@ -115,56 +74,19 @@ namespace OpenSim.Data.MySQL
/// <param name="connect">connect string.</param>
public override void Initialise(string connect)
{
if (connect == String.Empty)
{
// TODO: actually do something with our connect string
// instead of loading the second config
m_log.Warn("Using obsoletely mysql_connection.ini, try using user_source connect string instead");
IniFile iniFile = new IniFile("mysql_connection.ini");
string settingHostname = iniFile.ParseFileReadValue("hostname");
string settingDatabase = iniFile.ParseFileReadValue("database");
string settingUsername = iniFile.ParseFileReadValue("username");
string settingPassword = iniFile.ParseFileReadValue("password");
string settingPooling = iniFile.ParseFileReadValue("pooling");
string settingPort = iniFile.ParseFileReadValue("port");
m_connectString = "Server=" + settingHostname + ";Port=" + settingPort + ";Database=" + settingDatabase +
";User ID=" +
settingUsername + ";Password=" + settingPassword + ";Pooling=" + settingPooling + ";";
m_log.Info("Creating " + m_maxConnections + " DB connections...");
for (int i = 0; i < m_maxConnections; i++)
{
m_log.Info("Connecting to DB... [" + i + "]");
MySQLSuperManager msm = new MySQLSuperManager();
msm.Manager = new MySQLManager(m_connectString);
m_dbconnections.Add(i, msm);
}
database = new MySQLManager(m_connectString);
}
else
{
m_connectString = connect;
database = new MySQLManager(m_connectString);
m_log.Info("Creating " + m_maxConnections + " DB connections...");
for (int i = 0; i < m_maxConnections; i++)
{
m_log.Info("Connecting to DB... [" + i + "]");
MySQLSuperManager msm = new MySQLSuperManager();
msm.Manager = new MySQLManager(m_connectString);
m_dbconnections.Add(i, msm);
}
}
m_connectionString = connect;
m_database = new MySQLManager(connect);
// This actually does the roll forward assembly stuff
Assembly assem = GetType().Assembly;
Migration m = new Migration(database.Connection, assem, "UserStore");
using (MySql.Data.MySqlClient.MySqlConnection dbcon = new MySql.Data.MySqlClient.MySqlConnection(m_connectionString))
{
dbcon.Open();
Migration m = new Migration(dbcon, assem, "UserStore");
m.Update();
}
}
public override void Dispose()
{
@ -173,35 +95,32 @@ namespace OpenSim.Data.MySQL
// see IUserDataPlugin
public override UserProfileData GetUserByName(string user, string last)
{
MySQLSuperManager dbm = GetLockedConnection("GetUserByName");
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?first"] = user;
param["?second"] = last;
IDbCommand result =
dbm.Manager.Query(
"SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param);
IDataReader reader = result.ExecuteReader();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
UserProfileData row = dbm.Manager.readUserRow(reader);
reader.Dispose();
result.Dispose();
using (IDbCommand result = m_database.Query(dbcon,
"SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param))
{
using (IDataReader reader = result.ExecuteReader())
{
UserProfileData row = m_database.readUserRow(reader);
return row;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
#region User Friends List Data
@ -216,38 +135,38 @@ namespace OpenSim.Data.MySQL
param["?friendPerms"] = perms.ToString();
param["?datetimestamp"] = dtvalue.ToString();
MySQLSuperManager dbm = GetLockedConnection("AddNewUserFriend");
try
{
IDbCommand adder =
dbm.Manager.Query(
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand adder = m_database.Query(dbcon,
"INSERT INTO `" + m_userFriendsTableName + "` " +
"(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
"VALUES " +
"(?ownerID,?friendID,?friendPerms,?datetimestamp)",
param);
param))
{
adder.ExecuteNonQuery();
}
adder =
dbm.Manager.Query(
using (IDbCommand adder = m_database.Query(dbcon,
"INSERT INTO `" + m_userFriendsTableName + "` " +
"(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
"VALUES " +
"(?friendID,?ownerID,?friendPerms,?datetimestamp)",
param);
param))
{
adder.ExecuteNonQuery();
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return;
}
finally
{
dbm.Release();
}
}
public override void RemoveUserFriend(UUID friendlistowner, UUID friend)
@ -256,32 +175,32 @@ namespace OpenSim.Data.MySQL
param["?ownerID"] = friendlistowner.ToString();
param["?friendID"] = friend.ToString();
MySQLSuperManager dbm = GetLockedConnection("RemoveUserFriend");
try
{
IDbCommand updater =
dbm.Manager.Query(
"delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID",
param);
updater.ExecuteNonQuery();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
updater =
dbm.Manager.Query(
"delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID",
param);
using (IDbCommand updater = m_database.Query(dbcon,
"delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID",
param))
{
updater.ExecuteNonQuery();
}
using (IDbCommand updater = m_database.Query(dbcon,
"delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID",
param))
{
updater.ExecuteNonQuery();
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return;
}
finally
{
dbm.Release();
}
}
public override void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms)
@ -291,28 +210,27 @@ namespace OpenSim.Data.MySQL
param["?friendID"] = friend.ToString();
param["?friendPerms"] = perms.ToString();
MySQLSuperManager dbm = GetLockedConnection("UpdateUserFriendPerms");
try
{
IDbCommand updater =
dbm.Manager.Query(
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand updater = m_database.Query(dbcon,
"update " + m_userFriendsTableName +
" SET friendPerms = ?friendPerms " +
"where ownerID = ?ownerID and friendID = ?friendID",
param);
param))
{
updater.ExecuteNonQuery();
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return;
}
finally
{
dbm.Release();
}
}
public override List<FriendListItem> GetUserFriendList(UUID friendlistowner)
@ -322,65 +240,66 @@ namespace OpenSim.Data.MySQL
Dictionary<string, object> param = new Dictionary<string, object>();
param["?ownerID"] = friendlistowner.ToString();
MySQLSuperManager dbm = GetLockedConnection("GetUserFriendList");
try
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
//Left Join userfriends to itself
IDbCommand result =
dbm.Manager.Query(
using (IDbCommand result = m_database.Query(dbcon,
"select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " +
m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" +
" where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID",
param);
IDataReader reader = result.ExecuteReader();
param))
{
using (IDataReader reader = result.ExecuteReader())
{
while (reader.Read())
{
FriendListItem fli = new FriendListItem();
fli.FriendListOwner = new UUID((string) reader["ownerID"]);
fli.Friend = new UUID((string) reader["friendID"]);
fli.FriendPerms = (uint) Convert.ToInt32(reader["friendPerms"]);
fli.FriendListOwner = new UUID((string)reader["ownerID"]);
fli.Friend = new UUID((string)reader["friendID"]);
fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]);
// This is not a real column in the database table, it's a joined column from the opposite record
fli.FriendListOwnerPerms = (uint) Convert.ToInt32(reader["ownerperms"]);
fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]);
Lfli.Add(fli);
}
reader.Dispose();
result.Dispose();
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return Lfli;
}
finally
{
dbm.Release();
}
return Lfli;
}
override public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos (List<UUID> uuids)
{
MySQLSuperManager dbm = GetLockedConnection("GetFriendRegionInfos");
Dictionary<UUID, FriendRegionInfo> infos = new Dictionary<UUID,FriendRegionInfo>();
try
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
foreach (UUID uuid in uuids)
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?uuid"] = uuid.ToString();
IDbCommand result =
dbm.Manager.Query("select agentOnline,currentHandle from " + m_agentsTableName +
" where UUID = ?uuid", param);
IDataReader reader = result.ExecuteReader();
using (IDbCommand result = m_database.Query(dbcon, "select agentOnline,currentHandle from " + m_agentsTableName +
" where UUID = ?uuid", param))
{
using (IDataReader reader = result.ExecuteReader())
{
while (reader.Read())
{
FriendRegionInfo fri = new FriendRegionInfo();
@ -389,20 +308,15 @@ namespace OpenSim.Data.MySQL
infos[uuid] = fri;
}
reader.Dispose();
result.Dispose();
}
}
}
}
}
catch (Exception e)
{
m_log.Warn("[MYSQL]: Got exception on trying to find friends regions:", e);
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
}
finally
{
dbm.Release();
m_log.Error(e.Message, e);
}
return infos;
@ -423,76 +337,73 @@ namespace OpenSim.Data.MySQL
Dictionary<string, object> param = new Dictionary<string, object>();
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%";
param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], String.Empty) + "%";
MySQLSuperManager dbm = GetLockedConnection("GeneratePickerResults");
try
{
IDbCommand result =
dbm.Manager.Query(
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon,
"SELECT UUID,username,lastname FROM " + m_usersTableName +
" WHERE username like ?first AND lastname like ?second LIMIT 100",
param);
IDataReader reader = result.ExecuteReader();
param))
{
using (IDataReader reader = result.ExecuteReader())
{
while (reader.Read())
{
AvatarPickerAvatar user = new AvatarPickerAvatar();
user.AvatarID = new UUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["lastname"];
user.AvatarID = new UUID((string)reader["UUID"]);
user.firstName = (string)reader["username"];
user.lastName = (string)reader["lastname"];
returnlist.Add(user);
}
reader.Dispose();
result.Dispose();
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return returnlist;
}
finally
{
dbm.Release();
}
}
else
{
MySQLSuperManager dbm = GetLockedConnection("GeneratePickerResults");
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%";
IDbCommand result =
dbm.Manager.Query(
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon,
"SELECT UUID,username,lastname FROM " + m_usersTableName +
" WHERE username like ?first OR lastname like ?first LIMIT 100",
param);
IDataReader reader = result.ExecuteReader();
param))
{
using (IDataReader reader = result.ExecuteReader())
{
while (reader.Read())
{
AvatarPickerAvatar user = new AvatarPickerAvatar();
user.AvatarID = new UUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["lastname"];
user.AvatarID = new UUID((string)reader["UUID"]);
user.firstName = (string)reader["username"];
user.lastName = (string)reader["lastname"];
returnlist.Add(user);
}
reader.Dispose();
result.Dispose();
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return returnlist;
}
finally
{
dbm.Release();
}
}
return returnlist;
}
@ -504,32 +415,30 @@ namespace OpenSim.Data.MySQL
/// <returns>User profile data</returns>
public override UserProfileData GetUserByUUID(UUID uuid)
{
MySQLSuperManager dbm = GetLockedConnection("GetUserByUUID");
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?uuid"] = uuid.ToString();
IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = dbm.Manager.readUserRow(reader);
reader.Dispose();
result.Dispose();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param))
{
using (IDataReader reader = result.ExecuteReader())
{
UserProfileData row = m_database.readUserRow(reader);
return row;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
/// <summary>
@ -565,25 +474,18 @@ namespace OpenSim.Data.MySQL
param["?UUID"] = AgentID.ToString();
param["?webLoginKey"] = WebLoginKey.ToString();
MySQLSuperManager dbm = GetLockedConnection("StoreWebLoginKey");
try
{
dbm.Manager.ExecuteParameterizedSql(
m_database.ExecuteParameterizedSql(
"update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " +
"where UUID = ?UUID",
param);
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return;
}
finally
{
dbm.Release();
}
}
/// <summary>
@ -593,34 +495,30 @@ namespace OpenSim.Data.MySQL
/// <returns>The users session</returns>
public override UserAgentData GetAgentByUUID(UUID uuid)
{
MySQLSuperManager dbm = GetLockedConnection("GetAgentByUUID");
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?uuid"] = uuid.ToString();
IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid",
param);
IDataReader reader = result.ExecuteReader();
UserAgentData row = dbm.Manager.readAgentRow(reader);
reader.Dispose();
result.Dispose();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", param))
{
using (IDataReader reader = result.ExecuteReader())
{
UserAgentData row = m_database.readAgentRow(reader);
return row;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
/// <summary>
@ -634,11 +532,11 @@ namespace OpenSim.Data.MySQL
{
return;
}
MySQLSuperManager dbm = GetLockedConnection("AddNewUserProfile");
try
{
dbm.Manager.insertUserRow(user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
m_database.insertUserRow(
user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y,
user.HomeLocation.Z,
user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created,
@ -649,12 +547,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
}
finally
{
dbm.Release();
m_log.Error(e.Message, e);
}
}
@ -668,19 +561,13 @@ namespace OpenSim.Data.MySQL
if (agent.ProfileID == zero || agent.SessionID == zero)
return;
MySQLSuperManager dbm = GetLockedConnection("AddNewUserAgent");
try
{
dbm.Manager.insertAgentRow(agent);
m_database.insertAgentRow(agent);
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
}
finally
{
dbm.Release();
m_log.Error(e.Message, e);
}
}
@ -690,10 +577,10 @@ namespace OpenSim.Data.MySQL
/// <param name="user">The profile data to use to update the DB</param>
public override bool UpdateUserProfile(UserProfileData user)
{
MySQLSuperManager dbm = GetLockedConnection("UpdateUserProfile");
try
{
dbm.Manager.updateUserRow(user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
m_database.updateUserRow(
user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y,
user.HomeLocation.Z, user.HomeLookAt.X,
user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, user.LastLogin,
@ -701,14 +588,14 @@ namespace OpenSim.Data.MySQL
user.UserAssetURI, user.CanDoMask, user.WantDoMask, user.AboutText,
user.FirstLifeAboutText, user.Image, user.FirstLifeImage, user.WebLoginKey,
user.UserFlags, user.GodLevel, user.CustomType, user.Partner);
}
finally
{
dbm.Release();
}
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Performs a money transfer request between two accounts
@ -742,41 +629,40 @@ namespace OpenSim.Data.MySQL
/// </summary>
public override AvatarAppearance GetUserAppearance(UUID user)
{
MySQLSuperManager dbm = GetLockedConnection("GetUserAppearance");
try
{
Dictionary<string, object> param = new Dictionary<string, object>();
param["?owner"] = user.ToString();
IDbCommand result = dbm.Manager.Query(
"SELECT * FROM " + m_appearanceTableName + " WHERE owner = ?owner", param);
IDataReader reader = result.ExecuteReader();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
AvatarAppearance appearance = dbm.Manager.readAppearanceRow(reader);
using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_appearanceTableName + " WHERE owner = ?owner", param))
{
using (IDataReader reader = result.ExecuteReader())
{
AvatarAppearance appearance = m_database.readAppearanceRow(reader);
reader.Dispose();
result.Dispose();
if (null == appearance)
if (appearance == null)
{
m_log.WarnFormat("[USER DB] No appearance found for user {0}", user.ToString());
return null;
}
else
{
appearance.SetAttachments(GetUserAttachments(user));
return appearance;
}
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
/// <summary>
@ -787,22 +673,16 @@ namespace OpenSim.Data.MySQL
// override
public override void UpdateUserAppearance(UUID user, AvatarAppearance appearance)
{
MySQLSuperManager dbm = GetLockedConnection("UpdateUserAppearance");
try
{
appearance.Owner = user;
dbm.Manager.insertAppearanceRow(appearance);
m_database.insertAppearanceRow(appearance);
UpdateUserAttachments(user, appearance.GetAttachments());
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
}
finally
{
dbm.Release();
m_log.Error(e.Message, e);
}
}
@ -829,43 +709,33 @@ namespace OpenSim.Data.MySQL
Dictionary<string, object> param = new Dictionary<string, object>();
param["?uuid"] = agentID.ToString();
MySQLSuperManager dbm = GetLockedConnection("GetUserAttachments");
try
{
IDbCommand result = dbm.Manager.Query(
"SELECT attachpoint, item, asset from " + m_attachmentsTableName + " WHERE UUID = ?uuid", param);
IDataReader reader = result.ExecuteReader();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Hashtable ret = dbm.Manager.readAttachments(reader);
reader.Dispose();
result.Dispose();
using (IDbCommand result = m_database.Query(dbcon,
"SELECT attachpoint, item, asset from " + m_attachmentsTableName + " WHERE UUID = ?uuid", param))
{
using (IDataReader reader = result.ExecuteReader())
{
Hashtable ret = m_database.readAttachments(reader);
return ret;
}
}
}
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return null;
}
finally
{
dbm.Release();
}
}
public void UpdateUserAttachments(UUID agentID, Hashtable data)
{
MySQLSuperManager dbm = GetLockedConnection("UpdateUserAttachments");
try
{
dbm.Manager.writeAttachments(agentID, data);
}
finally
{
dbm.Release();
}
m_database.writeAttachments(agentID, data);
}
public override void ResetAttachments(UUID userID)
@ -873,45 +743,29 @@ namespace OpenSim.Data.MySQL
Dictionary<string, string> param = new Dictionary<string, string>();
param["?uuid"] = userID.ToString();
MySQLSuperManager dbm = GetLockedConnection("ResetAttachments");
try
{
dbm.Manager.ExecuteParameterizedSql(
m_database.ExecuteParameterizedSql(
"UPDATE " + m_attachmentsTableName +
" SET asset = '00000000-0000-0000-0000-000000000000' WHERE UUID = ?uuid",
param);
}
finally
{
dbm.Release();
}
}
public override void LogoutUsers(UUID regionID)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?regionID"] = regionID.ToString();
MySQLSuperManager dbm = GetLockedConnection("LogoutUsers");
try
{
dbm.Manager.ExecuteParameterizedSql(
m_database.ExecuteParameterizedSql(
"update " + m_agentsTableName + " SET agentOnline = 0 " +
"where currentRegion = ?regionID",
param);
}
catch (Exception e)
{
dbm.Manager.Reconnect();
m_log.Error(e.ToString());
m_log.Error(e.Message, e);
return;
}
finally
{
dbm.Release();
}
}
}
}

View File

@ -110,7 +110,8 @@ namespace OpenSim.Data.MySQL
public bool MoveItem(string id, string newParent)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm);
cmd.Parameters.AddWithValue("?ParentFolderID", newParent);
@ -118,10 +119,12 @@ namespace OpenSim.Data.MySQL
return ExecuteNonQuery(cmd) == 0 ? false : true;
}
}
public XInventoryItem[] GetActiveGestures(UUID principalID)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags = 1", m_Realm);
cmd.Parameters.AddWithValue("?uuid", principalID.ToString());
@ -129,16 +132,24 @@ namespace OpenSim.Data.MySQL
return DoQuery(cmd);
}
}
public int GetAssetPermissions(UUID principalID, UUID assetID)
{
MySqlCommand cmd = new MySqlCommand();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = dbcon;
cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue("?AssetID", assetID.ToString());
IDataReader reader = ExecuteReader(cmd);
using (IDataReader reader = cmd.ExecuteReader())
{
int perms = 0;
@ -147,10 +158,10 @@ namespace OpenSim.Data.MySQL
perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]);
}
reader.Close();
CloseReaderCommand(cmd);
return perms;
}
}
}
}
}
}

View File

@ -31,6 +31,7 @@ using OpenSim.Data.Tests;
using log4net;
using System.Reflection;
using OpenSim.Tests.Common;
using MySql.Data.MySqlClient;
namespace OpenSim.Data.MySQL.Tests
{
@ -65,10 +66,14 @@ namespace OpenSim.Data.MySQL.Tests
// This actually does the roll forward assembly stuff
Assembly assem = GetType().Assembly;
Migration m = new Migration(database.Connection, assem, "GridStore");
using (MySqlConnection dbcon = new MySqlConnection(connect))
{
dbcon.Open();
Migration m = new Migration(dbcon, assem, "AssetStore");
m.Update();
}
}
[TestFixtureTearDown]
public void Cleanup()

View File

@ -41,7 +41,7 @@ namespace OpenSim.Data.SQLite
/// </summary>
public class SQLiteAssetData : AssetDataBase
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private const string SelectAssetSQL = "select * from assets where UUID=:UUID";
private const string SelectAssetMetadataSQL = "select Name, Description, Type, Temporary, UUID from assets limit :start, :count";

View File

@ -39,9 +39,7 @@ namespace OpenSim.Data.SQLite
{
public class SQLiteGenericTableHandler<T> : SQLiteFramework where T: class, new()
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Dictionary<string, FieldInfo> m_Fields =
new Dictionary<string, FieldInfo>();

View File

@ -41,8 +41,7 @@ namespace OpenSim.Data.SQLite
/// </summary>
public class SQLiteXInventoryData : IXInventoryData
{
private static readonly ILog m_log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private SQLiteGenericTableHandler<XInventoryFolder> m_Folders;
private SqliteItemHandler m_Items;

View File

@ -0,0 +1,755 @@
/*
* 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.IO;
using System.Net;
using System.Reflection;
using System.Text;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using log4net;
namespace OpenSim.Framework.Communications.Clients
{
public class RegionClient
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public bool DoCreateChildAgentCall(GridRegion region, AgentCircuitData aCircuit, string authKey, uint teleportFlags, out string reason)
{
reason = String.Empty;
// Eventually, we want to use a caps url instead of the agentID
string uri = string.Empty;
try
{
uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + aCircuit.AgentID + "/";
}
catch (Exception e)
{
m_log.Debug("[REST COMMS]: Unable to resolve external endpoint on agent create. Reason: " + e.Message);
reason = e.Message;
return false;
}
//Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri);
HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
AgentCreateRequest.Method = "POST";
AgentCreateRequest.ContentType = "application/json";
AgentCreateRequest.Timeout = 10000;
//AgentCreateRequest.KeepAlive = false;
AgentCreateRequest.Headers.Add("Authorization", authKey);
// Fill it in
OSDMap args = null;
try
{
args = aCircuit.PackAgentCircuitData();
}
catch (Exception e)
{
m_log.Debug("[REST COMMS]: PackAgentCircuitData failed with exception: " + e.Message);
}
// Add the regionhandle of the destination region
ulong regionHandle = GetRegionHandle(region.RegionHandle);
args["destination_handle"] = OSD.FromString(regionHandle.ToString());
args["teleport_flags"] = OSD.FromString(teleportFlags.ToString());
string strBuffer = "";
byte[] buffer = new byte[1];
try
{
strBuffer = OSDParser.SerializeJsonString(args);
Encoding str = Util.UTF8;
buffer = str.GetBytes(strBuffer);
}
catch (Exception e)
{
m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
// ignore. buffer will be empty, caller should check.
}
Stream os = null;
try
{ // send the Post
AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
os = AgentCreateRequest.GetRequestStream();
os.Write(buffer, 0, strBuffer.Length); //Send it
//m_log.InfoFormat("[REST COMMS]: Posted CreateChildAgent request to remote sim {0}", uri);
}
//catch (WebException ex)
catch
{
//m_log.InfoFormat("[REST COMMS]: Bad send on ChildAgentUpdate {0}", ex.Message);
reason = "cannot contact remote region";
return false;
}
finally
{
if (os != null)
os.Close();
}
// Let's wait for the response
//m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall");
WebResponse webResponse = null;
StreamReader sr = null;
try
{
webResponse = AgentCreateRequest.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on DoCreateChildAgentCall post");
}
else
{
sr = new StreamReader(webResponse.GetResponseStream());
string response = sr.ReadToEnd().Trim();
m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", response);
if (!String.IsNullOrEmpty(response))
{
try
{
// we assume we got an OSDMap back
OSDMap r = GetOSDMap(response);
bool success = r["success"].AsBoolean();
reason = r["reason"].AsString();
return success;
}
catch (NullReferenceException e)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
// check for old style response
if (response.ToLower().StartsWith("true"))
return true;
return false;
}
}
}
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
// ignore, really
}
finally
{
if (sr != null)
sr.Close();
}
return true;
}
public bool DoChildAgentUpdateCall(GridRegion region, IAgentData cAgentData)
{
// Eventually, we want to use a caps url instead of the agentID
string uri = string.Empty;
try
{
uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + cAgentData.AgentID + "/";
}
catch (Exception e)
{
m_log.Debug("[REST COMMS]: Unable to resolve external endpoint on agent update. Reason: " + e.Message);
return false;
}
//Console.WriteLine(" >>> DoChildAgentUpdateCall <<< " + uri);
HttpWebRequest ChildUpdateRequest = (HttpWebRequest)WebRequest.Create(uri);
ChildUpdateRequest.Method = "PUT";
ChildUpdateRequest.ContentType = "application/json";
ChildUpdateRequest.Timeout = 10000;
//ChildUpdateRequest.KeepAlive = false;
// Fill it in
OSDMap args = null;
try
{
args = cAgentData.Pack();
}
catch (Exception e)
{
m_log.Debug("[REST COMMS]: PackUpdateMessage failed with exception: " + e.Message);
}
// Add the regionhandle of the destination region
ulong regionHandle = GetRegionHandle(region.RegionHandle);
args["destination_handle"] = OSD.FromString(regionHandle.ToString());
string strBuffer = "";
byte[] buffer = new byte[1];
try
{
strBuffer = OSDParser.SerializeJsonString(args);
Encoding str = Util.UTF8;
buffer = str.GetBytes(strBuffer);
}
catch (Exception e)
{
m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of ChildUpdate: {0}", e.Message);
// ignore. buffer will be empty, caller should check.
}
Stream os = null;
try
{ // send the Post
ChildUpdateRequest.ContentLength = buffer.Length; //Count bytes to send
os = ChildUpdateRequest.GetRequestStream();
os.Write(buffer, 0, strBuffer.Length); //Send it
//m_log.InfoFormat("[REST COMMS]: Posted ChildAgentUpdate request to remote sim {0}", uri);
}
//catch (WebException ex)
catch
{
//m_log.InfoFormat("[REST COMMS]: Bad send on ChildAgentUpdate {0}", ex.Message);
return false;
}
finally
{
if (os != null)
os.Close();
}
// Let's wait for the response
//m_log.Info("[REST COMMS]: Waiting for a reply after ChildAgentUpdate");
WebResponse webResponse = null;
StreamReader sr = null;
try
{
webResponse = ChildUpdateRequest.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on ChilAgentUpdate post");
}
sr = new StreamReader(webResponse.GetResponseStream());
//reply = sr.ReadToEnd().Trim();
sr.ReadToEnd().Trim();
sr.Close();
//m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply);
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of ChilAgentUpdate {0}", ex.Message);
// ignore, really
}
finally
{
if (sr != null)
sr.Close();
}
return true;
}
public bool DoRetrieveRootAgentCall(GridRegion region, UUID id, out IAgentData agent)
{
agent = null;
// Eventually, we want to use a caps url instead of the agentID
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() + "/";
//Console.WriteLine(" >>> DoRetrieveRootAgentCall <<< " + uri);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.Timeout = 10000;
//request.Headers.Add("authorization", ""); // coming soon
HttpWebResponse webResponse = null;
string reply = string.Empty;
StreamReader sr = null;
try
{
webResponse = (HttpWebResponse)request.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on agent get ");
}
sr = new StreamReader(webResponse.GetResponseStream());
reply = sr.ReadToEnd().Trim();
//Console.WriteLine("[REST COMMS]: ChilAgentUpdate reply was " + reply);
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message);
// ignore, really
return false;
}
finally
{
if (sr != null)
sr.Close();
}
if (webResponse.StatusCode == HttpStatusCode.OK)
{
// we know it's jason
OSDMap args = GetOSDMap(reply);
if (args == null)
{
//Console.WriteLine("[REST COMMS]: Error getting OSDMap from reply");
return false;
}
agent = new CompleteAgentData();
agent.Unpack(args);
return true;
}
//Console.WriteLine("[REST COMMS]: DoRetrieveRootAgentCall returned status " + webResponse.StatusCode);
return false;
}
public bool DoReleaseAgentCall(ulong regionHandle, UUID id, string uri)
{
//m_log.Debug(" >>> DoReleaseAgentCall <<< " + uri);
WebRequest request = WebRequest.Create(uri);
request.Method = "DELETE";
request.Timeout = 10000;
StreamReader sr = null;
try
{
WebResponse webResponse = request.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on agent delete ");
}
sr = new StreamReader(webResponse.GetResponseStream());
//reply = sr.ReadToEnd().Trim();
sr.ReadToEnd().Trim();
sr.Close();
//m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply);
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of agent delete {0}", ex.Message);
// ignore, really
}
finally
{
if (sr != null)
sr.Close();
}
return true;
}
public bool DoCloseAgentCall(GridRegion region, UUID id)
{
string uri = string.Empty;
try
{
uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() + "/";
}
catch (Exception e)
{
m_log.Debug("[REST COMMS]: Unable to resolve external endpoint on agent close. Reason: " + e.Message);
return false;
}
//Console.WriteLine(" >>> DoCloseAgentCall <<< " + uri);
WebRequest request = WebRequest.Create(uri);
request.Method = "DELETE";
request.Timeout = 10000;
StreamReader sr = null;
try
{
WebResponse webResponse = request.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on agent delete ");
}
sr = new StreamReader(webResponse.GetResponseStream());
//reply = sr.ReadToEnd().Trim();
sr.ReadToEnd().Trim();
sr.Close();
//m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply);
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of agent delete {0}", ex.Message);
// ignore, really
}
finally
{
if (sr != null)
sr.Close();
}
return true;
}
public bool DoCreateObjectCall(GridRegion region, ISceneObject sog, string sogXml2, bool allowScriptCrossing)
{
ulong regionHandle = GetRegionHandle(region.RegionHandle);
string uri
= "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort
+ "/object/" + sog.UUID + "/" + regionHandle.ToString() + "/";
//m_log.Debug(" >>> DoCreateChildAgentCall <<< " + uri);
WebRequest ObjectCreateRequest = WebRequest.Create(uri);
ObjectCreateRequest.Method = "POST";
ObjectCreateRequest.ContentType = "application/json";
ObjectCreateRequest.Timeout = 10000;
OSDMap args = new OSDMap(2);
args["sog"] = OSD.FromString(sogXml2);
args["extra"] = OSD.FromString(sog.ExtraToXmlString());
if (allowScriptCrossing)
{
string state = sog.GetStateSnapshot();
if (state.Length > 0)
args["state"] = OSD.FromString(state);
}
string strBuffer = "";
byte[] buffer = new byte[1];
try
{
strBuffer = OSDParser.SerializeJsonString(args);
Encoding str = Util.UTF8;
buffer = str.GetBytes(strBuffer);
}
catch (Exception e)
{
m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message);
// ignore. buffer will be empty, caller should check.
}
Stream os = null;
try
{ // send the Post
ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send
os = ObjectCreateRequest.GetRequestStream();
os.Write(buffer, 0, strBuffer.Length); //Send it
m_log.InfoFormat("[REST COMMS]: Posted ChildAgentUpdate request to remote sim {0}", uri);
}
//catch (WebException ex)
catch
{
// m_log.InfoFormat("[REST COMMS]: Bad send on CreateObject {0}", ex.Message);
return false;
}
finally
{
if (os != null)
os.Close();
}
// Let's wait for the response
//m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall");
StreamReader sr = null;
try
{
WebResponse webResponse = ObjectCreateRequest.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on DoCreateObjectCall post");
}
sr = new StreamReader(webResponse.GetResponseStream());
//reply = sr.ReadToEnd().Trim();
sr.ReadToEnd().Trim();
//m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", reply);
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateObjectCall {0}", ex.Message);
// ignore, really
}
finally
{
if (sr != null)
sr.Close();
}
return true;
}
public bool DoCreateObjectCall(GridRegion region, UUID userID, UUID itemID)
{
ulong regionHandle = GetRegionHandle(region.RegionHandle);
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/object/" + UUID.Zero + "/" + regionHandle.ToString() + "/";
//m_log.Debug(" >>> DoCreateChildAgentCall <<< " + uri);
WebRequest ObjectCreateRequest = WebRequest.Create(uri);
ObjectCreateRequest.Method = "PUT";
ObjectCreateRequest.ContentType = "application/json";
ObjectCreateRequest.Timeout = 10000;
OSDMap args = new OSDMap(2);
args["userid"] = OSD.FromUUID(userID);
args["itemid"] = OSD.FromUUID(itemID);
string strBuffer = "";
byte[] buffer = new byte[1];
try
{
strBuffer = OSDParser.SerializeJsonString(args);
Encoding str = Util.UTF8;
buffer = str.GetBytes(strBuffer);
}
catch (Exception e)
{
m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message);
// ignore. buffer will be empty, caller should check.
}
Stream os = null;
try
{ // send the Post
ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send
os = ObjectCreateRequest.GetRequestStream();
os.Write(buffer, 0, strBuffer.Length); //Send it
//m_log.InfoFormat("[REST COMMS]: Posted CreateObject request to remote sim {0}", uri);
}
//catch (WebException ex)
catch
{
// m_log.InfoFormat("[REST COMMS]: Bad send on CreateObject {0}", ex.Message);
return false;
}
finally
{
if (os != null)
os.Close();
}
// Let's wait for the response
//m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall");
StreamReader sr = null;
try
{
WebResponse webResponse = ObjectCreateRequest.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on DoCreateObjectCall post");
}
sr = new StreamReader(webResponse.GetResponseStream());
sr.ReadToEnd().Trim();
sr.ReadToEnd().Trim();
//m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", reply);
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateObjectCall {0}", ex.Message);
// ignore, really
}
finally
{
if (sr != null)
sr.Close();
}
return true;
}
public bool DoHelloNeighbourCall(RegionInfo region, RegionInfo thisRegion)
{
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/region/" + thisRegion.RegionID + "/";
//m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri);
WebRequest HelloNeighbourRequest = WebRequest.Create(uri);
HelloNeighbourRequest.Method = "POST";
HelloNeighbourRequest.ContentType = "application/json";
HelloNeighbourRequest.Timeout = 10000;
// Fill it in
OSDMap args = null;
try
{
args = thisRegion.PackRegionInfoData();
}
catch (Exception e)
{
m_log.Debug("[REST COMMS]: PackRegionInfoData failed with exception: " + e.Message);
}
// Add the regionhandle of the destination region
ulong regionHandle = GetRegionHandle(region.RegionHandle);
args["destination_handle"] = OSD.FromString(regionHandle.ToString());
string strBuffer = "";
byte[] buffer = new byte[1];
try
{
strBuffer = OSDParser.SerializeJsonString(args);
Encoding str = Util.UTF8;
buffer = str.GetBytes(strBuffer);
}
catch (Exception e)
{
m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of HelloNeighbour: {0}", e.Message);
// ignore. buffer will be empty, caller should check.
}
Stream os = null;
try
{ // send the Post
HelloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send
os = HelloNeighbourRequest.GetRequestStream();
os.Write(buffer, 0, strBuffer.Length); //Send it
//m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri);
}
//catch (WebException ex)
catch
{
//m_log.InfoFormat("[REST COMMS]: Bad send on HelloNeighbour {0}", ex.Message);
return false;
}
finally
{
if (os != null)
os.Close();
}
// Let's wait for the response
//m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall");
StreamReader sr = null;
try
{
WebResponse webResponse = HelloNeighbourRequest.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on DoHelloNeighbourCall post");
}
sr = new StreamReader(webResponse.GetResponseStream());
//reply = sr.ReadToEnd().Trim();
sr.ReadToEnd().Trim();
//m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply);
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of DoHelloNeighbourCall {0}", ex.Message);
// ignore, really
}
finally
{
if (sr != null)
sr.Close();
}
return true;
}
#region Hyperlinks
public virtual ulong GetRegionHandle(ulong handle)
{
return handle;
}
public virtual bool IsHyperlink(ulong handle)
{
return false;
}
public virtual void SendUserInformation(GridRegion regInfo, AgentCircuitData aCircuit)
{
}
public virtual void AdjustUserInformation(AgentCircuitData aCircuit)
{
}
#endregion /* Hyperlinks */
public static OSDMap GetOSDMap(string data)
{
OSDMap args = null;
try
{
OSD buffer;
// We should pay attention to the content-type, but let's assume we know it's Json
buffer = OSDParser.DeserializeJson(data);
if (buffer.Type == OSDType.Map)
{
args = (OSDMap)buffer;
return args;
}
else
{
// uh?
System.Console.WriteLine("[REST COMMS]: Got OSD of type " + buffer.Type.ToString());
return null;
}
}
catch (Exception ex)
{
System.Console.WriteLine("[REST COMMS]: exception on parse of REST message " + ex.Message);
return null;
}
}
}
}

2
OpenSim/Framework/Console/ConsoleBase.cs Normal file → Executable file
View File

@ -73,7 +73,7 @@ namespace OpenSim.Framework.Console
public virtual void Output(string text)
{
System.Console.Write(text);
System.Console.WriteLine(text);
}
public string CmdPrompt(string p)

2
OpenSim/Framework/Console/ConsolePluginCommand.cs Normal file → Executable file
View File

@ -124,7 +124,7 @@ namespace OpenSim.Framework.Console
/// </summary>
public void ShowHelp(ConsoleBase console)
{
console.Output(String.Join(" ", m_cmdText) + " - " + m_helpText);
console.Output(String.Join(" ", m_cmdText) + " - " + m_helpText + "\n");
}
/// <summary>

View File

@ -302,6 +302,12 @@ namespace OpenSim.Framework.Console
if (!UUID.TryParse(post["ID"].ToString(), out id))
return reply;
lock(m_Connections)
{
if(!m_Connections.ContainsKey(id))
return reply;
}
if (post["COMMAND"] == null || post["COMMAND"].ToString() == String.Empty)
return reply;

122
OpenSim/Region/Application/OpenSim.cs Normal file → Executable file
View File

@ -409,7 +409,7 @@ namespace OpenSim
if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) &&
presence.Lastname.ToLower().Contains(cmdparams[3].ToLower()))
{
m_log.Info(
MainConsole.Instance.Output(
String.Format(
"Kicking user: {0,-16}{1,-16}{2,-37} in region: {3,-16}",
presence.Firstname, presence.Lastname, presence.UUID, regionInfo.RegionName));
@ -424,7 +424,7 @@ namespace OpenSim
presence.Scene.IncomingCloseAgent(presence.UUID);
}
}
m_log.Info("");
MainConsole.Instance.Output("");
}
/// <summary>
@ -471,7 +471,7 @@ namespace OpenSim
private void HandleClearAssets(string module, string[] args)
{
m_log.Info("Not implemented.");
MainConsole.Instance.Output("Not implemented.");
}
/// <summary>
@ -481,7 +481,7 @@ namespace OpenSim
/// <param name="args"></param>
private void HandleForceUpdate(string module, string[] args)
{
m_log.Info("Updating all clients");
MainConsole.Instance.Output("Updating all clients");
m_sceneManager.ForceCurrentSceneClientUpdate();
}
@ -498,7 +498,7 @@ namespace OpenSim
}
else
{
m_log.Info("Argument error: edit scale <prim name> <x> <y> <z>");
MainConsole.Instance.Output("Argument error: edit scale <prim name> <x> <y> <z>");
}
}
@ -511,7 +511,7 @@ namespace OpenSim
{
if (cmd.Length < 4)
{
m_log.Error("Usage: create region <region name> <region_file.ini>");
MainConsole.Instance.Output("Usage: create region <region name> <region_file.ini>");
return;
}
if (cmd[3].EndsWith(".xml"))
@ -538,7 +538,7 @@ namespace OpenSim
}
else
{
m_log.Error("Usage: create region <region name> <region_file.ini>");
MainConsole.Instance.Output("Usage: create region <region name> <region_file.ini>");
return;
}
}
@ -562,8 +562,8 @@ namespace OpenSim
case "set":
if (cmdparams.Length < 4)
{
m_log.Error("SYNTAX: " + n + " SET SECTION KEY VALUE");
m_log.Error("EXAMPLE: " + n + " SET ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
MainConsole.Instance.Output(String.Format("SYNTAX: {0} SET SECTION KEY VALUE",n));
MainConsole.Instance.Output(String.Format("EXAMPLE: {0} SET ScriptEngine.DotNetEngine NumberOfScriptThreads 5",n));
}
else
{
@ -576,8 +576,7 @@ namespace OpenSim
c.Set(cmdparams[2], _value);
m_config.Source.Merge(source);
m_log.Error(n + " " + n + " " + cmdparams[1] + " " + cmdparams[2] + " " +
_value);
MainConsole.Instance.Output(String.Format("{0} {0} {1} {2} {3}",n,cmdparams[1],cmdparams[2],_value));
}
}
break;
@ -585,21 +584,21 @@ namespace OpenSim
case "get":
if (cmdparams.Length < 3)
{
m_log.Error("SYNTAX: " + n + " GET SECTION KEY");
m_log.Error("EXAMPLE: " + n + " GET ScriptEngine.DotNetEngine NumberOfScriptThreads");
MainConsole.Instance.Output(String.Format("SYNTAX: {0} GET SECTION KEY",n));
MainConsole.Instance.Output(String.Format("EXAMPLE: {0} GET ScriptEngine.DotNetEngine NumberOfScriptThreads",n));
}
else
{
IConfig c = m_config.Source.Configs[cmdparams[1]];
if (c == null)
{
m_log.Info("Section \"" + cmdparams[1] + "\" does not exist.");
MainConsole.Instance.Output(String.Format("Section \"{0}\" does not exist.",cmdparams[1]));
break;
}
else
{
m_log.Info(n + " GET " + cmdparams[1] + " " + cmdparams[2] + ": " +
c.GetString(cmdparams[2]));
MainConsole.Instance.Output(String.Format("{0} GET {1} {2} : {3}",n,cmdparams[1],cmdparams[2],
c.GetString(cmdparams[2])));
}
}
@ -608,17 +607,17 @@ namespace OpenSim
case "save":
if (cmdparams.Length < 2)
{
m_log.Error("SYNTAX: " + n + " SAVE FILE");
MainConsole.Instance.Output("SYNTAX: " + n + " SAVE FILE");
return;
}
if (Application.iniFilePath == cmdparams[1])
{
m_log.Error("FILE can not be "+Application.iniFilePath);
MainConsole.Instance.Output("FILE can not be " + Application.iniFilePath);
return;
}
m_log.Info("Saving configuration file: " + cmdparams[1]);
MainConsole.Instance.Output("Saving configuration file: " + cmdparams[1]);
m_config.Save(cmdparams[1]);
break;
}
@ -644,7 +643,7 @@ namespace OpenSim
case "list":
foreach (IRegionModule irm in m_moduleLoader.GetLoadedSharedModules)
{
m_log.Info("Shared region module: " + irm.Name);
MainConsole.Instance.Output(String.Format("Shared region module: {0}", irm.Name));
}
break;
case "unload":
@ -654,7 +653,7 @@ namespace OpenSim
{
if (rm.Name.ToLower() == cmdparams[1].ToLower())
{
m_log.Info("Unloading module: " + rm.Name);
MainConsole.Instance.Output(String.Format("Unloading module: {0}", rm.Name));
m_moduleLoader.UnloadModule(rm);
}
}
@ -665,7 +664,7 @@ namespace OpenSim
{
foreach (Scene s in new ArrayList(m_sceneManager.Scenes))
{
m_log.Info("Loading module: " + cmdparams[1]);
MainConsole.Instance.Output(String.Format("Loading module: {0}", cmdparams[1]));
m_moduleLoader.LoadRegionModules(cmdparams[1], s);
}
}
@ -710,7 +709,7 @@ namespace OpenSim
if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
RemoveRegion(removeScene, false);
else
m_log.Error("no region with that name");
MainConsole.Instance.Output("no region with that name");
break;
case "delete-region":
@ -720,7 +719,7 @@ namespace OpenSim
if (m_sceneManager.TryGetScene(regDeleteName, out killScene))
RemoveRegion(killScene, true);
else
m_log.Error("no region with that name");
MainConsole.Instance.Output("no region with that name");
break;
case "restart":
@ -730,7 +729,7 @@ namespace OpenSim
case "Add-InventoryHost":
if (cmdparams.Length > 0)
{
m_log.Info("Not implemented.");
MainConsole.Instance.Output("Not implemented.");
}
break;
@ -748,20 +747,19 @@ namespace OpenSim
string newRegionName = CombineParams(cmdparams, 2);
if (!m_sceneManager.TrySetCurrentScene(newRegionName))
m_log.Error("Couldn't select region " + newRegionName);
MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName));
}
else
{
m_log.Error("Usage: change region <region name>");
MainConsole.Instance.Output("Usage: change region <region name>");
}
string regionName = (m_sceneManager.CurrentScene == null ? "root" : m_sceneManager.CurrentScene.RegionInfo.RegionName);
m_log.Info(String.Format("Currently selected region is {0}", regionName));
MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
m_console.DefaultPrompt = String.Format("Region ({0}) ", regionName);
m_console.ConsoleScene = m_sceneManager.CurrentScene;
}
/// <summary>
/// Turn on some debugging values for OpenSim.
/// </summary>
@ -783,9 +781,9 @@ namespace OpenSim
}
else
{
m_log.Error("packet debug should be 0..255");
MainConsole.Instance.Output("packet debug should be 0..255");
}
m_log.Info("New packet debug: " + newDebug.ToString());
MainConsole.Instance.Output(String.Format("New packet debug: {0}", newDebug));
}
break;
@ -795,7 +793,7 @@ namespace OpenSim
{
if (m_sceneManager.CurrentScene == null)
{
m_log.Info("Please use 'change region <regioname>' first");
MainConsole.Instance.Output("Please use 'change region <regioname>' first");
}
else
{
@ -804,7 +802,7 @@ namespace OpenSim
bool physicsOn = !Convert.ToBoolean(args[4]);
m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn);
m_log.Info(
MainConsole.Instance.Output(
String.Format(
"Set debug scene scripting = {0}, collisions = {1}, physics = {2}",
!scriptingOn, !collisionsOn, !physicsOn));
@ -812,13 +810,13 @@ namespace OpenSim
}
else
{
m_log.Error("debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
MainConsole.Instance.Output("debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
}
break;
default:
m_log.Error("Unknown debug");
MainConsole.Instance.Output("Unknown debug");
break;
}
}
@ -840,7 +838,7 @@ namespace OpenSim
switch (showParams[0])
{
case "assets":
m_log.Info("Not implemented.");
MainConsole.Instance.Output("Not implemented.");
break;
case "users":
@ -854,9 +852,9 @@ namespace OpenSim
agents = m_sceneManager.GetCurrentSceneAvatars();
}
m_log.Info(String.Format("\nAgents connected: {0}\n", agents.Count));
MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
m_log.Info(
MainConsole.Instance.Output(
String.Format("{0,-16}{1,-16}{2,-37}{3,-11}{4,-16}{5,-30}", "Firstname", "Lastname",
"Agent ID", "Root/Child", "Region", "Position"));
@ -874,7 +872,7 @@ namespace OpenSim
regionName = regionInfo.RegionName;
}
m_log.Info(
MainConsole.Instance.Output(
String.Format(
"{0,-16}{1,-16}{2,-37}{3,-11}{4,-16}{5,-30}",
presence.Firstname,
@ -885,7 +883,7 @@ namespace OpenSim
presence.AbsolutePosition.ToString()));
}
m_log.Info(String.Empty);
MainConsole.Instance.Output(String.Empty);
break;
case "connections":
@ -903,25 +901,30 @@ namespace OpenSim
}
);
m_log.Info(connections.ToString());
MainConsole.Instance.Output(connections.ToString());
break;
case "modules":
m_log.Info("The currently loaded shared modules are:");
MainConsole.Instance.Output("The currently loaded shared modules are:");
foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules)
{
m_log.Info("Shared Module: " + module.Name);
MainConsole.Instance.Output("Shared Module: " + module.Name);
}
MainConsole.Instance.Output("");
break;
case "regions":
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
m_log.Info("Region Name: " + scene.RegionInfo.RegionName + " , Region XLoc: " +
scene.RegionInfo.RegionLocX + " , Region YLoc: " +
scene.RegionInfo.RegionLocY + " , Region Port: " +
scene.RegionInfo.InternalEndPoint.Port.ToString());
MainConsole.Instance.Output(String.Format(
"Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}",
scene.RegionInfo.RegionName,
scene.RegionInfo.RegionLocX,
scene.RegionInfo.RegionLocY,
scene.RegionInfo.InternalEndPoint.Port));
});
break;
@ -946,8 +949,10 @@ namespace OpenSim
{
rating = "PG";
}
m_log.Info("Region Name: " + scene.RegionInfo.RegionName + " , Region Rating: " +
rating);
MainConsole.Instance.Output(String.Format(
"Region Name: {0}, Region Rating {1}",
scene.RegionInfo.RegionName,
rating));
});
break;
}
@ -968,7 +973,7 @@ namespace OpenSim
if (client is IStatsCollector)
{
report = report + client.FirstName +
" " + client.LastName + "\n";
" " + client.LastName;
IStatsCollector stats =
(IStatsCollector) client;
@ -985,7 +990,7 @@ namespace OpenSim
"Texture",
"Asset");
report = report + stats.Report() +
"\n\n";
"\n";
}
});
});
@ -1017,7 +1022,7 @@ namespace OpenSim
/// <param name="cmdparams"></param>
protected void SaveXml(string module, string[] cmdparams)
{
m_log.Error("[CONSOLE]: PLEASE NOTE, save-xml is DEPRECATED and may be REMOVED soon. If you are using this and there is some reason you can't use save-xml2, please file a mantis detailing the reason.");
MainConsole.Instance.Output("PLEASE NOTE, save-xml is DEPRECATED and may be REMOVED soon. If you are using this and there is some reason you can't use save-xml2, please file a mantis detailing the reason.");
if (cmdparams.Length > 0)
{
@ -1036,7 +1041,7 @@ namespace OpenSim
/// <param name="cmdparams"></param>
protected void LoadXml(string module, string[] cmdparams)
{
m_log.Error("[CONSOLE]: PLEASE NOTE, load-xml is DEPRECATED and may be REMOVED soon. If you are using this and there is some reason you can't use load-xml2, please file a mantis detailing the reason.");
MainConsole.Instance.Output("PLEASE NOTE, load-xml is DEPRECATED and may be REMOVED soon. If you are using this and there is some reason you can't use load-xml2, please file a mantis detailing the reason.");
Vector3 loadOffset = new Vector3(0, 0, 0);
if (cmdparams.Length > 2)
@ -1059,8 +1064,7 @@ namespace OpenSim
{
loadOffset.Z = (float) Convert.ToDecimal(cmdparams[6]);
}
m_log.Error("loadOffsets <X,Y,Z> = <" + loadOffset.X + "," + loadOffset.Y + "," +
loadOffset.Z + ">");
MainConsole.Instance.Output(String.Format("loadOffsets <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
}
}
m_sceneManager.LoadCurrentSceneFromXml(cmdparams[0], generateNewIDS, loadOffset);
@ -1073,7 +1077,7 @@ namespace OpenSim
}
catch (FileNotFoundException)
{
m_log.Error("Default xml not found. Usage: load-xml <filename>");
MainConsole.Instance.Output("Default xml not found. Usage: load-xml <filename>");
}
}
}
@ -1109,7 +1113,7 @@ namespace OpenSim
}
catch (FileNotFoundException)
{
m_log.Error("Specified xml not found. Usage: load xml2 <filename>");
MainConsole.Instance.Output("Specified xml not found. Usage: load xml2 <filename>");
}
}
else
@ -1120,7 +1124,7 @@ namespace OpenSim
}
catch (FileNotFoundException)
{
m_log.Error("Default xml not found. Usage: load xml2 <filename>");
MainConsole.Instance.Output("Default xml not found. Usage: load xml2 <filename>");
}
}
}
@ -1137,7 +1141,7 @@ namespace OpenSim
}
catch (Exception e)
{
m_log.Error(e.Message);
MainConsole.Instance.Output(e.Message);
}
}

View File

@ -1471,6 +1471,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendKillObject(ulong regionHandle, uint localID)
{
// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
// TODO: don't create new blocks if recycling an old packet
kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
@ -3478,6 +3480,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendPrimitiveToClient(SendPrimitiveData data)
{
// string text = data.text;
// if (text.IndexOf("\n") >= 0)
// text = text.Remove(text.IndexOf("\n"));
// m_log.DebugFormat(
// "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}",
// data.localID, text, Name);
if (data.priority == double.NaN)
{
m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update");
@ -3515,7 +3524,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count];
for (int i = 0; i < count; i++)
{
outPacket.ObjectData[i] = m_primFullUpdates.Dequeue();
// string text = Util.FieldToString(outPacket.ObjectData[i].Text);
// if (text.IndexOf("\n") >= 0)
// text = text.Remove(text.IndexOf("\n"));
// m_log.DebugFormat(
// "[CLIENT]: Sending full info about prim {0} text {1} to client {2}",
// outPacket.ObjectData[i].ID, text, Name);
}
}
OutPacket(outPacket, ThrottleOutPacketType.State);
@ -5173,6 +5191,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
ScriptDialogReplyPacket rdialog = (ScriptDialogReplyPacket)Pack;
//m_log.DebugFormat("[CLIENT]: Received ScriptDialogReply from {0}", rdialog.Data.ObjectID);
#region Packet Session and User Check
if (m_checkPackets)
{
@ -9095,8 +9115,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandleSendPostcard(IClientAPI client, Packet packet)
{
SendPostcardPacket SendPostcard =
(SendPostcardPacket)packet;
// SendPostcardPacket SendPostcard =
// (SendPostcardPacket)packet;
SendPostcard handlerSendPostcard = OnSendPostcard;
if (handlerSendPostcard != null)
{

View File

@ -762,7 +762,7 @@ namespace Flotsam.RegionModules.AssetCache
case "expire":
if (cmdparams.Length >= 3)
if (cmdparams.Length < 3)
{
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Invalid parameters for Expire, please specify a valid date & time", cmd);
break;

View File

@ -171,11 +171,13 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
}
private void RetrieveInstantMessages(IClientAPI client)
{
if (m_RestURL != "")
{
m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId);
List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
"POST", m_RestURL+"/RetrieveMessages/", client.AgentId);
List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
"POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
foreach (GridInstantMessage im in msglist)
{
@ -192,6 +194,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
s.EventManager.TriggerIncomingInstantMessage(im);
}
}
}
private void UndeliveredMessage(GridInstantMessage im)
{

View File

@ -191,7 +191,6 @@ namespace OpenSim.Region.CoreModules.Framework.Library
{
m_log.DebugFormat("[LIBRARY MODULE]: Exception when processing archive {0}: {1}", iarFileName, e.Message);
}
}
}
@ -203,6 +202,14 @@ namespace OpenSim.Region.CoreModules.Framework.Library
m_log.DebugFormat(" - folder {0}", lib.Name);
DumpFolder(lib);
}
//
// private void DumpLibrary()
// {
// InventoryFolderImpl lib = m_Scene.CommsManager.UserProfileCacheService.LibraryRoot;
//
// m_log.DebugFormat(" - folder {0}", lib.Name);
// DumpFolder(lib);
// }
private void DumpFolder(InventoryFolderImpl folder)
{

View File

@ -87,7 +87,10 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
foreach (IMonitor monitor in m_monitors)
{
if (monitor.ToString() == monID)
string elemName = monitor.ToString();
if (elemName.StartsWith(monitor.GetType().Namespace))
elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1);
if (elemName == monID || monitor.ToString() == monID)
{
Hashtable ereply3 = new Hashtable();

View File

@ -361,10 +361,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
}
if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
{
if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString());
if (oldAsset != null)
{
if (oldAsset.Temporary == true)
{
scene.AssetService.Delete(oldID.ToString());
}
}
}
}
private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
{

View File

@ -342,6 +342,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
m_log.Error(
"[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Empty byte data returned!");
}
m_textureManager.ReturnData(id, imageJ2000);
}

View File

@ -262,44 +262,34 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
case ChatTypeEnum.Whisper:
if (dis < m_whisperdistance)
{
lock (m_pending.SyncRoot)
{
m_pending.Enqueue(new ListenerInfo(li,name,id,msg));
}
}
QueueMessage(new ListenerInfo(li, name, id, msg));
break;
case ChatTypeEnum.Say:
if (dis < m_saydistance)
{
lock (m_pending.SyncRoot)
{
m_pending.Enqueue(new ListenerInfo(li,name,id,msg));
}
}
QueueMessage(new ListenerInfo(li, name, id, msg));
break;
case ChatTypeEnum.Shout:
if (dis < m_shoutdistance)
{
lock (m_pending.SyncRoot)
{
m_pending.Enqueue(new ListenerInfo(li,name,id,msg));
}
}
QueueMessage(new ListenerInfo(li, name, id, msg));
break;
case ChatTypeEnum.Region:
lock (m_pending.SyncRoot)
{
m_pending.Enqueue(new ListenerInfo(li,name,id,msg));
}
QueueMessage(new ListenerInfo(li, name, id, msg));
break;
}
}
}
protected void QueueMessage(ListenerInfo li)
{
lock (m_pending.SyncRoot)
{
m_pending.Enqueue(li);
}
}
/// <summary>
/// Are there any listen events ready to be dispatched?
/// </summary>
@ -319,7 +309,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
lock (m_pending.SyncRoot)
{
li = (ListenerInfo) m_pending.Dequeue();
li = (ListenerInfo)m_pending.Dequeue();
}
return li;

View File

@ -41,9 +41,7 @@ namespace OpenSim.Region.CoreModules.World
{
public class AccessModule : ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<Scene> m_SceneList = new List<Scene>();

View File

@ -422,6 +422,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight;
IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
if (estateModule != null)
estateModule.sendRegionHandshakeToAll();
return true;

View File

@ -36,11 +36,13 @@ using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Serialization;
using OpenSim.Framework.Serialization.External;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.CoreModules.World.Terrain;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.World.Archiver.Tests
@ -51,6 +53,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
private Guid m_lastRequestId;
private string m_lastErrorMessage;
protected TestScene m_scene;
protected ArchiverModule m_archiverModule;
[SetUp]
public void SetUp()
{
m_archiverModule = new ArchiverModule();
SerialiserModule serialiserModule = new SerialiserModule();
TerrainModule terrainModule = new TerrainModule();
m_scene = SceneSetupHelpers.SetupScene("scene1");
SceneSetupHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule);
}
private void LoadCompleted(Guid requestId, string errorMessage)
{
lock (this)
@ -74,6 +90,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
}
}
protected SceneObjectPart CreateSceneObjectPart1()
{
string partName = "My Little Pony";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
Vector3 groupPosition = new Vector3(10, 20, 30);
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
Vector3 offsetPosition = new Vector3(5, 10, 15);
return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
}
protected SceneObjectPart CreateSceneObjectPart2()
{
string partName = "Action Man";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
Vector3 groupPosition = new Vector3(90, 80, 70);
Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
Vector3 offsetPosition = new Vector3(20, 25, 30);
return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
}
/// <summary>
/// Test saving a V0.2 OpenSim Region Archive.
/// </summary>
@ -83,59 +123,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
ArchiverModule archiverModule = new ArchiverModule();
SerialiserModule serialiserModule = new SerialiserModule();
TerrainModule terrainModule = new TerrainModule();
SceneObjectPart part1 = CreateSceneObjectPart1();
m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
Scene scene = SceneSetupHelpers.SetupScene("asset");
SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
SceneObjectPart part1;
// Create and add prim 1
{
string partName = "My Little Pony";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
Vector3 groupPosition = new Vector3(10, 20, 30);
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
Vector3 offsetPosition = new Vector3(5, 10, 15);
part1
= new SceneObjectPart(
ownerId, shape, groupPosition, rotationOffset, offsetPosition);
part1.Name = partName;
scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
}
SceneObjectPart part2;
// Create and add prim 2
{
string partName = "Action Man";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
Vector3 groupPosition = new Vector3(90, 80, 70);
Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
Vector3 offsetPosition = new Vector3(20, 25, 30);
part2
= new SceneObjectPart(
ownerId, shape, groupPosition, rotationOffset, offsetPosition);
part2.Name = partName;
scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
}
SceneObjectPart part2 = CreateSceneObjectPart2();
m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
MemoryStream archiveWriteStream = new MemoryStream();
scene.EventManager.OnOarFileSaved += SaveCompleted;
m_scene.EventManager.OnOarFileSaved += SaveCompleted;
Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
lock (this)
{
archiverModule.ArchiveRegion(archiveWriteStream, requestId);
m_archiverModule.ArchiveRegion(archiveWriteStream, requestId);
//AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
//while (assetServer.HasWaitingRequests())
// assetServer.ProcessNextRequest();
@ -217,29 +218,55 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
string part1Name = "object1";
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
Vector3 groupPosition = new Vector3(90, 80, 70);
Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
Vector3 offsetPosition = new Vector3(20, 25, 30);
SerialiserModule serialiserModule = new SerialiserModule();
ArchiverModule archiverModule = new ArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
SceneObjectPart part1
= new SceneObjectPart(
UUID.Zero, shape, groupPosition, rotationOffset, offsetPosition);
part1.Name = part1Name;
SceneObjectPart part1 = CreateSceneObjectPart1();
SceneObjectGroup object1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(object1, false);
// Let's put some inventory items into our object
string soundItemName = "sound-item1";
UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
Type type = GetType();
Assembly assembly = type.Assembly;
string soundDataResourceName = null;
string[] names = assembly.GetManifestResourceNames();
foreach (string name in names)
{
if (name.EndsWith(".Resources.test-sound.wav"))
soundDataResourceName = name;
}
Assert.That(soundDataResourceName, Is.Not.Null);
byte[] soundData;
Console.WriteLine("Loading " + soundDataResourceName);
using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName))
{
using (BinaryReader br = new BinaryReader(resource))
{
// FIXME: Use the inspector insteadthere are so many forums and lists already, though admittedly none of them are suitable for cross virtual-enivornemnt discussion
soundData = br.ReadBytes(99999999);
UUID soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
string soundAssetFileName
= ArchiveConstants.ASSETS_PATH + soundUuid
+ ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
tar.WriteFile(soundAssetFileName, soundData);
/*
AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
scene.AssetService.Store(soundAsset);
asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
*/
TaskInventoryItem item1
= new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
part1.Inventory.AddInventoryItem(item1, true);
}
}
m_scene.AddNewSceneObject(object1, false);
string object1FileName = string.Format(
"{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
part1Name,
Math.Round(groupPosition.X), Math.Round(groupPosition.Y), Math.Round(groupPosition.Z),
part1.Name,
Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
part1.UUID);
tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1));
@ -249,26 +276,124 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
lock (this)
{
scene.EventManager.OnOarFileLoaded += LoadCompleted;
archiverModule.DearchiveRegion(archiveReadStream);
m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
m_archiverModule.DearchiveRegion(archiveReadStream);
}
Assert.That(m_lastErrorMessage, Is.Null);
SceneObjectPart object1PartLoaded = scene.GetSceneObjectPart(part1Name);
SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
Assert.That(object1PartLoaded.Name, Is.EqualTo(part1Name), "object1 names not identical");
Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(groupPosition), "object1 group position not equal");
Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical");
Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
Assert.That(
object1PartLoaded.RotationOffset, Is.EqualTo(rotationOffset), "object1 rotation offset not equal");
object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
Assert.That(
object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal");
object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
// Temporary
Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod());
}
/// <summary>
/// Test loading the region settings of a V0.2 OpenSim Region Archive.
/// </summary>
[Test]
public void TestLoadOarV0_2RegionSettings()
{
TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
MemoryStream archiveWriteStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
RegionSettings rs = new RegionSettings();
rs.AgentLimit = 17;
rs.AllowDamage = true;
rs.AllowLandJoinDivide = true;
rs.AllowLandResell = true;
rs.BlockFly = true;
rs.BlockShowInSearch = true;
rs.BlockTerraform = true;
rs.DisableCollisions = true;
rs.DisablePhysics = true;
rs.DisableScripts = true;
rs.Elevation1NW = 15.9;
rs.Elevation1NE = 45.3;
rs.Elevation1SE = 49;
rs.Elevation1SW = 1.9;
rs.Elevation2NW = 4.5;
rs.Elevation2NE = 19.2;
rs.Elevation2SE = 9.2;
rs.Elevation2SW = 2.1;
rs.FixedSun = true;
rs.ObjectBonus = 1.4;
rs.RestrictPushing = true;
rs.TerrainLowerLimit = 0.4;
rs.TerrainRaiseLimit = 17.9;
rs.TerrainTexture1 = UUID.Parse("00000000-0000-0000-0000-000000000020");
rs.TerrainTexture2 = UUID.Parse("00000000-0000-0000-0000-000000000040");
rs.TerrainTexture3 = UUID.Parse("00000000-0000-0000-0000-000000000060");
rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080");
rs.UseEstateSun = true;
rs.WaterHeight = 23;
tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs));
tar.Close();
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
lock (this)
{
m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
m_archiverModule.DearchiveRegion(archiveReadStream);
}
Assert.That(m_lastErrorMessage, Is.Null);
RegionSettings loadedRs = m_scene.RegionInfo.RegionSettings;
Assert.That(loadedRs.AgentLimit, Is.EqualTo(17));
Assert.That(loadedRs.AllowDamage, Is.True);
Assert.That(loadedRs.AllowLandJoinDivide, Is.True);
Assert.That(loadedRs.AllowLandResell, Is.True);
Assert.That(loadedRs.BlockFly, Is.True);
Assert.That(loadedRs.BlockShowInSearch, Is.True);
Assert.That(loadedRs.BlockTerraform, Is.True);
Assert.That(loadedRs.DisableCollisions, Is.True);
Assert.That(loadedRs.DisablePhysics, Is.True);
Assert.That(loadedRs.DisableScripts, Is.True);
Assert.That(loadedRs.Elevation1NW, Is.EqualTo(15.9));
Assert.That(loadedRs.Elevation1NE, Is.EqualTo(45.3));
Assert.That(loadedRs.Elevation1SE, Is.EqualTo(49));
Assert.That(loadedRs.Elevation1SW, Is.EqualTo(1.9));
Assert.That(loadedRs.Elevation2NW, Is.EqualTo(4.5));
Assert.That(loadedRs.Elevation2NE, Is.EqualTo(19.2));
Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2));
Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1));
Assert.That(loadedRs.FixedSun, Is.True);
Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4));
Assert.That(loadedRs.RestrictPushing, Is.True);
Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4));
Assert.That(loadedRs.TerrainRaiseLimit, Is.EqualTo(17.9));
Assert.That(loadedRs.TerrainTexture1, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000020")));
Assert.That(loadedRs.TerrainTexture2, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000040")));
Assert.That(loadedRs.TerrainTexture3, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000060")));
Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080")));
Assert.That(loadedRs.UseEstateSun, Is.True);
Assert.That(loadedRs.WaterHeight, Is.EqualTo(23));
}
/// <summary>
/// Test merging a V0.2 OpenSim Region Archive into an existing scene
/// </summary>
@ -280,11 +405,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
MemoryStream archiveWriteStream = new MemoryStream();
string part2Name = "objectMerge";
PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
Vector3 part2GroupPosition = new Vector3(90, 80, 70);
Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
// string part2Name = "objectMerge";
// PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
// Vector3 part2GroupPosition = new Vector3(90, 80, 70);
// Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
// Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
SceneObjectPart part2 = CreateSceneObjectPart2();
// Create an oar file that we can use for the merge
{
@ -295,61 +422,37 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
Scene scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
SceneObjectPart part2
= new SceneObjectPart(
UUID.Zero, part2Shape, part2GroupPosition, part2RotationOffset, part2OffsetPosition);
part2.Name = part2Name;
SceneObjectGroup object2 = new SceneObjectGroup(part2);
scene.AddNewSceneObject(object2, false);
m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
// Write out this scene
scene.EventManager.OnOarFileSaved += SaveCompleted;
lock (this)
{
archiverModule.ArchiveRegion(archiveWriteStream);
m_archiverModule.ArchiveRegion(archiveWriteStream);
Monitor.Wait(this, 60000);
}
}
{
ArchiverModule archiverModule = new ArchiverModule();
SerialiserModule serialiserModule = new SerialiserModule();
TerrainModule terrainModule = new TerrainModule();
Scene scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
string part1Name = "objectExisting";
PrimitiveBaseShape part1Shape = PrimitiveBaseShape.CreateCylinder();
Vector3 part1GroupPosition = new Vector3(80, 70, 60);
Quaternion part1RotationOffset = new Quaternion(50, 60, 70, 80);
Vector3 part1OffsetPosition = new Vector3(15, 20, 25);
SceneObjectPart part1
= new SceneObjectPart(
UUID.Zero, part1Shape, part1GroupPosition, part1RotationOffset, part1OffsetPosition);
part1.Name = part1Name;
SceneObjectGroup object1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(object1, false);
SceneObjectPart part1 = CreateSceneObjectPart1();
m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
// Merge in the archive we created earlier
byte[] archive = archiveWriteStream.ToArray();
MemoryStream archiveReadStream = new MemoryStream(archive);
archiverModule.DearchiveRegion(archiveReadStream, true, Guid.Empty);
m_archiverModule.DearchiveRegion(archiveReadStream, true, Guid.Empty);
SceneObjectPart object1Existing = scene.GetSceneObjectPart(part1Name);
SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name);
Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
Assert.That(object1Existing.Name, Is.EqualTo(part1Name), "object1 names not identical after merge");
Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1GroupPosition), "object1 group position not equal after merge");
Assert.That(object1Existing.Name, Is.EqualTo(part1.Name), "object1 names not identical after merge");
Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal after merge");
SceneObjectPart object2PartMerged = scene.GetSceneObjectPart(part2Name);
SceneObjectPart object2PartMerged = m_scene.GetSceneObjectPart(part2.Name);
Assert.That(object2PartMerged, Is.Not.Null, "object2 was not present after merge");
Assert.That(object2PartMerged.Name, Is.EqualTo(part2Name), "object2 names not identical after merge");
Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2GroupPosition), "object2 group position not equal after merge");
Assert.That(object2PartMerged.Name, Is.EqualTo(part2.Name), "object2 names not identical after merge");
Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge");
}
}
}

View File

@ -142,6 +142,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
private bool m_debugPermissions = false;
private bool m_allowGridGods = false;
private bool m_RegionOwnerIsGod = false;
private bool m_RegionManagerIsGod = false;
private bool m_ParcelOwnerIsGod = false;
/// <value>
@ -184,6 +185,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", false);
m_propagatePermissions = myConfig.GetBoolean("propagate_permissions", true);
m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true);
m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false);
m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true);
m_allowedScriptCreators
@ -479,10 +481,13 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero)
{
if (m_scene.RegionInfo.EstateSettings.EstateOwner == user)
if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod)
return true;
}
if (IsEstateManager(user) && m_RegionManagerIsGod)
return true;
if (m_allowGridGods)
{
UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user);
@ -495,6 +500,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return false;
}
protected bool IsFriendWithPerms(UUID user,UUID objectOwner)
{
@ -896,9 +902,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name);
if (m_bypassPermissions) return m_bypassPermissionsValue;
if (IsEstateManager(user) && m_RegionOwnerIsGod)
return true;
return IsAdministrator(user);
}

View File

@ -72,12 +72,17 @@ namespace OpenSim.Region.Framework.Interfaces
/// Start all the scripts contained in this entity's inventory
/// </summary>
void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
ArrayList GetScriptErrors(UUID itemID);
/// <summary>
/// Stop all the scripts in this entity.
/// </summary>
void RemoveScriptInstances();
/// <param name="sceneObjectBeingDeleted">
/// Should be true if these scripts are being removed because the scene
/// object is being deleted. This will prevent spurious updates to the client.
/// </param>
void RemoveScriptInstances(bool sceneObjectBeingDeleted);
/// <summary>
/// Start a script which is in this entity's inventory.
@ -103,7 +108,11 @@ namespace OpenSim.Region.Framework.Interfaces
/// Stop a script which is in this prim's inventory.
/// </summary>
/// <param name="itemId"></param>
void RemoveScriptInstance(UUID itemId);
/// <param name="sceneObjectBeingDeleted">
/// Should be true if these scripts are being removed because the scene
/// object is being deleted. This will prevent spurious updates to the client.
/// </param>
void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted);
/// <summary>
/// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative
@ -134,6 +143,16 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns>null if the item does not exist</returns>
TaskInventoryItem GetInventoryItem(UUID itemId);
/// <summary>
/// Get inventory items by name.
/// </summary>
/// <param name="name"></param>
/// <returns>
/// A list of inventory items with that name.
/// If no inventory item has that name then an empty list is returned.
/// </returns>
IList<TaskInventoryItem> GetInventoryItems(string name);
/// <summary>
/// Update an existing inventory item.
/// </summary>

View File

@ -49,10 +49,49 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IWorldComm
{
/// <summary>
/// Create a listen event callback with the specified filters.
/// The parameters localID,itemID are needed to uniquely identify
/// the script during 'peek' time. Parameter hostID is needed to
/// determine the position of the script.
/// </summary>
/// <param name="localID">localID of the script engine</param>
/// <param name="itemID">UUID of the script engine</param>
/// <param name="hostID">UUID of the SceneObjectPart</param>
/// <param name="channel">channel to listen on</param>
/// <param name="name">name to filter on</param>
/// <param name="id">key to filter on (user given, could be totally faked)</param>
/// <param name="msg">msg to filter on</param>
/// <returns>number of the scripts handle</returns>
int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg);
/// <summary>
/// This method scans over the objects which registered an interest in listen callbacks.
/// For everyone it finds, it checks if it fits the given filter. If it does, then
/// enqueue the message for delivery to the objects listen event handler.
/// The enqueued ListenerInfo no longer has filter values, but the actually trigged values.
/// Objects that do an llSay have their messages delivered here and for nearby avatars,
/// the OnChatFromClient event is used.
/// </summary>
/// <param name="type">type of delvery (whisper,say,shout or regionwide)</param>
/// <param name="channel">channel to sent on</param>
/// <param name="name">name of sender (object or avatar)</param>
/// <param name="id">key of sender (object or avatar)</param>
/// <param name="msg">msg to sent</param>
void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg);
/// <summary>
/// Are there any listen events ready to be dispatched?
/// </summary>
/// <returns>boolean indication</returns>
bool HasMessages();
/// <summary>
/// Pop the first availlable listen event from the queue
/// </summary>
/// <returns>ListenerInfo with filter filled in</returns>
IWorldCommListenerInfo GetNextMessage();
void ListenControl(UUID itemID, int handle, int active);
void ListenRemove(UUID itemID, int handle);
void DeleteListener(UUID itemID);

File diff suppressed because it is too large Load Diff

View File

@ -197,7 +197,7 @@ namespace OpenSim.Region.Framework.Scenes
if (isScriptRunning)
{
part.Inventory.RemoveScriptInstance(item.ItemID);
part.Inventory.RemoveScriptInstance(item.ItemID, false);
}
// Update item with new asset
@ -794,8 +794,10 @@ namespace OpenSim.Region.Framework.Scenes
if (item.Type == 10)
{
part.RemoveScriptEvents(itemID);
EventManager.TriggerRemoveScript(localID, itemID);
}
group.RemoveInventoryItem(localID, itemID);
part.GetProperties(remoteClient);
}
@ -1879,9 +1881,19 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
/// <summary>
/// Attach an object.
/// </summary>
/// <param name="controllingClient"></param>
/// <param name="localID"></param>
/// <param name="attachPoint"></param>
/// <param name="rot"></param>
/// <param name="pos"></param>
/// <param name="silent"></param>
/// <returns>true if the object was successfully attached, false otherwise</returns>
public bool AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
{
m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
}
public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)

View File

@ -292,6 +292,46 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
{
List<EntityBase> EntityList = GetEntities();
SurfaceTouchEventArgs surfaceArg = null;
if (surfaceArgs != null && surfaceArgs.Count > 0)
surfaceArg = surfaceArgs[0];
foreach (EntityBase ent in EntityList)
{
if (ent is SceneObjectGroup)
{
SceneObjectGroup obj = ent as SceneObjectGroup;
if (obj != null)
{
// Is this prim part of the group
if (obj.HasChildPrim(objectID))
{
SceneObjectPart part = obj.GetChildPart(objectID);
// If the touched prim handles touches, deliver it
// If not, deliver to root prim
if ((part.ScriptEvents & scriptEvents.touch) != 0)
EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
// Deliver to the root prim if the touched prim doesn't handle touches
// or if we're meant to pass on touches anyway. Don't send to root prim
// if prim touched is the root prim as we just did it
if (((part.ScriptEvents & scriptEvents.touch) == 0) ||
(part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
{
EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
}
return;
}
}
}
}
}
public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
{
List<EntityBase> EntityList = GetEntities();

View File

@ -1102,7 +1102,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (ent is SceneObjectGroup)
{
((SceneObjectGroup) ent).RemoveScriptInstances();
((SceneObjectGroup) ent).RemoveScriptInstances(false);
}
}
}
@ -1977,13 +1977,15 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="silent">Suppress broadcasting changes to other clients.</param>
public void DeleteSceneObject(SceneObjectGroup group, bool silent)
{
// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
//SceneObjectPart rootPart = group.GetChildPart(group.UUID);
// Serialise calls to RemoveScriptInstances to avoid
// deadlocking on m_parts inside SceneObjectGroup
lock (m_deleting_scene_object)
{
group.RemoveScriptInstances();
group.RemoveScriptInstances(true);
}
foreach (SceneObjectPart part in group.Children.Values)
@ -2011,6 +2013,8 @@ namespace OpenSim.Region.Framework.Scenes
}
group.DeleteGroup(silent);
// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
}
/// <summary>
@ -2539,6 +2543,7 @@ namespace OpenSim.Region.Framework.Scenes
client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
client.OnObjectPermissions += HandleObjectPermissionsUpdate;
client.OnGrabObject += ProcessObjectGrab;
client.OnGrabUpdate += ProcessObjectGrabUpdate;
client.OnDeGrabObject += ProcessObjectDeGrab;
client.OnUndo += m_sceneGraph.HandleUndo;
client.OnObjectDescription += m_sceneGraph.PrimDescription;

View File

@ -479,25 +479,35 @@ namespace OpenSim.Region.Framework.Scenes
if (part == null)
return;
if (!m_parentScene.Permissions.CanTakeObject(
part.UUID, remoteClient.AgentId))
if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
return;
// Calls attach with a Zero position
AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false);
if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false))
{
m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
// Save avatar attachment information
ScenePresence presence;
if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
{
m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt);
m_log.Info(
"[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
+ ", AttachmentPoint: " + AttachmentPt);
m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
}
}
}
public SceneObjectGroup RezSingleAttachment(
IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
/// <summary>
/// Rez an attachment
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="AttachmentPt"></param>
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
IInventoryAccessModule invAccess = m_parentScene.RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null)
@ -560,7 +570,17 @@ namespace OpenSim.Region.Framework.Scenes
}
}
protected internal void AttachObject(
/// <summary>
/// Attach a scene object to an avatar.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="objectLocalID"></param>
/// <param name="AttachmentPt"></param>
/// <param name="rot"></param>
/// <param name="attachPos"></param>
/// <param name="silent"></param>
/// <returns>true if the attachment was successful, false otherwise</returns>
protected internal bool AttachObject(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
{
SceneObjectGroup group = GetGroupByPrim(objectLocalID);
@ -589,10 +609,8 @@ namespace OpenSim.Region.Framework.Scenes
// Stick it on left hand with Zero Offset from the attachment point.
AttachmentPt = (uint)AttachmentPoint.LeftHand;
attachPos = Vector3.Zero;
}
group.SetAttachmentPoint((byte)AttachmentPt);
group.AbsolutePosition = attachPos;
@ -620,10 +638,16 @@ namespace OpenSim.Region.Framework.Scenes
else
{
remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false);
return false;
}
}
else
{
m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID);
return false;
}
return true;
}
protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance)

View File

@ -74,13 +74,17 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// Stop the scripts contained in all the prims in this group
/// </summary>
public void RemoveScriptInstances()
/// <param name="sceneObjectBeingDeleted">
/// Should be true if these scripts are being removed because the scene
/// object is being deleted. This will prevent spurious updates to the client.
/// </param>
public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
{
lock (m_parts)
{
foreach (SceneObjectPart part in m_parts.Values)
{
part.Inventory.RemoveScriptInstances();
part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
}
}
}

View File

@ -235,6 +235,9 @@ namespace OpenSim.Region.Framework.Scenes
set { m_rootPart.GroupID = value; }
}
/// <value>
/// The parts of this scene object group. You must lock this property before using it.
/// </value>
public Dictionary<UUID, SceneObjectPart> Children
{
get { return m_parts; }
@ -2097,7 +2100,7 @@ namespace OpenSim.Region.Framework.Scenes
}
/// <summary>
/// Get a child part with a given UUID
/// Get a part with a given UUID
/// </summary>
/// <param name="primID"></param>
/// <returns>null if a child part with the primID was not found</returns>
@ -2112,7 +2115,7 @@ namespace OpenSim.Region.Framework.Scenes
}
/// <summary>
/// Get a child part with a given local ID
/// Get a part with a given local ID
/// </summary>
/// <param name="localID"></param>
/// <returns>null if a child part with the local ID was not found</returns>

View File

@ -90,12 +90,38 @@ namespace OpenSim.Region.Framework.Scenes
SCALE = 0x40
}
public enum PrimType : int
{
BOX = 0,
CYLINDER = 1,
PRISM = 2,
SPHERE = 3,
TORUS = 4,
TUBE = 5,
RING = 6,
SCULPT = 7
}
#endregion Enumerations
public class SceneObjectPart : IScriptHost
{
/// <value>
/// Denote all sides of the prim
/// </value>
public const int ALL_SIDES = -1;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <value>
/// Is this sop a root part?
/// </value>
[XmlIgnore]
public bool IsRoot
{
get { return ParentGroup.RootPart == this; }
}
// use only one serializer to give the runtime a chance to optimize it (it won't do that if you
// use a new instance every time)
private static XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart));
@ -737,6 +763,9 @@ namespace OpenSim.Region.Framework.Scenes
}
}
/// <value>
/// Text color.
/// </value>
public Color Color
{
get { return m_color; }
@ -1901,7 +1930,7 @@ namespace OpenSim.Region.Framework.Scenes
foreach (uint localId in startedColliders)
{
if (localId == 0)
return;
continue;
// always running this check because if the user deletes the object it would return a null reference.
if (m_parentGroup == null)
return;
@ -2037,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes
{
// always running this check because if the user deletes the object it would return a null reference.
if (localId == 0)
return;
continue;
if (m_parentGroup == null)
return;
@ -2169,7 +2198,7 @@ namespace OpenSim.Region.Framework.Scenes
foreach (uint localId in endedColliders)
{
if (localId == 0)
return;
continue;
// always running this check because if the user deletes the object it would return a null reference.
if (m_parentGroup == null)
@ -2533,6 +2562,8 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void ScheduleFullUpdate()
{
// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
if (m_parentGroup != null)
{
m_parentGroup.QueueForUpdateCheck();
@ -2953,6 +2984,178 @@ namespace OpenSim.Region.Framework.Scenes
}
}
/// <summary>
/// Set the color of prim faces
/// </summary>
/// <param name="color"></param>
/// <param name="face"></param>
public void SetFaceColor(Vector3 color, int face)
{
Primitive.TextureEntry tex = Shape.Textures;
Color4 texcolor;
if (face >= 0 && face < GetNumberOfSides())
{
texcolor = tex.CreateFace((uint)face).RGBA;
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
tex.FaceTextures[face].RGBA = texcolor;
UpdateTexture(tex);
return;
}
else if (face == ALL_SIDES)
{
for (uint i = 0; i < GetNumberOfSides(); i++)
{
if (tex.FaceTextures[i] != null)
{
texcolor = tex.FaceTextures[i].RGBA;
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
tex.FaceTextures[i].RGBA = texcolor;
}
texcolor = tex.DefaultTexture.RGBA;
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
tex.DefaultTexture.RGBA = texcolor;
}
UpdateTexture(tex);
return;
}
}
/// <summary>
/// Get the number of sides that this part has.
/// </summary>
/// <returns></returns>
public int GetNumberOfSides()
{
int ret = 0;
bool hasCut;
bool hasHollow;
bool hasDimple;
bool hasProfileCut;
PrimType primType = GetPrimType();
HasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
switch (primType)
{
case PrimType.BOX:
ret = 6;
if (hasCut) ret += 2;
if (hasHollow) ret += 1;
break;
case PrimType.CYLINDER:
ret = 3;
if (hasCut) ret += 2;
if (hasHollow) ret += 1;
break;
case PrimType.PRISM:
ret = 5;
if (hasCut) ret += 2;
if (hasHollow) ret += 1;
break;
case PrimType.SPHERE:
ret = 1;
if (hasCut) ret += 2;
if (hasDimple) ret += 2;
if (hasHollow) ret += 1;
break;
case PrimType.TORUS:
ret = 1;
if (hasCut) ret += 2;
if (hasProfileCut) ret += 2;
if (hasHollow) ret += 1;
break;
case PrimType.TUBE:
ret = 4;
if (hasCut) ret += 2;
if (hasProfileCut) ret += 2;
if (hasHollow) ret += 1;
break;
case PrimType.RING:
ret = 3;
if (hasCut) ret += 2;
if (hasProfileCut) ret += 2;
if (hasHollow) ret += 1;
break;
case PrimType.SCULPT:
ret = 1;
break;
}
return ret;
}
/// <summary>
/// Tell us what type this prim is
/// </summary>
/// <param name="primShape"></param>
/// <returns></returns>
public PrimType GetPrimType()
{
if (Shape.SculptEntry)
return PrimType.SCULPT;
if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
{
if (Shape.PathCurve == (byte)Extrusion.Straight)
return PrimType.BOX;
else if (Shape.PathCurve == (byte)Extrusion.Curve1)
return PrimType.TUBE;
}
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
{
if (Shape.PathCurve == (byte)Extrusion.Straight)
return PrimType.CYLINDER;
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
else if (Shape.PathCurve == (byte)Extrusion.Curve1)
return PrimType.TORUS;
}
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
{
if (Shape.PathCurve == (byte)Extrusion.Curve1 || Shape.PathCurve == (byte)Extrusion.Curve2)
return PrimType.SPHERE;
}
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
{
if (Shape.PathCurve == (byte)Extrusion.Straight)
return PrimType.PRISM;
else if (Shape.PathCurve == (byte)Extrusion.Curve1)
return PrimType.RING;
}
return PrimType.BOX;
}
/// <summary>
/// Tell us if this object has cut, hollow, dimple, and other factors affecting the number of faces
/// </summary>
/// <param name="primType"></param>
/// <param name="shape"></param>
/// <param name="hasCut"></param>
/// <param name="hasHollow"></param>
/// <param name="hasDimple"></param>
/// <param name="hasProfileCut"></param>
protected static void HasCutHollowDimpleProfileCut(PrimType primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
out bool hasDimple, out bool hasProfileCut)
{
if (primType == PrimType.BOX
||
primType == PrimType.CYLINDER
||
primType == PrimType.PRISM)
hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
else
hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
hasHollow = shape.ProfileHollow > 0;
hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
hasProfileCut = hasDimple; // is it the same thing?
}
public void SetGroup(UUID groupID, IClientAPI client)
{
_groupID = groupID;
@ -2984,6 +3187,11 @@ namespace OpenSim.Region.Framework.Scenes
}
}
/// <summary>
/// Set the events that this part will pass on to listeners.
/// </summary>
/// <param name="scriptid"></param>
/// <param name="events"></param>
public void SetScriptEvents(UUID scriptid, int events)
{
// scriptEvents oldparts;
@ -3936,9 +4144,13 @@ namespace OpenSim.Region.Framework.Scenes
ScheduleFullUpdate();
}
// Added to handle bug in libsecondlife's TextureEntry.ToBytes()
// not handling RGBA properly. Cycles through, and "fixes" the color
// info
/// <summary>
/// Update the textures on the part.
/// </summary>
/// Added to handle bug in libsecondlife's TextureEntry.ToBytes()
/// not handling RGBA properly. Cycles through, and "fixes" the color
/// info
/// <param name="tex"></param>
public void UpdateTexture(Primitive.TextureEntry tex)
{
//Color4 tmpcolor;
@ -4042,6 +4254,8 @@ namespace OpenSim.Region.Framework.Scenes
if (m_parentGroup == null)
{
// m_log.DebugFormat(
// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId);
ScheduleFullUpdate();
return;
}
@ -4058,10 +4272,16 @@ namespace OpenSim.Region.Framework.Scenes
LocalFlags=(PrimFlags)objectflagupdate;
if (m_parentGroup != null && m_parentGroup.RootPart == this)
{
m_parentGroup.aggregateScriptEvents();
}
else
{
// m_log.DebugFormat(
// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId);
ScheduleFullUpdate();
}
}
public int registerTargetWaypoint(Vector3 target, float tolerance)
{

View File

@ -229,7 +229,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// Stop all the scripts in this prim.
/// </summary>
public void RemoveScriptInstances()
/// <param name="sceneObjectBeingDeleted">
/// Should be true if these scripts are being removed because the scene
/// object is being deleted. This will prevent spurious updates to the client.
/// </param>
public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
{
lock (Items)
{
@ -237,8 +241,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if ((int)InventoryType.LSL == item.InvType)
{
RemoveScriptInstance(item.ItemID);
m_part.RemoveScriptEvents(item.ItemID);
RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
}
}
}
@ -265,9 +268,13 @@ namespace OpenSim.Region.Framework.Scenes
{
if (stateSource == 1 && // Prim crossing
m_part.ParentGroup.Scene.m_trustBinaries)
{
lock (m_items)
{
m_items[item.ItemID].PermsMask = 0;
m_items[item.ItemID].PermsGranter = UUID.Zero;
}
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
m_part.ParentGroup.AddActiveScriptCount(1);
@ -275,7 +282,8 @@ namespace OpenSim.Region.Framework.Scenes
return;
}
m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset)
m_part.ParentGroup.Scene.AssetService.Get(
item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset)
{
if (null == asset)
{
@ -289,20 +297,24 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_part.ParentGroup.m_savedScriptState != null)
RestoreSavedScriptState(item.OldItemID, item.ItemID);
lock (m_items)
{
m_items[item.ItemID].PermsMask = 0;
m_items[item.ItemID].PermsGranter = UUID.Zero;
}
string script = Utils.BytesToString(asset.Data);
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
m_part.ParentGroup.AddActiveScriptCount(1);
m_part.ScheduleFullUpdate();
}
});
}
);
}
}
static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
private void RestoreSavedScriptState(UUID oldID, UUID newID)
{
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
@ -387,10 +399,25 @@ namespace OpenSim.Region.Framework.Scenes
/// Stop a script which is in this prim's inventory.
/// </summary>
/// <param name="itemId"></param>
public void RemoveScriptInstance(UUID itemId)
/// <param name="sceneObjectBeingDeleted">
/// Should be true if this script is being removed because the scene
/// object is being deleted. This will prevent spurious updates to the client.
/// </param>
public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
{
bool scriptPresent = false;
lock (m_items)
{
if (m_items.ContainsKey(itemId))
scriptPresent = true;
}
if (scriptPresent)
{
if (!sceneObjectBeingDeleted)
m_part.RemoveScriptEvents(itemId);
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId);
m_part.ParentGroup.AddActiveScriptCount(-1);
}
@ -458,13 +485,19 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="item"></param>
public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
{
List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
List<TaskInventoryItem> il;
lock (m_items)
{
il = new List<TaskInventoryItem>(m_items.Values);
}
foreach (TaskInventoryItem i in il)
{
if (i.Name == item.Name)
{
if (i.InvType == (int)InventoryType.LSL)
RemoveScriptInstance(i.ItemID);
RemoveScriptInstance(i.ItemID, false);
RemoveInventoryItem(i.ItemID);
break;
@ -540,11 +573,37 @@ namespace OpenSim.Region.Framework.Scenes
public TaskInventoryItem GetInventoryItem(UUID itemId)
{
TaskInventoryItem item;
lock (m_items)
m_items.TryGetValue(itemId, out item);
return item;
}
/// <summary>
/// Get inventory items by name.
/// </summary>
/// <param name="name"></param>
/// <returns>
/// A list of inventory items with that name.
/// If no inventory item has that name then an empty list is returned.
/// </returns>
public IList<TaskInventoryItem> GetInventoryItems(string name)
{
IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
lock (m_items)
{
foreach (TaskInventoryItem item in m_items.Values)
{
if (item.Name == name)
items.Add(item);
}
}
return items;
}
/// <summary>
/// Update an existing inventory item.
/// </summary>
@ -612,6 +671,7 @@ namespace OpenSim.Region.Framework.Scenes
int type = m_items[itemID].InvType;
if (type == 10) // Script
{
m_part.RemoveScriptEvents(itemID);
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
}
m_items.Remove(itemID);
@ -841,6 +901,8 @@ namespace OpenSim.Region.Framework.Scenes
{
uint mask=0x7fffffff;
lock (m_items)
{
foreach (TaskInventoryItem item in m_items.Values)
{
if (item.InvType != (int)InventoryType.Object)
@ -869,10 +931,14 @@ namespace OpenSim.Region.Framework.Scenes
if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
mask &= ~(uint)PermissionMask.Modify;
}
}
return mask;
}
public void ApplyNextOwnerPermissions()
{
lock (m_items)
{
foreach (TaskInventoryItem item in m_items.Values)
{
@ -890,11 +956,14 @@ namespace OpenSim.Region.Framework.Scenes
item.BasePermissions &= item.NextPermissions;
item.EveryonePermissions &= item.NextPermissions;
}
}
m_part.TriggerScriptChangedEvent(Changed.OWNER);
}
public void ApplyGodPermissions(uint perms)
{
lock (m_items)
{
foreach (TaskInventoryItem item in m_items.Values)
{
@ -902,8 +971,11 @@ namespace OpenSim.Region.Framework.Scenes
item.BasePermissions = perms;
}
}
}
public bool ContainsScripts()
{
lock (m_items)
{
foreach (TaskInventoryItem item in m_items.Values)
{
@ -912,6 +984,8 @@ namespace OpenSim.Region.Framework.Scenes
return true;
}
}
}
return false;
}
@ -919,8 +993,11 @@ namespace OpenSim.Region.Framework.Scenes
{
List<UUID> ret = new List<UUID>();
lock (m_items)
{
foreach (TaskInventoryItem item in m_items.Values)
ret.Add(item.ItemID);
}
return ret;
}
@ -933,6 +1010,8 @@ namespace OpenSim.Region.Framework.Scenes
if (engines == null) // No engine at all
return ret;
lock (m_items)
{
foreach (TaskInventoryItem item in m_items.Values)
{
if (item.InvType == (int)InventoryType.LSL)
@ -952,6 +1031,8 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
}
return ret;
}
}

View File

@ -104,6 +104,8 @@ namespace OpenSim.Region.Framework.Scenes
}
protected ScenePresenceAnimator m_animator;
protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
@ -217,7 +219,6 @@ namespace OpenSim.Region.Framework.Scenes
protected AvatarAppearance m_appearance;
protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
public List<SceneObjectGroup> Attachments
{
get { return m_attachments; }
@ -637,11 +638,15 @@ namespace OpenSim.Region.Framework.Scenes
#region Constructor(s)
private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo)
public ScenePresence()
{
m_animator = new ScenePresenceAnimator(this);
m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
CreateSceneViewer();
m_animator = new ScenePresenceAnimator(this);
}
private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
{
m_rootRegionHandle = reginfo.RegionHandle;
m_controllingClient = client;
m_firstname = m_controllingClient.FirstName;
@ -665,7 +670,6 @@ namespace OpenSim.Region.Framework.Scenes
m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize);
m_reprioritization_timer.AutoReset = false;
AdjustKnownSeeds();
// TODO: I think, this won't send anything, as we are still a child here...
@ -1294,6 +1298,12 @@ namespace OpenSim.Region.Framework.Scenes
if (m_allowMovement)
{
if (agentData.UseClientAgentPosition)
{
m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
m_moveToPositionTarget = agentData.ClientAgentPosition;
}
int i = 0;
bool update_rotation = false;
@ -1400,7 +1410,7 @@ namespace OpenSim.Region.Framework.Scenes
if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving))
{
//Check the error term of the current position in relation to the target position
if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 1.5f)
if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f)
{
// we are close enough to the target
m_moveToPositionTarget = Vector3.Zero;
@ -2795,8 +2805,15 @@ namespace OpenSim.Region.Framework.Scenes
protected void CrossToNewRegion()
{
InTransit();
try
{
m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying);
}
catch
{
m_scene.CrossAgentToNewRegion(this, false);
}
}
public void InTransit()
{
@ -2873,7 +2890,6 @@ namespace OpenSim.Region.Framework.Scenes
{
RemoveNeighbourRegion(handle);
}
}
#endregion
@ -3037,7 +3053,7 @@ namespace OpenSim.Region.Framework.Scenes
List<int> attPoints = m_appearance.GetAttachedPoints();
if (attPoints != null)
{
m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count);
//m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count);
int i = 0;
AttachmentData[] attachs = new AttachmentData[attPoints.Count];
foreach (int point in attPoints)
@ -3261,17 +3277,15 @@ namespace OpenSim.Region.Framework.Scenes
uint killerObj = 0;
foreach (uint localid in coldata.Keys)
{
if (coldata[localid].PenetrationDepth <= 0.10f || m_invulnerable)
continue;
//if (localid == 0)
//continue;
SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
SceneObjectPart part = Scene.GetSceneObjectPart(localid);
if (part != null && part.ParentGroup.Damage != -1.0f)
Health -= part.ParentGroup.Damage;
else
{
if (coldata[localid].PenetrationDepth >= 0.10f)
Health -= coldata[localid].PenetrationDepth * 5.0f;
}
if (Health <= 0.0f)
{
@ -3290,8 +3304,6 @@ namespace OpenSim.Region.Framework.Scenes
if (m_health <= 0)
m_scene.EventManager.TriggerAvatarKill(killerObj, this);
}
}
public void setHealthWithUpdate(float health)
@ -3338,13 +3350,6 @@ namespace OpenSim.Region.Framework.Scenes
m_animator = null;
}
public ScenePresence()
{
m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
CreateSceneViewer();
m_animator = new ScenePresenceAnimator(this);
}
public void AddAttachment(SceneObjectGroup gobj)
{
lock (m_attachments)

View File

@ -116,7 +116,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
static string ConvertMRMKeywords(string script)
{
script = script.Replace("microthreaded void ", "IEnumerable");
script = script.Replace("microthreaded void", "IEnumerable");
script = script.Replace("relax;", "yield return null;");
return script;

View File

@ -1575,6 +1575,7 @@ Console.WriteLine(" JointCreateFixed");
{
//Console.WriteLine("Move " + m_primName);
if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
/*
// NON-'VEHICLES' are dealt with here
if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
{
@ -1587,6 +1588,7 @@ Console.WriteLine(" JointCreateFixed");
avel2.Z = 0;
d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z);
}
*/
//float PID_P = 900.0f;
float m_mass = CalculateMass();

View File

@ -55,7 +55,7 @@ using OpenSim.Services.Interfaces;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
using AssetLandmark = OpenSim.Framework.AssetLandmark;
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
@ -1331,44 +1331,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
SetColor(m_host, color, face);
}
if (face == ScriptBaseClass.ALL_SIDES)
face = SceneObjectPart.ALL_SIDES;
protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
{
Primitive.TextureEntry tex = part.Shape.Textures;
Color4 texcolor;
if (face >= 0 && face < GetNumberOfSides(part))
{
texcolor = tex.CreateFace((uint)face).RGBA;
texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
tex.FaceTextures[face].RGBA = texcolor;
part.UpdateTexture(tex);
return;
}
else if (face == ScriptBaseClass.ALL_SIDES)
{
for (uint i = 0; i < GetNumberOfSides(part); i++)
{
if (tex.FaceTextures[i] != null)
{
texcolor = tex.FaceTextures[i].RGBA;
texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
tex.FaceTextures[i].RGBA = texcolor;
}
texcolor = tex.DefaultTexture.RGBA;
texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
tex.DefaultTexture.RGBA = texcolor;
}
part.UpdateTexture(tex);
return;
}
m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
}
public void SetTexGen(SceneObjectPart part, int face,int style)
@ -1515,7 +1481,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
int i;
double sum = 0.0;
for (i = 0 ; i < GetNumberOfSides(part) ; i++)
for (i = 0 ; i < GetNumberOfSides(part); i++)
sum += (double)tex.GetFace((uint)i).RGBA.A;
return sum;
}
@ -1662,7 +1628,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
int i;
for (i = 0 ; i < GetNumberOfSides(part) ; i++)
for (i = 0 ; i < GetNumberOfSides(part); i++)
{
texcolor = tex.GetFace((uint)i).RGBA;
rgb.x += texcolor.R;
@ -3415,7 +3381,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
List<SceneObjectPart> parts = GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
SetColor(part, color, face);
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
}
public void llCreateLink(string target, int parent)
@ -4262,7 +4228,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
if (item.Type == 10 && item.ItemID == m_itemID)
{
result = item.Name!=null?item.Name:String.Empty;
result = item.Name != null ? item.Name : String.Empty;
break;
}
}
@ -4271,63 +4237,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return result;
}
// this function to understand which shape it is (taken from meshmerizer)
// quite useful can be used by meshmerizer to have a centralized point of understanding the shape
// except that it refers to scripting constants
public int getScriptPrimType(PrimitiveBaseShape primShape)
{
if (primShape.SculptEntry)
return ScriptBaseClass.PRIM_TYPE_SCULPT;
if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
{
if (primShape.PathCurve == (byte)Extrusion.Straight)
return ScriptBaseClass.PRIM_TYPE_BOX;
else if (primShape.PathCurve == (byte)Extrusion.Curve1)
return ScriptBaseClass.PRIM_TYPE_TUBE;
}
else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
{
if (primShape.PathCurve == (byte)Extrusion.Straight)
return ScriptBaseClass.PRIM_TYPE_CYLINDER;
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
else if (primShape.PathCurve == (byte)Extrusion.Curve1)
return ScriptBaseClass.PRIM_TYPE_TORUS;
}
else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
{
if (primShape.PathCurve == (byte)Extrusion.Curve1 || primShape.PathCurve == (byte)Extrusion.Curve2)
return ScriptBaseClass.PRIM_TYPE_SPHERE;
}
else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
{
if (primShape.PathCurve == (byte)Extrusion.Straight)
return ScriptBaseClass.PRIM_TYPE_PRISM;
else if (primShape.PathCurve == (byte)Extrusion.Curve1)
return ScriptBaseClass.PRIM_TYPE_RING;
}
return ScriptBaseClass.PRIM_TYPE_BOX;
}
// Helper functions to understand if object has cut, hollow, dimple, and other affecting number of faces
protected void hasCutHollowDimpleProfileCut(int primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
out bool hasDimple, out bool hasProfileCut)
{
if (primType == ScriptBaseClass.PRIM_TYPE_BOX
||
primType == ScriptBaseClass.PRIM_TYPE_CYLINDER
||
primType == ScriptBaseClass.PRIM_TYPE_PRISM)
hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
else
hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
hasHollow = shape.ProfileHollow > 0;
hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
hasProfileCut = hasDimple; // is it the same thing?
}
public LSL_Integer llGetNumberOfSides()
{
m_host.AddScriptLPS(1);
@ -4337,61 +4246,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected int GetNumberOfSides(SceneObjectPart part)
{
int ret = 0;
bool hasCut;
bool hasHollow;
bool hasDimple;
bool hasProfileCut;
int sides = part.GetNumberOfSides();
int primType = getScriptPrimType(part.Shape);
hasCutHollowDimpleProfileCut(primType, part.Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
switch (primType)
if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0)
{
case ScriptBaseClass.PRIM_TYPE_BOX:
ret = 6;
if (hasCut) ret += 2;
if (hasHollow) ret += 1;
break;
case ScriptBaseClass.PRIM_TYPE_CYLINDER:
ret = 3;
if (hasCut) ret += 2;
if (hasHollow) ret += 1;
break;
case ScriptBaseClass.PRIM_TYPE_PRISM:
ret = 5;
if (hasCut) ret += 2;
if (hasHollow) ret += 1;
break;
case ScriptBaseClass.PRIM_TYPE_SPHERE:
ret = 1;
if (hasCut) ret += 2;
if (hasDimple) ret += 2;
if (hasHollow) ret += 3; // Emulate lsl on secondlife (according to documentation it should have added only +1)
break;
case ScriptBaseClass.PRIM_TYPE_TORUS:
ret = 1;
if (hasCut) ret += 2;
if (hasProfileCut) ret += 2;
if (hasHollow) ret += 1;
break;
case ScriptBaseClass.PRIM_TYPE_TUBE:
ret = 4;
if (hasCut) ret += 2;
if (hasProfileCut) ret += 2;
if (hasHollow) ret += 1;
break;
case ScriptBaseClass.PRIM_TYPE_RING:
ret = 3;
if (hasCut) ret += 2;
if (hasProfileCut) ret += 2;
if (hasHollow) ret += 1;
break;
case ScriptBaseClass.PRIM_TYPE_SCULPT:
ret = 1;
break;
// Make up for a bug where LSL shows 4 sides rather than 2
sides += 2;
}
return ret;
return sides;
}
@ -4418,8 +4281,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
*/
// Xantor 29/apr/2008
// Returns rotation described by rotating angle radians about axis.
// q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2))
@ -7020,10 +6881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_Vector color=rules.GetVector3Item(idx++);
double alpha=(double)rules.GetLSLFloatItem(idx++);
SetColor(part, color, face);
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
SetAlpha(part, alpha, face);
break;
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
if (remain < 7)
return;
@ -7039,6 +6901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force);
break;
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
if (remain < 5)
return;
@ -7051,6 +6914,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetPointLight(part, light, lightcolor, intensity, radius, falloff);
break;
case (int)ScriptBaseClass.PRIM_GLOW:
if (remain < 2)
return;
@ -7060,6 +6924,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetGlow(part, face, glow);
break;
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
if (remain < 3)
return;
@ -7070,6 +6935,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetShiny(part, face, shiny, bump);
break;
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
if (remain < 2)
return;
@ -7077,6 +6943,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
bool st = rules.GetLSLIntegerItem(idx++);
SetFullBright(part, face , st);
break;
case (int)ScriptBaseClass.PRIM_MATERIAL:
if (remain < 1)
return;
@ -7086,6 +6953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.Material = Convert.ToByte(mat);
break;
case (int)ScriptBaseClass.PRIM_PHANTOM:
if (remain < 1)
return;
@ -7100,6 +6968,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.ScriptSetPhantomStatus(phantom);
break;
case (int)ScriptBaseClass.PRIM_PHYSICS:
if (remain < 1)
return;
@ -7113,6 +6982,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.ScriptSetPhysicsStatus(physics);
break;
case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
if (remain < 1)
return;
@ -7380,7 +7250,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules)
{
LSL_List res = new LSL_List();
int idx=0;
while (idx < rules.Length)
@ -7442,7 +7311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE:
// implementing box
PrimitiveBaseShape Shape = part.Shape;
int primType = getScriptPrimType(part.Shape);
int primType = (int)part.GetPrimType();
res.Add(new LSL_Integer(primType));
double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX
double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY.
@ -7522,7 +7391,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
Primitive.TextureEntry tex = part.Shape.Textures;
if (face == ScriptBaseClass.ALL_SIDES)
{
for (face = 0 ; face < GetNumberOfSides(part) ; face++)
for (face = 0 ; face < GetNumberOfSides(part); face++)
{
Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
@ -7564,7 +7433,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
Color4 texcolor;
if (face == ScriptBaseClass.ALL_SIDES)
{
for (face = 0 ; face < GetNumberOfSides(part) ; face++)
for (face = 0 ; face < GetNumberOfSides(part); face++)
{
texcolor = tex.GetFace((uint)face).RGBA;
res.Add(new LSL_Vector(texcolor.R,

View File

@ -55,6 +55,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_log.Info("[XEngine] Hooking up to server events");
myScriptEngine.World.EventManager.OnAttach += attach;
myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
myScriptEngine.World.EventManager.OnObjectGrabbing += touch;
myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end;
myScriptEngine.World.EventManager.OnScriptChangedEvent += changed;
myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target;
@ -148,7 +149,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
}
public void touch(uint localID, uint originalID, Vector3 offsetPos,
IClientAPI remoteClient)
IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
// Add to queue for all scripts in ObjectID object
DetectParams[] det = new DetectParams[1];
@ -172,6 +173,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID);
det[0].LinkNum = originalPart.LinkNum;
}
if (surfaceArgs != null)
{
det[0].SurfaceTouchArgs = surfaceArgs;
}
myScriptEngine.PostObjectEvent(localID, new EventParams(
"touch", new Object[] { new LSL_Types.LSLInteger(1) },

View File

@ -806,12 +806,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
instance.ClearQueue();
instance.Stop(0);
SceneObjectPart part =
m_Scene.GetSceneObjectPart(localID);
if (part != null)
part.RemoveScriptEvents(itemID);
// bool objectRemoved = false;
lock (m_PrimObjects)
@ -846,7 +840,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
if (handlerObjectRemoved != null)
{
SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
handlerObjectRemoved(part.UUID);
}
CleanAssemblies();
}

View File

@ -63,7 +63,7 @@ namespace OpenSim.Server.Handlers.Asset
if (p.Length > 0)
{
result = m_AssetService.Delete(p[0]);
// result = m_AssetService.Delete(p[0]);
}
XmlSerializer xs = new XmlSerializer(typeof(bool));

View File

@ -0,0 +1,251 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Xml;
using log4net;
using Nini.Config;
namespace Careminster
{
/// <summary>
/// Loads the Configuration files into nIni
/// </summary>
public class ConfigurationLoader
{
/// <summary>
/// A source of Configuration data
/// </summary>
protected IConfigSource m_config;
/// <summary>
/// Console logger
/// </summary>
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
public ConfigurationLoader()
{
}
/// <summary>
/// Loads the region configuration
/// </summary>
/// <param name="argvSource">Parameters passed into the process when started</param>
/// <param name="configSettings"></param>
/// <param name="networkInfo"></param>
/// <returns>A configuration that gets passed to modules</returns>
public IConfigSource LoadConfigSettings()
{
bool iniFileExists = false;
List<string> sources = new List<string>();
string iniFileName = "OpenSim.ini";
string iniFilePath = Path.Combine(".", iniFileName);
if (IsUri(iniFileName))
{
if (!sources.Contains(iniFileName))
sources.Add(iniFileName);
}
else
{
if (File.Exists(iniFilePath))
{
if (!sources.Contains(iniFilePath))
sources.Add(iniFilePath);
}
}
m_config = new IniConfigSource();
m_config.Merge(DefaultConfig());
m_log.Info("[CONFIG] Reading configuration settings");
if (sources.Count == 0)
{
m_log.FatalFormat("[CONFIG] Could not load any configuration");
m_log.FatalFormat("[CONFIG] Did you copy the OpenSim.ini.example file to OpenSim.ini?");
Environment.Exit(1);
}
for (int i = 0 ; i < sources.Count ; i++)
{
if (ReadConfig(sources[i]))
iniFileExists = true;
AddIncludes(sources);
}
if (!iniFileExists)
{
m_log.FatalFormat("[CONFIG] Could not load any configuration");
m_log.FatalFormat("[CONFIG] Configuration exists, but there was an error loading it!");
Environment.Exit(1);
}
return m_config;
}
/// <summary>
/// Adds the included files as ini configuration files
/// </summary>
/// <param name="sources">List of URL strings or filename strings</param>
private void AddIncludes(List<string> sources)
{
//loop over config sources
foreach (IConfig config in m_config.Configs)
{
// Look for Include-* in the key name
string[] keys = config.GetKeys();
foreach (string k in keys)
{
if (k.StartsWith("Include-"))
{
// read the config file to be included.
string file = config.GetString(k);
if (IsUri(file))
{
if (!sources.Contains(file))
sources.Add(file);
}
else
{
string basepath = Path.GetFullPath(".");
string path = Path.Combine(basepath, file);
string[] paths = Util.Glob(path);
foreach (string p in paths)
{
if (!sources.Contains(p))
sources.Add(p);
}
}
}
}
}
}
/// <summary>
/// Check if we can convert the string to a URI
/// </summary>
/// <param name="file">String uri to the remote resource</param>
/// <returns>true if we can convert the string to a Uri object</returns>
bool IsUri(string file)
{
Uri configUri;
return Uri.TryCreate(file, UriKind.Absolute,
out configUri) && configUri.Scheme == Uri.UriSchemeHttp;
}
/// <summary>
/// Provide same ini loader functionality for standard ini and master ini - file system or XML over http
/// </summary>
/// <param name="iniPath">Full path to the ini</param>
/// <returns></returns>
private bool ReadConfig(string iniPath)
{
bool success = false;
if (!IsUri(iniPath))
{
m_log.InfoFormat("[CONFIG] Reading configuration file {0}",
Path.GetFullPath(iniPath));
m_config.Merge(new IniConfigSource(iniPath));
success = true;
}
else
{
m_log.InfoFormat("[CONFIG] {0} is a http:// URI, fetching ...",
iniPath);
// The ini file path is a http URI
// Try to read it
//
try
{
XmlReader r = XmlReader.Create(iniPath);
XmlConfigSource cs = new XmlConfigSource(r);
m_config.Merge(cs);
success = true;
}
catch (Exception e)
{
m_log.FatalFormat("[CONFIG] Exception reading config from URI {0}\n" + e.ToString(), iniPath);
Environment.Exit(1);
}
}
return success;
}
/// <summary>
/// Setup a default config values in case they aren't present in the ini file
/// </summary>
/// <returns>A Configuration source containing the default configuration</returns>
private static IConfigSource DefaultConfig()
{
IConfigSource defaultConfig = new IniConfigSource();
{
IConfig config = defaultConfig.Configs["Startup"];
if (null == config)
config = defaultConfig.AddConfig("Startup");
config.Set("region_info_source", "filesystem");
config.Set("gridmode", false);
config.Set("physics", "OpenDynamicsEngine");
config.Set("meshing", "Meshmerizer");
config.Set("physical_prim", true);
config.Set("see_into_this_sim_from_neighbor", true);
config.Set("serverside_object_permissions", false);
config.Set("storage_plugin", "OpenSim.Data.SQLite.dll");
config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3");
config.Set("storage_prim_inventories", true);
config.Set("startup_console_commands_file", String.Empty);
config.Set("shutdown_console_commands_file", String.Empty);
config.Set("DefaultScriptEngine", "XEngine");
config.Set("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
// life doesn't really work without this
config.Set("EventQueue", true);
}
{
IConfig config = defaultConfig.Configs["StandAlone"];
if (null == config)
config = defaultConfig.AddConfig("StandAlone");
config.Set("accounts_authenticate", true);
config.Set("welcome_message", "Welcome to OpenSimulator");
config.Set("inventory_plugin", "OpenSim.Data.SQLite.dll");
config.Set("inventory_source", "");
config.Set("userDatabase_plugin", "OpenSim.Data.SQLite.dll");
config.Set("user_source", "");
config.Set("LibrariesXMLFile", string.Format(".{0}inventory{0}Libraries.xml", Path.DirectorySeparatorChar));
}
{
IConfig config = defaultConfig.Configs["Network"];
if (null == config)
config = defaultConfig.AddConfig("Network");
config.Set("default_location_x", 1000);
config.Set("default_location_y", 1000);
config.Set("grid_send_key", "null");
config.Set("grid_recv_key", "null");
config.Set("user_send_key", "null");
config.Set("user_recv_key", "null");
config.Set("secure_inventory_server", "true");
}
return defaultConfig;
}
}
}

View File

@ -0,0 +1,108 @@
using Nini.Config;
using System;
namespace Careminster
{
public class Configger
{
public static int Main(string[] args)
{
ArgvConfigSource argvConfig = new ArgvConfigSource(args);
argvConfig.AddSwitch("Startup", "format", "f");
IConfig startupConfig = argvConfig.Configs["Startup"];
string format = startupConfig.GetString("format", "ini");
ConfigurationLoader loader = new ConfigurationLoader();
IConfigSource s = loader.LoadConfigSettings();
if (format == "mysql")
{
foreach (IConfig c in s.Configs)
{
foreach (string k in c.GetKeys())
{
string v = c.GetString(k);
if (k.StartsWith("Include-"))
continue;
Console.WriteLine("insert ignore into config (section, name, value) values ('{0}', '{1}', '{2}');", c.Name, k, v);
}
}
}
else if (format == "xml")
{
Console.WriteLine("<Nini>");
foreach (IConfig c in s.Configs)
{
int count = 0;
foreach (string k in c.GetKeys())
{
if (k.StartsWith("Include-"))
continue;
count++;
}
if (count > 0)
{
Console.WriteLine("<Section Name=\"{0}\">", c.Name);
foreach (string k in c.GetKeys())
{
string v = c.GetString(k);
if (k.StartsWith("Include-"))
continue;
Console.WriteLine(" <Key Name=\"{0}\" Value=\"{1}\" />", k, v);
Console.WriteLine("</Section>");
}
}
}
Console.WriteLine("</Nini>");
}
else if (format == "ini")
{
foreach (IConfig c in s.Configs)
{
int count = 0;
foreach (string k in c.GetKeys())
{
if (k.StartsWith("Include-"))
continue;
count++;
}
if (count > 0)
{
Console.WriteLine("[{0}]", c.Name);
foreach (string k in c.GetKeys())
{
string v = c.GetString(k);
if (k.StartsWith("Include-"))
continue;
Console.WriteLine("{0} = \"{1}\"", k, v);
}
Console.WriteLine();
}
}
}
else
{
Console.WriteLine("Error: unknown format: {0}", format);
}
return 0;
}
}
}

View File

@ -0,0 +1,79 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using log4net;
using Nini.Config;
namespace Careminster
{
public static class Util
{
public static string[] Glob(string path)
{
string vol=String.Empty;
if (Path.VolumeSeparatorChar != Path.DirectorySeparatorChar)
{
string[] vcomps = path.Split(new char[] {Path.VolumeSeparatorChar}, 2, StringSplitOptions.RemoveEmptyEntries);
if (vcomps.Length > 1)
{
path = vcomps[1];
vol = vcomps[0];
}
}
string[] comps = path.Split(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}, StringSplitOptions.RemoveEmptyEntries);
// Glob
path = vol;
if (vol != String.Empty)
path += new String(new char[] {Path.VolumeSeparatorChar, Path.DirectorySeparatorChar});
else
path = new String(new char[] {Path.DirectorySeparatorChar});
List<string> paths = new List<string>();
List<string> found = new List<string>();
paths.Add(path);
int compIndex = -1;
foreach (string c in comps)
{
compIndex++;
List<string> addpaths = new List<string>();
foreach (string p in paths)
{
string[] dirs = Directory.GetDirectories(p, c);
if (dirs.Length != 0)
{
foreach (string dir in dirs)
addpaths.Add(Path.Combine(path, dir));
}
// Only add files if that is the last path component
if (compIndex == comps.Length - 1)
{
string[] files = Directory.GetFiles(p, c);
foreach (string f in files)
found.Add(f);
}
}
paths = addpaths;
}
return found.ToArray();
}
}
}

View File

@ -123,3 +123,16 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
WelcomeMessage = "Welcome, Avatar!"
; * This is the new style grid service.
; * "Realm" is the table that is used for user lookup.
; * It defaults to "regions", which uses the legacy tables
; *
[GridService]
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
StorageProvider = "OpenSim.Data.MySQL.dll:MySqlRegionData"
ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=grid;"
Realm = "regions"
; If true, duplicate region names are allowed on the grid. If false, no duplicate names are allowed
; Default is false
; AllowDuplicateNames = "True"

2
bin/OpenSim.exe.config Normal file → Executable file
View File

@ -12,7 +12,7 @@
<log4net>
<appender name="Console" type="OpenSim.Framework.Console.OpenSimAppender, OpenSim.Framework.Console">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{HH:mm:ss} - %message%newline" />
<conversionPattern value="%date{HH:mm:ss} - %message" />
</layout>
</appender>

View File

@ -191,6 +191,7 @@
; This allows somne control over permissions
; please note that this still doesn't duplicate SL, and is not intended to
;region_owner_is_god = true
;region_manager_is_god = false
;parcel_owner_is_god = true
; Control user types that are allowed to create new scripts

View File

@ -1915,6 +1915,7 @@
<Reference name="OpenMetaverseTypes.dll"/>
<Reference name="OpenMetaverse.dll"/>
<Reference name="Nini.dll" />
<Reference name="Mono.Addins" />
<Reference name="log4net.dll" />
<Files>
<Match pattern="*.cs" recurse="true"/>
@ -1976,6 +1977,7 @@
<Reference name="log4net.dll"/>
<Reference name="protobuf-net"/>
<Reference name="MXP.dll"/>
<Reference name="Mono.Addins"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
@ -2486,6 +2488,7 @@
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="Mono.Data.SqliteClient"/>
<Reference name="Mono.Addins"/>
<!-- For scripting in funny languages by default -->
<Reference name="Microsoft.JScript"/>
@ -2557,6 +2560,28 @@
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Tools.Configger" path="OpenSim/Tools/Configger" type="Exe">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="Nini.dll"/>
<Reference name="log4net.dll"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<!-- Test Suite -->
<Project frameworkVersion="v3_5" name="OpenSim.TestSuite" path="OpenSim/TestSuite" type="Exe">
<Configuration name="Debug">
@ -2963,6 +2988,7 @@
<Match path="Agent/TextureSender/Tests" pattern="*.cs" recurse="true" />
<Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true" />
<Match path="World/Archiver/Tests" pattern="*.cs" recurse="true" />
<Match path="World/Archiver/Tests/Resources" pattern="*" buildAction="EmbeddedResource"/>
<Match path="World/Serialiser/Tests" pattern="*.cs" recurse="true" />
<Match path="World/Terrain/Tests" pattern="*.cs" recurse="true" />
<Match path="ServiceConnectorsOut/Grid/Tests" pattern="*.cs" recurse="true" />