Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
commit
f4f55c4d6b
|
@ -34,7 +34,7 @@ namespace OpenSim.Data
|
||||||
{
|
{
|
||||||
public class FriendsData
|
public class FriendsData
|
||||||
{
|
{
|
||||||
public UUID PrincipalID;
|
public string PrincipalID;
|
||||||
public string Friend;
|
public string Friend;
|
||||||
public Dictionary<string, string> Data;
|
public Dictionary<string, string> Data;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ namespace OpenSim.Data
|
||||||
{
|
{
|
||||||
bool Store(FriendsData data);
|
bool Store(FriendsData data);
|
||||||
bool Delete(UUID ownerID, string friend);
|
bool Delete(UUID ownerID, string friend);
|
||||||
|
bool Delete(string ownerID, string friend);
|
||||||
FriendsData[] GetFriends(UUID principalID);
|
FriendsData[] GetFriends(UUID principalID);
|
||||||
|
FriendsData[] GetFriends(string principalID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
private const string _migrationStore = "EstateStore";
|
private const string _migrationStore = "EstateStore";
|
||||||
|
|
||||||
private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private MSSQLManager _Database;
|
private MSSQLManager _Database;
|
||||||
private string m_connectionString;
|
private string m_connectionString;
|
||||||
|
@ -72,7 +72,12 @@ namespace OpenSim.Data.MSSQL
|
||||||
}
|
}
|
||||||
|
|
||||||
//Migration settings
|
//Migration settings
|
||||||
_Database.CheckMigration(_migrationStore);
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
Migration m = new Migration(conn, GetType().Assembly, "EstateStore");
|
||||||
|
m.Update();
|
||||||
|
}
|
||||||
|
|
||||||
//Interesting way to get parameters! Maybe implement that also with other types
|
//Interesting way to get parameters! Maybe implement that also with other types
|
||||||
Type t = typeof(EstateSettings);
|
Type t = typeof(EstateSettings);
|
||||||
|
@ -112,19 +117,19 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
FieldInfo f = _FieldMap[name];
|
FieldInfo f = _FieldMap[name];
|
||||||
object v = reader[name];
|
object v = reader[name];
|
||||||
if (f.FieldType == typeof(bool) )
|
if (f.FieldType == typeof(bool))
|
||||||
{
|
{
|
||||||
f.SetValue(es, Convert.ToInt32(v) != 0);
|
f.SetValue(es, Convert.ToInt32(v) != 0);
|
||||||
}
|
}
|
||||||
else if (f.FieldType == typeof(UUID) )
|
else if (f.FieldType == typeof(UUID))
|
||||||
{
|
{
|
||||||
f.SetValue(es, new UUID((Guid)v)); // uuid);
|
f.SetValue(es, new UUID((Guid)v)); // uuid);
|
||||||
}
|
}
|
||||||
else if (f.FieldType == typeof(string))
|
else if (f.FieldType == typeof(string))
|
||||||
{
|
{
|
||||||
f.SetValue(es, v.ToString());
|
f.SetValue(es, v.ToString());
|
||||||
}
|
}
|
||||||
else if (f.FieldType == typeof(UInt32))
|
else if (f.FieldType == typeof(UInt32))
|
||||||
{
|
{
|
||||||
f.SetValue(es, Convert.ToUInt32(v));
|
f.SetValue(es, Convert.ToUInt32(v));
|
||||||
}
|
}
|
||||||
|
@ -186,7 +191,7 @@ namespace OpenSim.Data.MSSQL
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_Log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
|
m_log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,12 +315,12 @@ namespace OpenSim.Data.MSSQL
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (SqlCommand cmd = conn.CreateCommand())
|
using (SqlCommand cmd = conn.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "delete from estateban where EstateID = @EstateID";
|
cmd.CommandText = "delete from estateban where EstateID = @EstateID";
|
||||||
cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID);
|
cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
//Insert after
|
//Insert after
|
||||||
cmd.CommandText = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )";
|
cmd.CommandText = "insert into estateban (EstateID, bannedUUID,bannedIp, bannedIpHostMask, bannedNameMask) values ( @EstateID, @bannedUUID, '','','' )";
|
||||||
cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty);
|
cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty);
|
||||||
foreach (EstateBan b in es.EstateBans)
|
foreach (EstateBan b in es.EstateBans)
|
||||||
{
|
{
|
||||||
|
@ -350,43 +355,195 @@ namespace OpenSim.Data.MSSQL
|
||||||
|
|
||||||
public EstateSettings LoadEstateSettings(int estateID)
|
public EstateSettings LoadEstateSettings(int estateID)
|
||||||
{
|
{
|
||||||
// TODO: Implementation!
|
EstateSettings es = new EstateSettings();
|
||||||
return new EstateSettings();
|
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = @EstateID";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
|
||||||
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
if (reader.Read())
|
||||||
|
{
|
||||||
|
foreach (string name in FieldList)
|
||||||
|
{
|
||||||
|
FieldInfo f = _FieldMap[name];
|
||||||
|
object v = reader[name];
|
||||||
|
if (f.FieldType == typeof(bool))
|
||||||
|
{
|
||||||
|
f.SetValue(es, Convert.ToInt32(v) != 0);
|
||||||
|
}
|
||||||
|
else if (f.FieldType == typeof(UUID))
|
||||||
|
{
|
||||||
|
f.SetValue(es, new UUID((Guid)v)); // uuid);
|
||||||
|
}
|
||||||
|
else if (f.FieldType == typeof(string))
|
||||||
|
{
|
||||||
|
f.SetValue(es, v.ToString());
|
||||||
|
}
|
||||||
|
else if (f.FieldType == typeof(UInt32))
|
||||||
|
{
|
||||||
|
f.SetValue(es, Convert.ToUInt32(v));
|
||||||
|
}
|
||||||
|
else if (f.FieldType == typeof(Single))
|
||||||
|
{
|
||||||
|
f.SetValue(es, Convert.ToSingle(v));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
f.SetValue(es, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LoadBanList(es);
|
||||||
|
|
||||||
|
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
|
||||||
|
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
|
||||||
|
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
|
||||||
|
|
||||||
|
//Set event
|
||||||
|
es.OnSave += StoreEstateSettings;
|
||||||
|
return es;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<EstateSettings> LoadEstateSettingsAll()
|
public List<EstateSettings> LoadEstateSettingsAll()
|
||||||
{
|
{
|
||||||
// TODO: Implementation!
|
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
|
||||||
return new List<EstateSettings>();
|
|
||||||
|
List<int> allEstateIds = GetEstatesAll();
|
||||||
|
|
||||||
|
foreach (int estateId in allEstateIds)
|
||||||
|
allEstateSettings.Add(LoadEstateSettings(estateId));
|
||||||
|
|
||||||
|
return allEstateSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<int> GetEstates(string search)
|
public List<int> GetEstates(string search)
|
||||||
{
|
{
|
||||||
// TODO: Implementation!
|
List<int> result = new List<int>();
|
||||||
return new List<int>();
|
string sql = "select estateID from estate_settings where EstateName = @EstateName";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("@EstateName", search);
|
||||||
|
|
||||||
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
result.Add(Convert.ToInt32(reader["EstateID"]));
|
||||||
|
}
|
||||||
|
reader.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<int> GetEstatesAll()
|
public List<int> GetEstatesAll()
|
||||||
{
|
{
|
||||||
// TODO: Implementation!
|
List<int> result = new List<int>();
|
||||||
return new List<int>();
|
string sql = "select estateID from estate_settings";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
result.Add(Convert.ToInt32(reader["EstateID"]));
|
||||||
|
}
|
||||||
|
reader.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<int> GetEstatesByOwner(UUID ownerID)
|
public List<int> GetEstatesByOwner(UUID ownerID)
|
||||||
{
|
{
|
||||||
return new List<int>();
|
List<int> result = new List<int>();
|
||||||
|
string sql = "select estateID from estate_settings where EstateOwner = @EstateOwner";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("@EstateOwner", ownerID);
|
||||||
|
|
||||||
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
result.Add(Convert.ToInt32(reader["EstateID"]));
|
||||||
|
}
|
||||||
|
reader.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LinkRegion(UUID regionID, int estateID)
|
public bool LinkRegion(UUID regionID, int estateID)
|
||||||
{
|
{
|
||||||
// TODO: Implementation!
|
string sql = "insert into estate_map values (@RegionID, @EstateID)";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("@RegionID", regionID);
|
||||||
|
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||||
|
|
||||||
|
int ret = cmd.ExecuteNonQuery();
|
||||||
|
return (ret != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UUID> GetRegions(int estateID)
|
public List<UUID> GetRegions(int estateID)
|
||||||
{
|
{
|
||||||
// TODO: Implementation!
|
List<UUID> result = new List<UUID>();
|
||||||
return new List<UUID>();
|
string sql = "select RegionID from estate_map where EstateID = @EstateID";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||||
|
|
||||||
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
result.Add(DBGuid.FromDB(reader["RegionID"]));
|
||||||
|
}
|
||||||
|
reader.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteEstate(int estateID)
|
public bool DeleteEstate(int estateID)
|
||||||
|
|
|
@ -51,6 +51,11 @@ namespace OpenSim.Data.MSSQL
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(UUID principalID, string friend)
|
public bool Delete(UUID principalID, string friend)
|
||||||
|
{
|
||||||
|
return Delete(principalID.ToString(), friend);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(string principalID, string friend)
|
||||||
{
|
{
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (SqlCommand cmd = new SqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
|
@ -67,6 +72,11 @@ namespace OpenSim.Data.MSSQL
|
||||||
}
|
}
|
||||||
|
|
||||||
public FriendsData[] GetFriends(UUID principalID)
|
public FriendsData[] GetFriends(UUID principalID)
|
||||||
|
{
|
||||||
|
return GetFriends(principalID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FriendsData[] GetFriends(string principalID)
|
||||||
{
|
{
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (SqlCommand cmd = new SqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
|
|
|
@ -168,14 +168,13 @@ namespace OpenSim.Data.MSSQL
|
||||||
|
|
||||||
protected T[] DoQuery(SqlCommand cmd)
|
protected T[] DoQuery(SqlCommand cmd)
|
||||||
{
|
{
|
||||||
|
List<T> result = new List<T>();
|
||||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
return new T[0];
|
return new T[0];
|
||||||
|
|
||||||
CheckColumnNames(reader);
|
CheckColumnNames(reader);
|
||||||
|
|
||||||
List<T> result = new List<T>();
|
|
||||||
|
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -262,6 +261,15 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
names.Add(fi.Name);
|
names.Add(fi.Name);
|
||||||
values.Add("@" + fi.Name);
|
values.Add("@" + fi.Name);
|
||||||
|
// Temporarily return more information about what field is unexpectedly null for
|
||||||
|
// http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
|
||||||
|
// InventoryTransferModule or we may be required to substitute a DBNull here.
|
||||||
|
if (fi.GetValue(row) == null)
|
||||||
|
throw new NullReferenceException(
|
||||||
|
string.Format(
|
||||||
|
"[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
|
||||||
|
fi.Name, row));
|
||||||
|
|
||||||
if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
|
if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
|
||||||
{
|
{
|
||||||
constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
|
constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
|
||||||
|
@ -358,12 +366,18 @@ namespace OpenSim.Data.MSSQL
|
||||||
|
|
||||||
string where = String.Join(" AND ", terms.ToArray());
|
string where = String.Join(" AND ", terms.ToArray());
|
||||||
|
|
||||||
string query = String.Format("DELETE * FROM {0} WHERE {1}", m_Realm, where);
|
string query = String.Format("DELETE FROM {0} WHERE {1}", m_Realm, where);
|
||||||
|
|
||||||
cmd.Connection = conn;
|
cmd.Connection = conn;
|
||||||
cmd.CommandText = query;
|
cmd.CommandText = query;
|
||||||
conn.Open();
|
conn.Open();
|
||||||
return cmd.ExecuteNonQuery() > 0;
|
|
||||||
|
if (cmd.ExecuteNonQuery() > 0)
|
||||||
|
{
|
||||||
|
//m_log.Warn("[MSSQLGenericTable]: " + deleteCommand);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,19 @@ using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
|
||||||
namespace OpenSim.Data.MSSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
public class MSSQLMigration : Migration
|
public class MSSQLMigration : Migration
|
||||||
{
|
{
|
||||||
public MSSQLMigration(DbConnection conn, Assembly assem, string type) : base(conn, assem, type)
|
public MSSQLMigration(DbConnection conn, Assembly assem, string type)
|
||||||
|
: base(conn, assem, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type) : base(conn, assem, subtype, type)
|
public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type)
|
||||||
|
: base(conn, assem, subtype, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,5 +70,30 @@ namespace OpenSim.Data.MSSQL
|
||||||
}
|
}
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void ExecuteScript(DbConnection conn, string[] script)
|
||||||
|
{
|
||||||
|
if (!(conn is SqlConnection))
|
||||||
|
{
|
||||||
|
base.ExecuteScript(conn, script);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string sql in script)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)conn))
|
||||||
|
{
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception(sql);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ namespace OpenSim.Data.MSSQL
|
||||||
string sql = "select * from ["+m_Realm+"] where regionName like @regionName";
|
string sql = "select * from ["+m_Realm+"] where regionName like @regionName";
|
||||||
if (scopeID != UUID.Zero)
|
if (scopeID != UUID.Zero)
|
||||||
sql += " and ScopeID = @scopeID";
|
sql += " and ScopeID = @scopeID";
|
||||||
|
sql += " order by regionName";
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,6 +55,10 @@ namespace OpenSim.Data.MSSQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private MSSQLManager _Database;
|
private MSSQLManager _Database;
|
||||||
private string m_connectionString;
|
private string m_connectionString;
|
||||||
|
protected virtual Assembly Assembly
|
||||||
|
{
|
||||||
|
get { return GetType().Assembly; }
|
||||||
|
}
|
||||||
|
|
||||||
public MSSQLSimulationData()
|
public MSSQLSimulationData()
|
||||||
{
|
{
|
||||||
|
@ -74,9 +78,28 @@ namespace OpenSim.Data.MSSQL
|
||||||
m_connectionString = connectionString;
|
m_connectionString = connectionString;
|
||||||
_Database = new MSSQLManager(connectionString);
|
_Database = new MSSQLManager(connectionString);
|
||||||
|
|
||||||
|
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
//New Migration settings
|
||||||
|
Migration m = new Migration(conn, Assembly, "RegionStore");
|
||||||
|
m.Update();
|
||||||
|
|
||||||
//Migration settings
|
// Clean dropped attachments
|
||||||
_Database.CheckMigration(_migrationStore);
|
//
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (SqlCommand cmd = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = "delete from prims where prims.UUID in (select UUID from primshapes where PCode = 9 and State <> 0); delete from primshapes where PCode = 9 and State <> 0";
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_Log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -214,7 +237,7 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
command.Parameters.Clear();
|
command.Parameters.Clear();
|
||||||
command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID));
|
command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID));
|
||||||
|
|
||||||
List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
|
List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
|
||||||
|
|
||||||
using (SqlDataReader reader = command.ExecuteReader())
|
using (SqlDataReader reader = command.ExecuteReader())
|
||||||
|
@ -241,6 +264,14 @@ namespace OpenSim.Data.MSSQL
|
||||||
/// <param name="regionUUID"></param>
|
/// <param name="regionUUID"></param>
|
||||||
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||||
{
|
{
|
||||||
|
uint flags = obj.RootPart.GetEffectiveObjectFlags();
|
||||||
|
// Eligibility check
|
||||||
|
//
|
||||||
|
if ((flags & (uint)PrimFlags.Temporary) != 0)
|
||||||
|
return;
|
||||||
|
if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
_Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length);
|
_Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length);
|
||||||
|
|
||||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
@ -700,16 +731,470 @@ VALUES
|
||||||
}
|
}
|
||||||
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
||||||
{
|
{
|
||||||
//This connector doesn't support the windlight module yet
|
RegionLightShareData nWP = new RegionLightShareData();
|
||||||
//Return default LL windlight settings
|
nWP.OnSave += StoreRegionWindlightSettings;
|
||||||
return new RegionLightShareData();
|
string sql = "select * from [regionwindlight] where region_id = @regionID";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@regionID", regionUUID));
|
||||||
|
conn.Open();
|
||||||
|
using (SqlDataReader result = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
if (!result.Read())
|
||||||
|
{
|
||||||
|
//No result, so store our default windlight profile and return it
|
||||||
|
nWP.regionID = regionUUID;
|
||||||
|
StoreRegionWindlightSettings(nWP);
|
||||||
|
return nWP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nWP.regionID = DBGuid.FromDB(result["region_id"]);
|
||||||
|
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
|
||||||
|
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
|
||||||
|
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
|
||||||
|
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
|
||||||
|
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
|
||||||
|
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
|
||||||
|
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
|
||||||
|
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
|
||||||
|
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
|
||||||
|
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
|
||||||
|
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
|
||||||
|
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
|
||||||
|
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
|
||||||
|
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
|
||||||
|
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
|
||||||
|
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
|
||||||
|
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
|
||||||
|
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
|
||||||
|
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
|
||||||
|
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
|
||||||
|
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
|
||||||
|
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
|
||||||
|
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
|
||||||
|
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
|
||||||
|
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
|
||||||
|
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
|
||||||
|
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
|
||||||
|
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
|
||||||
|
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
|
||||||
|
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
|
||||||
|
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
|
||||||
|
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
|
||||||
|
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
|
||||||
|
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
|
||||||
|
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
|
||||||
|
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
|
||||||
|
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
|
||||||
|
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
|
||||||
|
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
|
||||||
|
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
|
||||||
|
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
|
||||||
|
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
|
||||||
|
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
|
||||||
|
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
|
||||||
|
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
|
||||||
|
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
|
||||||
|
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
|
||||||
|
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
|
||||||
|
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
|
||||||
|
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
|
||||||
|
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
|
||||||
|
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
|
||||||
|
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
|
||||||
|
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
|
||||||
|
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
|
||||||
|
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
|
||||||
|
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
|
||||||
|
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
|
||||||
|
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
|
||||||
|
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
|
||||||
|
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
|
||||||
|
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
|
||||||
|
nWP.valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nWP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegionWindlightSettings(UUID regionID)
|
public void RemoveRegionWindlightSettings(UUID regionID)
|
||||||
{
|
{
|
||||||
|
string sql = "delete from [regionwindlight] where region_id = @region_id";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionID));
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StoreRegionWindlightSettings(RegionLightShareData wl)
|
public void StoreRegionWindlightSettings(RegionLightShareData wl)
|
||||||
{
|
{
|
||||||
//This connector doesn't support the windlight module yet
|
string sql = "select count (region_id) from regionwindlight where region_id = @region_id";
|
||||||
|
bool exists = false;
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@region_id", wl.regionID));
|
||||||
|
exists = (int)cmd.ExecuteScalar() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exists)
|
||||||
|
{
|
||||||
|
RemoveRegionWindlightSettings(wl.regionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sql insert
|
||||||
|
sql = @"INSERT INTO [regionwindlight]
|
||||||
|
([region_id]
|
||||||
|
,[water_color_r]
|
||||||
|
,[water_color_g]
|
||||||
|
,[water_color_b]
|
||||||
|
,[water_fog_density_exponent]
|
||||||
|
,[underwater_fog_modifier]
|
||||||
|
,[reflection_wavelet_scale_1]
|
||||||
|
,[reflection_wavelet_scale_2]
|
||||||
|
,[reflection_wavelet_scale_3]
|
||||||
|
,[fresnel_scale]
|
||||||
|
,[fresnel_offset]
|
||||||
|
,[refract_scale_above]
|
||||||
|
,[refract_scale_below]
|
||||||
|
,[blur_multiplier]
|
||||||
|
,[big_wave_direction_x]
|
||||||
|
,[big_wave_direction_y]
|
||||||
|
,[little_wave_direction_x]
|
||||||
|
,[little_wave_direction_y]
|
||||||
|
,[normal_map_texture]
|
||||||
|
,[horizon_r]
|
||||||
|
,[horizon_g]
|
||||||
|
,[horizon_b]
|
||||||
|
,[horizon_i]
|
||||||
|
,[haze_horizon]
|
||||||
|
,[blue_density_r]
|
||||||
|
,[blue_density_g]
|
||||||
|
,[blue_density_b]
|
||||||
|
,[blue_density_i]
|
||||||
|
,[haze_density]
|
||||||
|
,[density_multiplier]
|
||||||
|
,[distance_multiplier]
|
||||||
|
,[max_altitude]
|
||||||
|
,[sun_moon_color_r]
|
||||||
|
,[sun_moon_color_g]
|
||||||
|
,[sun_moon_color_b]
|
||||||
|
,[sun_moon_color_i]
|
||||||
|
,[sun_moon_position]
|
||||||
|
,[ambient_r]
|
||||||
|
,[ambient_g]
|
||||||
|
,[ambient_b]
|
||||||
|
,[ambient_i]
|
||||||
|
,[east_angle]
|
||||||
|
,[sun_glow_focus]
|
||||||
|
,[sun_glow_size]
|
||||||
|
,[scene_gamma]
|
||||||
|
,[star_brightness]
|
||||||
|
,[cloud_color_r]
|
||||||
|
,[cloud_color_g]
|
||||||
|
,[cloud_color_b]
|
||||||
|
,[cloud_color_i]
|
||||||
|
,[cloud_x]
|
||||||
|
,[cloud_y]
|
||||||
|
,[cloud_density]
|
||||||
|
,[cloud_coverage]
|
||||||
|
,[cloud_scale]
|
||||||
|
,[cloud_detail_x]
|
||||||
|
,[cloud_detail_y]
|
||||||
|
,[cloud_detail_density]
|
||||||
|
,[cloud_scroll_x]
|
||||||
|
,[cloud_scroll_x_lock]
|
||||||
|
,[cloud_scroll_y]
|
||||||
|
,[cloud_scroll_y_lock]
|
||||||
|
,[draw_classic_clouds])
|
||||||
|
VALUES
|
||||||
|
(@region_id
|
||||||
|
,@water_color_r
|
||||||
|
,@water_color_g
|
||||||
|
,@water_color_b
|
||||||
|
,@water_fog_density_exponent
|
||||||
|
,@underwater_fog_modifier
|
||||||
|
,@reflection_wavelet_scale_1
|
||||||
|
,@reflection_wavelet_scale_2
|
||||||
|
,@reflection_wavelet_scale_3
|
||||||
|
,@fresnel_scale
|
||||||
|
,@fresnel_offset
|
||||||
|
,@refract_scale_above
|
||||||
|
,@refract_scale_below
|
||||||
|
,@blur_multiplier
|
||||||
|
,@big_wave_direction_x
|
||||||
|
,@big_wave_direction_y
|
||||||
|
,@little_wave_direction_x
|
||||||
|
,@little_wave_direction_y
|
||||||
|
,@normal_map_texture
|
||||||
|
,@horizon_r
|
||||||
|
,@horizon_g
|
||||||
|
,@horizon_b
|
||||||
|
,@horizon_i
|
||||||
|
,@haze_horizon
|
||||||
|
,@blue_density_r
|
||||||
|
,@blue_density_g
|
||||||
|
,@blue_density_b
|
||||||
|
,@blue_density_i
|
||||||
|
,@haze_density
|
||||||
|
,@density_multiplier
|
||||||
|
,@distance_multiplier
|
||||||
|
,@max_altitude
|
||||||
|
,@sun_moon_color_r
|
||||||
|
,@sun_moon_color_g
|
||||||
|
,@sun_moon_color_b
|
||||||
|
,@sun_moon_color_i
|
||||||
|
,@sun_moon_position
|
||||||
|
,@ambient_r
|
||||||
|
,@ambient_g
|
||||||
|
,@ambient_b
|
||||||
|
,@ambient_i
|
||||||
|
,@east_angle
|
||||||
|
,@sun_glow_focus
|
||||||
|
,@sun_glow_size
|
||||||
|
,@scene_gamma
|
||||||
|
,@star_brightness
|
||||||
|
,@cloud_color_r
|
||||||
|
,@cloud_color_g
|
||||||
|
,@cloud_color_b
|
||||||
|
,@cloud_color_i
|
||||||
|
,@cloud_x
|
||||||
|
,@cloud_y
|
||||||
|
,@cloud_density
|
||||||
|
,@cloud_coverage
|
||||||
|
,@cloud_scale
|
||||||
|
,@cloud_detail_x
|
||||||
|
,@cloud_detail_y
|
||||||
|
,@cloud_detail_density
|
||||||
|
,@cloud_scroll_x
|
||||||
|
,@cloud_scroll_x_lock
|
||||||
|
,@cloud_scroll_y
|
||||||
|
,@cloud_scroll_y_lock
|
||||||
|
,@draw_classic_clouds)";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("water_color_r", wl.waterColor.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("water_color_g", wl.waterColor.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("water_color_b", wl.waterColor.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("water_fog_density_exponent", wl.waterFogDensityExponent));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("underwater_fog_modifier", wl.underwaterFogModifier));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("fresnel_scale", wl.fresnelScale));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("fresnel_offset", wl.fresnelOffset));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("refract_scale_above", wl.refractScaleAbove));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("refract_scale_below", wl.refractScaleBelow));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("blur_multiplier", wl.blurMultiplier));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_x", wl.bigWaveDirection.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_y", wl.bigWaveDirection.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_x", wl.littleWaveDirection.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_y", wl.littleWaveDirection.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("normal_map_texture", wl.normalMapTexture));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("horizon_r", wl.horizon.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("horizon_g", wl.horizon.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("horizon_b", wl.horizon.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("horizon_i", wl.horizon.W));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("haze_horizon", wl.hazeHorizon));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("blue_density_r", wl.blueDensity.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("blue_density_g", wl.blueDensity.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("blue_density_b", wl.blueDensity.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("blue_density_i", wl.blueDensity.W));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("haze_density", wl.hazeDensity));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("density_multiplier", wl.densityMultiplier));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("distance_multiplier", wl.distanceMultiplier));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("max_altitude", wl.maxAltitude));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_r", wl.sunMoonColor.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_g", wl.sunMoonColor.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_b", wl.sunMoonColor.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_i", wl.sunMoonColor.W));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_position", wl.sunMoonPosition));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("ambient_r", wl.ambient.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("ambient_g", wl.ambient.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("ambient_b", wl.ambient.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("ambient_i", wl.ambient.W));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("east_angle", wl.eastAngle));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("sun_glow_focus", wl.sunGlowFocus));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("sun_glow_size", wl.sunGlowSize));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("scene_gamma", wl.sceneGamma));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("star_brightness", wl.starBrightness));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_r", wl.cloudColor.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_g", wl.cloudColor.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_b", wl.cloudColor.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_i", wl.cloudColor.W));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_x", wl.cloudXYDensity.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_y", wl.cloudXYDensity.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_density", wl.cloudXYDensity.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_coverage", wl.cloudCoverage));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_scale", wl.cloudScale));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_x", wl.cloudDetailXYDensity.X));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_y", wl.cloudDetailXYDensity.Y));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_density", wl.cloudDetailXYDensity.Z));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x", wl.cloudScrollX));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x_lock", wl.cloudScrollXLock));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y", wl.cloudScrollY));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y_lock", wl.cloudScrollYLock));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("draw_classic_clouds", wl.drawClassicClouds));
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#region update
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // sql update
|
||||||
|
// sql = @"UPDATE [OpenSim].[dbo].[regionwindlight]
|
||||||
|
// SET [region_id] = @region_id
|
||||||
|
// ,[water_color_r] = @water_color_r
|
||||||
|
// ,[water_color_g] = @water_color_g
|
||||||
|
// ,[water_color_b] = @water_color_b
|
||||||
|
// ,[water_fog_density_exponent] = @water_fog_density_exponent
|
||||||
|
// ,[underwater_fog_modifier] = @underwater_fog_modifier
|
||||||
|
// ,[reflection_wavelet_scale_1] = @reflection_wavelet_scale_1
|
||||||
|
// ,[reflection_wavelet_scale_2] = @reflection_wavelet_scale_2
|
||||||
|
// ,[reflection_wavelet_scale_3] = @reflection_wavelet_scale_3
|
||||||
|
// ,[fresnel_scale] = @fresnel_scale
|
||||||
|
// ,[fresnel_offset] = @fresnel_offset
|
||||||
|
// ,[refract_scale_above] = @refract_scale_above
|
||||||
|
// ,[refract_scale_below] = @refract_scale_below
|
||||||
|
// ,[blur_multiplier] = @blur_multiplier
|
||||||
|
// ,[big_wave_direction_x] = @big_wave_direction_x
|
||||||
|
// ,[big_wave_direction_y] = @big_wave_direction_y
|
||||||
|
// ,[little_wave_direction_x] = @little_wave_direction_x
|
||||||
|
// ,[little_wave_direction_y] = @little_wave_direction_y
|
||||||
|
// ,[normal_map_texture] = @normal_map_texture
|
||||||
|
// ,[horizon_r] = @horizon_r
|
||||||
|
// ,[horizon_g] = @horizon_g
|
||||||
|
// ,[horizon_b] = @horizon_b
|
||||||
|
// ,[horizon_i] = @horizon_i
|
||||||
|
// ,[haze_horizon] = @haze_horizon
|
||||||
|
// ,[blue_density_r] = @blue_density_r
|
||||||
|
// ,[blue_density_g] = @blue_density_g
|
||||||
|
// ,[blue_density_b] = @blue_density_b
|
||||||
|
// ,[blue_density_i] = @blue_density_i
|
||||||
|
// ,[haze_density] = @haze_density
|
||||||
|
// ,[density_multiplier] = @density_multiplier
|
||||||
|
// ,[distance_multiplier] = @distance_multiplier
|
||||||
|
// ,[max_altitude] = @max_altitude
|
||||||
|
// ,[sun_moon_color_r] = @sun_moon_color_r
|
||||||
|
// ,[sun_moon_color_g] = @sun_moon_color_g
|
||||||
|
// ,[sun_moon_color_b] = @sun_moon_color_b
|
||||||
|
// ,[sun_moon_color_i] = @sun_moon_color_i
|
||||||
|
// ,[sun_moon_position] = @sun_moon_position
|
||||||
|
// ,[ambient_r] = @ambient_r
|
||||||
|
// ,[ambient_g] = @ambient_g
|
||||||
|
// ,[ambient_b] = @ambient_b
|
||||||
|
// ,[ambient_i] = @ambient_i
|
||||||
|
// ,[east_angle] = @east_angle
|
||||||
|
// ,[sun_glow_focus] = @sun_glow_focus
|
||||||
|
// ,[sun_glow_size] = @sun_glow_size
|
||||||
|
// ,[scene_gamma] = @scene_gamma
|
||||||
|
// ,[star_brightness] = @star_brightness
|
||||||
|
// ,[cloud_color_r] = @cloud_color_r
|
||||||
|
// ,[cloud_color_g] = @cloud_color_g
|
||||||
|
// ,[cloud_color_b] = @cloud_color_b
|
||||||
|
// ,[cloud_color_i] = @cloud_color_i
|
||||||
|
// ,[cloud_x] = @cloud_x
|
||||||
|
// ,[cloud_y] = @cloud_y
|
||||||
|
// ,[cloud_density] = @cloud_density
|
||||||
|
// ,[cloud_coverage] = @cloud_coverage
|
||||||
|
// ,[cloud_scale] = @cloud_scale
|
||||||
|
// ,[cloud_detail_x] = @cloud_detail_x
|
||||||
|
// ,[cloud_detail_y] = @cloud_detail_y
|
||||||
|
// ,[cloud_detail_density] = @cloud_detail_density
|
||||||
|
// ,[cloud_scroll_x] = @cloud_scroll_x
|
||||||
|
// ,[cloud_scroll_x_lock] = @cloud_scroll_x_lock
|
||||||
|
// ,[cloud_scroll_y] = @cloud_scroll_y
|
||||||
|
// ,[cloud_scroll_y_lock] = @cloud_scroll_y_lock
|
||||||
|
// ,[draw_classic_clouds] = @draw_classic_clouds
|
||||||
|
// WHERE region_id = @region_id";
|
||||||
|
// using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
// {
|
||||||
|
// conn.Open();
|
||||||
|
// using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
// {
|
||||||
|
// cmd.Parameters.AddWithValue("region_id", wl.regionID);
|
||||||
|
// cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
|
||||||
|
// cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
|
||||||
|
// cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
|
||||||
|
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
|
||||||
|
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
|
||||||
|
// cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
|
||||||
|
// cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
|
||||||
|
// cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
|
||||||
|
// cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
|
||||||
|
// cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
|
||||||
|
// cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
|
||||||
|
// cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
|
||||||
|
// cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
|
||||||
|
// cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
|
||||||
|
// cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
|
||||||
|
// cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
|
||||||
|
// cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
|
||||||
|
// cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
|
||||||
|
// cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
|
||||||
|
// cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
|
||||||
|
// cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
|
||||||
|
// cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
|
||||||
|
// cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
|
||||||
|
// cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
|
||||||
|
// cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
|
||||||
|
// cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
|
||||||
|
// cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
|
||||||
|
// cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
|
||||||
|
// cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
|
||||||
|
// cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
|
||||||
|
// cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
|
||||||
|
// cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
|
||||||
|
// cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
|
||||||
|
|
||||||
|
// cmd.ExecuteNonQuery();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the settings of a region.
|
/// Loads the settings of a region.
|
||||||
|
@ -1136,7 +1621,7 @@ VALUES
|
||||||
if (Convert.ToInt16(primRow["PassTouches"]) != 0)
|
if (Convert.ToInt16(primRow["PassTouches"]) != 0)
|
||||||
prim.PassTouches = true;
|
prim.PassTouches = true;
|
||||||
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
|
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
|
||||||
|
|
||||||
if (!(primRow["MediaURL"] is System.DBNull))
|
if (!(primRow["MediaURL"] is System.DBNull))
|
||||||
prim.MediaUrl = (string)primRow["MediaURL"];
|
prim.MediaUrl = (string)primRow["MediaURL"];
|
||||||
|
|
||||||
|
@ -1192,11 +1677,11 @@ VALUES
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(shapeRow["Media"] is System.DBNull) )
|
if (!(shapeRow["Media"] is System.DBNull))
|
||||||
{
|
{
|
||||||
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
|
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return baseShape;
|
return baseShape;
|
||||||
}
|
}
|
||||||
|
@ -1576,15 +2061,15 @@ VALUES
|
||||||
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
||||||
parameters.Add(_Database.CreateParameter("State", s.State));
|
parameters.Add(_Database.CreateParameter("State", s.State));
|
||||||
|
|
||||||
if(null == s.Media )
|
if (null == s.Media)
|
||||||
{
|
{
|
||||||
parameters.Add(_Database.CreateParameter("Media", DBNull.Value));
|
parameters.Add(_Database.CreateParameter("Media", DBNull.Value));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
|
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return parameters.ToArray();
|
return parameters.ToArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,11 +66,18 @@ namespace OpenSim.Data.MSSQL
|
||||||
|
|
||||||
public bool StoreFolder(XInventoryFolder folder)
|
public bool StoreFolder(XInventoryFolder folder)
|
||||||
{
|
{
|
||||||
|
if (folder.folderName.Length > 64)
|
||||||
|
folder.folderName = folder.folderName.Substring(0, 64);
|
||||||
return m_Folders.Store(folder);
|
return m_Folders.Store(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StoreItem(XInventoryItem item)
|
public bool StoreItem(XInventoryItem item)
|
||||||
{
|
{
|
||||||
|
if (item.inventoryName.Length > 64)
|
||||||
|
item.inventoryName = item.inventoryName.Substring(0, 64);
|
||||||
|
if (item.inventoryDescription.Length > 128)
|
||||||
|
item.inventoryDescription = item.inventoryDescription.Substring(0, 128);
|
||||||
|
|
||||||
return m_Items.Store(item);
|
return m_Items.Store(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +85,6 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
return m_Folders.Delete(field, val);
|
return m_Folders.Delete(field, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteFolders(string[] fields, string[] vals)
|
public bool DeleteFolders(string[] fields, string[] vals)
|
||||||
{
|
{
|
||||||
return m_Folders.Delete(fields, vals);
|
return m_Folders.Delete(fields, vals);
|
||||||
|
@ -88,12 +94,10 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
return m_Items.Delete(field, val);
|
return m_Items.Delete(field, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteItems(string[] fields, string[] vals)
|
public bool DeleteItems(string[] fields, string[] vals)
|
||||||
{
|
{
|
||||||
return m_Items.Delete(fields, vals);
|
return m_Items.Delete(fields, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MoveItem(string id, string newParent)
|
public bool MoveItem(string id, string newParent)
|
||||||
{
|
{
|
||||||
return m_Items.MoveItem(id, newParent);
|
return m_Items.MoveItem(id, newParent);
|
||||||
|
@ -172,5 +176,27 @@ namespace OpenSim.Data.MSSQL
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public override bool Store(XInventoryItem item)
|
||||||
|
{
|
||||||
|
if (!base.Store(item))
|
||||||
|
return false;
|
||||||
|
string sql = "update inventoryfolders set version=version+1 where folderID = @folderID";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
|
||||||
|
cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,4 +37,28 @@ EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 3
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
CREATE TABLE dbo.Tmp_Avatars
|
||||||
|
(
|
||||||
|
PrincipalID uniqueidentifier NOT NULL,
|
||||||
|
[Name] varchar(32) NOT NULL,
|
||||||
|
Value text NOT NULL DEFAULT '',
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[PrincipalID] ASC, [Name] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
TEXTIMAGE_ON [PRIMARY]
|
||||||
|
|
||||||
|
IF EXISTS(SELECT * FROM dbo.Avatars)
|
||||||
|
EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
|
||||||
|
SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
|
||||||
|
|
||||||
|
DROP TABLE dbo.Avatars
|
||||||
|
|
||||||
|
EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
|
|
@ -17,3 +17,49 @@ CREATE TABLE "GridUser" (
|
||||||
)
|
)
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 2 # --------------------------
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
CREATE TABLE [GridUser_tmp] (
|
||||||
|
[UserID] VARCHAR(255) NOT NULL,
|
||||||
|
[HomeRegionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||||
|
[HomePosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||||
|
[HomeLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||||
|
[LastRegionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||||
|
[LastPosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||||
|
[LastLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||||
|
[Online] CHAR(5) NOT NULL DEFAULT 'false',
|
||||||
|
[Login] CHAR(16) NOT NULL DEFAULT '0',
|
||||||
|
[Logout] CHAR(16) NOT NULL DEFAULT '0',
|
||||||
|
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[UserID] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
IF EXISTS(SELECT * FROM dbo.GridUser)
|
||||||
|
EXEC('INSERT INTO dbo.GridUser_tmp ([UserID]
|
||||||
|
,[HomeRegionID]
|
||||||
|
,[HomePosition]
|
||||||
|
,[HomeLookAt]
|
||||||
|
,[LastRegionID]
|
||||||
|
,[LastPosition]
|
||||||
|
,[LastLookAt]
|
||||||
|
,[Online]
|
||||||
|
,[Login]
|
||||||
|
,[Logout])
|
||||||
|
SELECT CONVERT(varchar(36), [HomeRegionID]), [HomePosition] ,[HomeLookAt] , CONVERT(varchar(36),[LastRegionID])
|
||||||
|
,[LastPosition]
|
||||||
|
,[LastLookAt]
|
||||||
|
,[Online]
|
||||||
|
,[Login]
|
||||||
|
,[Logout] FROM dbo.GridUser WITH (HOLDLOCK TABLOCKX)')
|
||||||
|
|
||||||
|
DROP TABLE dbo.GridUser
|
||||||
|
|
||||||
|
EXECUTE sp_rename N'dbo.GridUser_tmp', N'GridUser', 'OBJECT'
|
|
@ -1003,7 +1003,7 @@ CREATE TABLE "regionwindlight" (
|
||||||
PRIMARY KEY ("region_id")
|
PRIMARY KEY ("region_id")
|
||||||
)
|
)
|
||||||
|
|
||||||
COMMIT TRANSACTION
|
COMMIT
|
||||||
|
|
||||||
:VERSION 26
|
:VERSION 26
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,11 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(UUID principalID, string friend)
|
public bool Delete(UUID principalID, string friend)
|
||||||
|
{
|
||||||
|
return Delete(principalID.ToString(), friend);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(string principalID, string friend)
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
MySqlCommand cmd = new MySqlCommand();
|
||||||
|
|
||||||
|
@ -64,5 +69,14 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FriendsData[] GetFriends(string principalID)
|
||||||
|
{
|
||||||
|
MySqlCommand cmd = new MySqlCommand();
|
||||||
|
|
||||||
|
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
|
||||||
|
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
|
||||||
|
return DoQuery(cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,5 +21,12 @@ INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userf
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
:VERSION 3 # -------------------------
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||||
|
ALTER TABLE `Friends` DROP PRIMARY KEY;
|
||||||
|
ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36));
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
|
@ -826,3 +826,19 @@ ALTER TABLE `prims` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
|
||||||
ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
|
ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
:VERSION 38 #---------------------
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
alter table land ENGINE = MyISAM;
|
||||||
|
alter table landaccesslist ENGINE = MyISAM;
|
||||||
|
alter table migrations ENGINE = MyISAM;
|
||||||
|
alter table primitems ENGINE = MyISAM;
|
||||||
|
alter table prims ENGINE = MyISAM;
|
||||||
|
alter table primshapes ENGINE = MyISAM;
|
||||||
|
alter table regionban ENGINE = MyISAM;
|
||||||
|
alter table regionsettings ENGINE = MyISAM;
|
||||||
|
alter table terrain ENGINE = MyISAM;
|
||||||
|
|
||||||
|
COMMIT;
|
|
@ -42,6 +42,11 @@ namespace OpenSim.Data.Null
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FriendsData[] GetFriends(UUID principalID)
|
||||||
|
{
|
||||||
|
return GetFriends(principalID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to implement the Get [] semantics, but it cuts corners.
|
/// Tries to implement the Get [] semantics, but it cuts corners.
|
||||||
/// Specifically, it gets all friendships even if they weren't accepted yet.
|
/// Specifically, it gets all friendships even if they weren't accepted yet.
|
||||||
|
@ -49,11 +54,11 @@ namespace OpenSim.Data.Null
|
||||||
/// <param name="fields"></param>
|
/// <param name="fields"></param>
|
||||||
/// <param name="values"></param>
|
/// <param name="values"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public FriendsData[] GetFriends(UUID userID)
|
public FriendsData[] GetFriends(string userID)
|
||||||
{
|
{
|
||||||
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
|
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
|
||||||
{
|
{
|
||||||
return fdata.PrincipalID == userID;
|
return fdata.PrincipalID == userID.ToString();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (lst != null)
|
if (lst != null)
|
||||||
|
@ -72,9 +77,14 @@ namespace OpenSim.Data.Null
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(UUID userID, string friendID)
|
public bool Delete(UUID principalID, string friend)
|
||||||
{
|
{
|
||||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID; });
|
return Delete(principalID.ToString(), friend);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(string userID, string friendID)
|
||||||
|
{
|
||||||
|
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
||||||
if (lst != null)
|
if (lst != null)
|
||||||
{
|
{
|
||||||
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
||||||
|
|
|
@ -46,7 +46,12 @@ namespace OpenSim.Data.SQLite
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public FriendsData[] GetFriends(UUID userID)
|
public FriendsData[] GetFriends(UUID principalID)
|
||||||
|
{
|
||||||
|
return GetFriends(principalID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FriendsData[] GetFriends(string userID)
|
||||||
{
|
{
|
||||||
SqliteCommand cmd = new SqliteCommand();
|
SqliteCommand cmd = new SqliteCommand();
|
||||||
|
|
||||||
|
@ -58,6 +63,11 @@ namespace OpenSim.Data.SQLite
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(UUID principalID, string friend)
|
public bool Delete(UUID principalID, string friend)
|
||||||
|
{
|
||||||
|
return Delete(principalID.ToString(), friend);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(string principalID, string friend)
|
||||||
{
|
{
|
||||||
SqliteCommand cmd = new SqliteCommand();
|
SqliteCommand cmd = new SqliteCommand();
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,7 @@ namespace OpenSim.Data.SQLite
|
||||||
|
|
||||||
string where = String.Join(" and ", terms.ToArray());
|
string where = String.Join(" and ", terms.ToArray());
|
||||||
|
|
||||||
string query = String.Format("delete * from {0} where {1}", m_Realm, where);
|
string query = String.Format("delete from {0} where {1}", m_Realm, where);
|
||||||
|
|
||||||
cmd.CommandText = query;
|
cmd.CommandText = query;
|
||||||
|
|
||||||
|
|
|
@ -345,6 +345,7 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,12 @@ namespace OpenSim.Framework
|
||||||
set { m_metadata.Temporary = value; }
|
set { m_metadata.Temporary = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string CreatorID
|
||||||
|
{
|
||||||
|
get { return m_metadata.CreatorID; }
|
||||||
|
set { m_metadata.CreatorID = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public AssetFlags Flags
|
public AssetFlags Flags
|
||||||
{
|
{
|
||||||
get { return m_metadata.Flags; }
|
get { return m_metadata.Flags; }
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace OpenSim.Framework
|
||||||
public Vector3 Position;
|
public Vector3 Position;
|
||||||
public ulong RegionHandle;
|
public ulong RegionHandle;
|
||||||
public UUID RegionID;
|
public UUID RegionID;
|
||||||
|
public string Gatekeeper = string.Empty;
|
||||||
public int Version;
|
public int Version;
|
||||||
|
|
||||||
public AssetLandmark(AssetBase a)
|
public AssetLandmark(AssetBase a)
|
||||||
|
@ -51,6 +52,8 @@ namespace OpenSim.Framework
|
||||||
string[] parts = temp.Split('\n');
|
string[] parts = temp.Split('\n');
|
||||||
int.TryParse(parts[0].Substring(17, 1), out Version);
|
int.TryParse(parts[0].Substring(17, 1), out Version);
|
||||||
UUID.TryParse(parts[1].Substring(10, 36), out RegionID);
|
UUID.TryParse(parts[1].Substring(10, 36), out RegionID);
|
||||||
|
if (parts.Length >= 5)
|
||||||
|
Gatekeeper = parts[4].Replace("gatekeeper ", "");
|
||||||
// The position is a vector with spaces as separators ("10.3 32.5 43").
|
// The position is a vector with spaces as separators ("10.3 32.5 43").
|
||||||
// Parse each scalar separately to take into account the system's culture setting.
|
// Parse each scalar separately to take into account the system's culture setting.
|
||||||
string[] scalars = parts[2].Substring(10, parts[2].Length - 10).Split(' ');
|
string[] scalars = parts[2].Substring(10, parts[2].Length - 10).Split(' ');
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace OpenSim.Framework
|
||||||
IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags);
|
IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags);
|
||||||
|
|
||||||
public delegate void TeleportLandmarkRequest(
|
public delegate void TeleportLandmarkRequest(
|
||||||
IClientAPI remoteClient, UUID regionID, Vector3 position);
|
IClientAPI remoteClient, AssetLandmark lm);
|
||||||
|
|
||||||
public delegate void DisconnectUser();
|
public delegate void DisconnectUser();
|
||||||
|
|
||||||
|
@ -1165,7 +1165,19 @@ namespace OpenSim.Framework
|
||||||
void SendAgentAlertMessage(string message, bool modal);
|
void SendAgentAlertMessage(string message, bool modal);
|
||||||
void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url);
|
void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url);
|
||||||
|
|
||||||
void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch,
|
/// <summary>
|
||||||
|
/// Open a dialog box on the client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectname"></param>
|
||||||
|
/// <param name="objectID"></param>
|
||||||
|
/// <param name="ownerID">/param>
|
||||||
|
/// <param name="ownerFirstName"></param>
|
||||||
|
/// <param name="ownerLastName"></param>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
/// <param name="textureID"></param>
|
||||||
|
/// <param name="ch"></param>
|
||||||
|
/// <param name="buttonlabels"></param>
|
||||||
|
void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch,
|
||||||
string[] buttonlabels);
|
string[] buttonlabels);
|
||||||
|
|
||||||
bool AddMoney(int debit);
|
bool AddMoney(int debit);
|
||||||
|
|
|
@ -182,6 +182,9 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
case "FixedSun":
|
case "FixedSun":
|
||||||
settings.FixedSun = bool.Parse(xtr.ReadElementContentAsString());
|
settings.FixedSun = bool.Parse(xtr.ReadElementContentAsString());
|
||||||
break;
|
break;
|
||||||
|
case "SunPosition":
|
||||||
|
settings.SunPosition = double.Parse(xtr.ReadElementContentAsString());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,8 +240,9 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
xtw.WriteElementString("TerrainLowerLimit", settings.TerrainLowerLimit.ToString());
|
xtw.WriteElementString("TerrainLowerLimit", settings.TerrainLowerLimit.ToString());
|
||||||
xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString());
|
xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString());
|
||||||
xtw.WriteElementString("FixedSun", settings.FixedSun.ToString());
|
xtw.WriteElementString("FixedSun", settings.FixedSun.ToString());
|
||||||
// XXX: Need to expose interface to get sun phase information from sun module
|
xtw.WriteElementString("SunPosition", settings.SunPosition.ToString());
|
||||||
// xtw.WriteStartElement("SunPhase",
|
// Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which
|
||||||
|
// calculates it automatically according to the date and other factors.
|
||||||
xtw.WriteEndElement();
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
xtw.WriteEndElement();
|
xtw.WriteEndElement();
|
||||||
|
|
|
@ -412,7 +412,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
// OpenSim.Framework.WebUtil.OSHeaderRequestID
|
// OpenSim.Framework.WebUtil.OSHeaderRequestID
|
||||||
if (request.Headers["opensim-request-id"] != null)
|
if (request.Headers["opensim-request-id"] != null)
|
||||||
reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]);
|
reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]);
|
||||||
// m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
|
//m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
|
||||||
|
|
||||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
|
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
|
||||||
|
|
||||||
|
@ -440,7 +440,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
string path = request.RawUrl;
|
string path = request.RawUrl;
|
||||||
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
||||||
|
|
||||||
// m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
|
//m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
|
||||||
|
|
||||||
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1706,5 +1706,68 @@ namespace OpenSim.Framework
|
||||||
return (T)Enum.Parse(typeof(T), value); ;
|
return (T)Enum.Parse(typeof(T), value); ;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Universal User Identifiers
|
||||||
|
/// <summary>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">uuid[;endpoint[;name]]</param>
|
||||||
|
/// <param name="uuid"></param>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="firstname"></param>
|
||||||
|
/// <param name="lastname"></param>
|
||||||
|
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
|
||||||
|
{
|
||||||
|
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
|
||||||
|
|
||||||
|
string[] parts = value.Split(';');
|
||||||
|
if (parts.Length >= 1)
|
||||||
|
if (!UUID.TryParse(parts[0], out uuid))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (parts.Length >= 2)
|
||||||
|
url = parts[1];
|
||||||
|
|
||||||
|
if (parts.Length >= 3)
|
||||||
|
{
|
||||||
|
string[] name = parts[2].Split();
|
||||||
|
if (name.Length == 2)
|
||||||
|
{
|
||||||
|
firstname = name[0];
|
||||||
|
lastname = name[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parts.Length >= 4)
|
||||||
|
secret = parts[3];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="acircuit"></param>
|
||||||
|
/// <returns>uuid[;endpoint[;name]]</returns>
|
||||||
|
public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
|
||||||
|
{
|
||||||
|
if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||||
|
{
|
||||||
|
string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
|
||||||
|
if (!agentsURI.EndsWith("/"))
|
||||||
|
agentsURI += "/";
|
||||||
|
|
||||||
|
// This is ugly, but there's no other way, given that the name is changed
|
||||||
|
// in the agent circuit data for foreigners
|
||||||
|
if (acircuit.lastname.Contains("@"))
|
||||||
|
{
|
||||||
|
string[] parts = acircuit.firstname.Split(new char[] { '.' });
|
||||||
|
if (parts.Length == 2)
|
||||||
|
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
|
||||||
|
}
|
||||||
|
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return acircuit.AgentID.ToString();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,8 @@ namespace OpenSim
|
||||||
configSource.Alias.AddAlias("Off", false);
|
configSource.Alias.AddAlias("Off", false);
|
||||||
configSource.Alias.AddAlias("True", true);
|
configSource.Alias.AddAlias("True", true);
|
||||||
configSource.Alias.AddAlias("False", false);
|
configSource.Alias.AddAlias("False", false);
|
||||||
|
configSource.Alias.AddAlias("Yes", true);
|
||||||
|
configSource.Alias.AddAlias("No", false);
|
||||||
|
|
||||||
configSource.AddSwitch("Startup", "background");
|
configSource.AddSwitch("Startup", "background");
|
||||||
configSource.AddSwitch("Startup", "inifile");
|
configSource.AddSwitch("Startup", "inifile");
|
||||||
|
@ -239,6 +241,8 @@ namespace OpenSim
|
||||||
configSource.AddSwitch("Startup", "physics");
|
configSource.AddSwitch("Startup", "physics");
|
||||||
configSource.AddSwitch("Startup", "gui");
|
configSource.AddSwitch("Startup", "gui");
|
||||||
configSource.AddSwitch("Startup", "console");
|
configSource.AddSwitch("Startup", "console");
|
||||||
|
configSource.AddSwitch("Startup", "save_crashes");
|
||||||
|
configSource.AddSwitch("Startup", "crash_dir");
|
||||||
|
|
||||||
configSource.AddConfig("StandAlone");
|
configSource.AddConfig("StandAlone");
|
||||||
configSource.AddConfig("Network");
|
configSource.AddConfig("Network");
|
||||||
|
|
|
@ -918,7 +918,7 @@ namespace OpenSim
|
||||||
|
|
||||||
if (regInfo.EstateSettings.EstateID == 0) // No record at all
|
if (regInfo.EstateSettings.EstateID == 0) // No record at all
|
||||||
{
|
{
|
||||||
MainConsole.Instance.OutputFormat("Region {0} is not part of an estate.", regInfo.RegionName);
|
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
|
||||||
|
|
||||||
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
|
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
|
||||||
List<string> estateNames = new List<string>();
|
List<string> estateNames = new List<string>();
|
||||||
|
@ -929,7 +929,7 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
if (estates.Count == 0)
|
if (estates.Count == 0)
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("No existing estates found. You must create a new one.");
|
m_log.Info("[ESTATE] No existing estates found. You must create a new one.");
|
||||||
|
|
||||||
if (CreateEstate(regInfo, estateNames))
|
if (CreateEstate(regInfo, estateNames))
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using Mono.Addins;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SimulatorFeatures capability. This is required for uploading Mesh.
|
||||||
|
/// Since is accepts an open-ended response, we also send more information
|
||||||
|
/// for viewers that care to interpret it.
|
||||||
|
///
|
||||||
|
/// NOTE: Part of this code was adapted from the Aurora project, specifically
|
||||||
|
/// the normal part of the response in the capability handler.
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class SimulatorFeaturesModule : ISharedRegionModule
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private Scene m_scene;
|
||||||
|
|
||||||
|
private string m_MapImageServerURL = string.Empty;
|
||||||
|
private string m_SearchURL = string.Empty;
|
||||||
|
|
||||||
|
#region ISharedRegionModule Members
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource source)
|
||||||
|
{
|
||||||
|
IConfig config = source.Configs["SimulatorFeatures"];
|
||||||
|
if (config == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty);
|
||||||
|
if (m_MapImageServerURL != string.Empty)
|
||||||
|
{
|
||||||
|
m_MapImageServerURL = m_MapImageServerURL.Trim();
|
||||||
|
if (!m_MapImageServerURL.EndsWith("/"))
|
||||||
|
m_MapImageServerURL = m_MapImageServerURL + "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
m_SearchURL = config.GetString("SearchServerURI", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene s)
|
||||||
|
{
|
||||||
|
m_scene = s;
|
||||||
|
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene s)
|
||||||
|
{
|
||||||
|
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close() { }
|
||||||
|
|
||||||
|
public string Name { get { return "SimulatorFeaturesModule"; } }
|
||||||
|
|
||||||
|
public Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
|
{
|
||||||
|
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), SimulatorFeatures);
|
||||||
|
caps.RegisterHandler("SimulatorFeatures", reqHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Hashtable SimulatorFeatures(Hashtable mDhttpMethod)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
|
||||||
|
OSDMap data = new OSDMap();
|
||||||
|
data["MeshRezEnabled"] = true;
|
||||||
|
data["MeshUploadEnabled"] = true;
|
||||||
|
data["MeshXferEnabled"] = true;
|
||||||
|
data["PhysicsMaterialsEnabled"] = true;
|
||||||
|
|
||||||
|
OSDMap typesMap = new OSDMap();
|
||||||
|
typesMap["convex"] = true;
|
||||||
|
typesMap["none"] = true;
|
||||||
|
typesMap["prim"] = true;
|
||||||
|
data["PhysicsShapeTypes"] = typesMap;
|
||||||
|
|
||||||
|
// Extra information for viewers that want to use it
|
||||||
|
OSDMap gridServicesMap = new OSDMap();
|
||||||
|
if (m_MapImageServerURL != string.Empty)
|
||||||
|
gridServicesMap["map-server-url"] = m_MapImageServerURL;
|
||||||
|
if (m_SearchURL != string.Empty)
|
||||||
|
gridServicesMap["search"] = m_SearchURL;
|
||||||
|
data["GridServices"] = gridServicesMap;
|
||||||
|
|
||||||
|
//Send back data
|
||||||
|
Hashtable responsedata = new Hashtable();
|
||||||
|
responsedata["int_response_code"] = 200;
|
||||||
|
responsedata["content_type"] = "text/plain";
|
||||||
|
responsedata["keepalive"] = false;
|
||||||
|
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data);
|
||||||
|
return responsedata;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -438,6 +438,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
#endregion Properties
|
#endregion Properties
|
||||||
|
|
||||||
|
// ~LLClientView()
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat("[LLCLIENTVIEW]: Destructor called for {0}, circuit code {1}", Name, CircuitCode);
|
||||||
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1476,6 +1481,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
money.MoneyData.TransactionSuccess = success;
|
money.MoneyData.TransactionSuccess = success;
|
||||||
money.MoneyData.Description = description;
|
money.MoneyData.Description = description;
|
||||||
money.MoneyData.MoneyBalance = balance;
|
money.MoneyData.MoneyBalance = balance;
|
||||||
|
money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE");
|
||||||
OutPacket(money, ThrottleOutPacketType.Task);
|
OutPacket(money, ThrottleOutPacketType.Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2231,7 +2237,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
OutPacket(loadURL, ThrottleOutPacketType.Task);
|
OutPacket(loadURL, ThrottleOutPacketType.Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
|
public void SendDialog(
|
||||||
|
string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg,
|
||||||
|
UUID textureID, int ch, string[] buttonlabels)
|
||||||
{
|
{
|
||||||
ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
|
ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
|
||||||
dialog.Data.ObjectID = objectID;
|
dialog.Data.ObjectID = objectID;
|
||||||
|
@ -2249,6 +2257,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
|
buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
|
||||||
}
|
}
|
||||||
dialog.Buttons = buttons;
|
dialog.Buttons = buttons;
|
||||||
|
|
||||||
|
dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
|
||||||
|
dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
|
||||||
|
dialog.OwnerData[0].OwnerID = ownerID;
|
||||||
|
|
||||||
OutPacket(dialog, ThrottleOutPacketType.Task);
|
OutPacket(dialog, ThrottleOutPacketType.Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2320,8 +2333,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff;
|
OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
|
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
|
||||||
viewertime.TimeInfo.SunDirection = Position;
|
viewertime.TimeInfo.SunDirection = Position;
|
||||||
viewertime.TimeInfo.SunAngVelocity = Velocity;
|
viewertime.TimeInfo.SunAngVelocity = Velocity;
|
||||||
|
@ -8358,16 +8369,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
AssetLandmark lm;
|
AssetLandmark lm;
|
||||||
if (lmid != UUID.Zero)
|
if (lmid != UUID.Zero)
|
||||||
{
|
{
|
||||||
|
|
||||||
//AssetBase lma = m_assetCache.GetAsset(lmid, false);
|
//AssetBase lma = m_assetCache.GetAsset(lmid, false);
|
||||||
AssetBase lma = m_assetService.Get(lmid.ToString());
|
AssetBase lma = m_assetService.Get(lmid.ToString());
|
||||||
|
|
||||||
if (lma == null)
|
if (lma == null)
|
||||||
{
|
{
|
||||||
// Failed to find landmark
|
// Failed to find landmark
|
||||||
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
|
||||||
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
// Let's try to search in the user's home asset server
|
||||||
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
lma = FindAssetInUserAssetServer(lmid.ToString());
|
||||||
OutPacket(tpCancel, ThrottleOutPacketType.Task);
|
|
||||||
|
if (lma == null)
|
||||||
|
{
|
||||||
|
// Really doesn't exist
|
||||||
|
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
||||||
|
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
||||||
|
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
||||||
|
OutPacket(tpCancel, ThrottleOutPacketType.Task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -8398,13 +8418,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest;
|
TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest;
|
||||||
if (handlerTeleportLandmarkRequest != null)
|
if (handlerTeleportLandmarkRequest != null)
|
||||||
{
|
{
|
||||||
handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position);
|
handlerTeleportLandmarkRequest(this, lm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//no event handler so cancel request
|
//no event handler so cancel request
|
||||||
|
|
||||||
|
|
||||||
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
||||||
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
||||||
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
||||||
|
@ -8414,6 +8432,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AssetBase FindAssetInUserAssetServer(string id)
|
||||||
|
{
|
||||||
|
AgentCircuitData aCircuit = ((Scene)Scene).AuthenticateHandler.GetAgentCircuitData(CircuitCode);
|
||||||
|
if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
|
||||||
|
{
|
||||||
|
string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString();
|
||||||
|
return ((Scene)Scene).AssetService.Get(assetServer + "/" + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack)
|
private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack)
|
||||||
{
|
{
|
||||||
TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
|
TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
|
||||||
|
|
|
@ -64,13 +64,13 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
private bool m_Enabled;
|
private bool m_Enabled;
|
||||||
|
|
||||||
private const string m_ModuleName = "FlotsamAssetCache";
|
private const string m_ModuleName = "FlotsamAssetCache";
|
||||||
private const string m_DefaultCacheDirectory = m_ModuleName;
|
private const string m_DefaultCacheDirectory = "./assetcache";
|
||||||
private string m_CacheDirectory = m_DefaultCacheDirectory;
|
private string m_CacheDirectory = m_DefaultCacheDirectory;
|
||||||
|
|
||||||
private readonly List<char> m_InvalidChars = new List<char>();
|
private readonly List<char> m_InvalidChars = new List<char>();
|
||||||
|
|
||||||
private int m_LogLevel = 0;
|
private int m_LogLevel = 0;
|
||||||
private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests
|
private ulong m_HitRateDisplay = 100; // How often to display hit statistics, given in requests
|
||||||
|
|
||||||
private static ulong m_Requests;
|
private static ulong m_Requests;
|
||||||
private static ulong m_RequestsForInprogress;
|
private static ulong m_RequestsForInprogress;
|
||||||
|
@ -87,14 +87,14 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private ExpiringCache<string, AssetBase> m_MemoryCache;
|
private ExpiringCache<string, AssetBase> m_MemoryCache;
|
||||||
private bool m_MemoryCacheEnabled = true;
|
private bool m_MemoryCacheEnabled = false;
|
||||||
|
|
||||||
// Expiration is expressed in hours.
|
// Expiration is expressed in hours.
|
||||||
private const double m_DefaultMemoryExpiration = 1.0;
|
private const double m_DefaultMemoryExpiration = 2;
|
||||||
private const double m_DefaultFileExpiration = 48;
|
private const double m_DefaultFileExpiration = 48;
|
||||||
private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration);
|
private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration);
|
||||||
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
|
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
|
||||||
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(m_DefaultFileExpiration);
|
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(0.166);
|
||||||
|
|
||||||
private static int m_CacheDirectoryTiers = 1;
|
private static int m_CacheDirectoryTiers = 1;
|
||||||
private static int m_CacheDirectoryTierLen = 3;
|
private static int m_CacheDirectoryTierLen = 3;
|
||||||
|
@ -141,26 +141,38 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
IConfig assetConfig = source.Configs["AssetCache"];
|
IConfig assetConfig = source.Configs["AssetCache"];
|
||||||
if (assetConfig == null)
|
if (assetConfig == null)
|
||||||
{
|
{
|
||||||
m_log.Warn("[FLOTSAM ASSET CACHE]: AssetCache missing from OpenSim.ini, using defaults.");
|
m_log.Warn(
|
||||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory);
|
"[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults.");
|
||||||
return;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
|
||||||
|
|
||||||
|
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled);
|
||||||
|
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
|
||||||
|
|
||||||
|
#if WAIT_ON_INPROGRESS_REQUESTS
|
||||||
|
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_LogLevel = assetConfig.GetInt("LogLevel", m_LogLevel);
|
||||||
|
m_HitRateDisplay = (ulong)assetConfig.GetLong("HitRateDisplay", (long)m_HitRateDisplay);
|
||||||
|
|
||||||
|
m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
|
||||||
|
m_FileExpirationCleanupTimer
|
||||||
|
= TimeSpan.FromHours(
|
||||||
|
assetConfig.GetDouble("FileCleanupTimer", m_FileExpirationCleanupTimer.TotalHours));
|
||||||
|
|
||||||
|
m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", m_CacheDirectoryTiers);
|
||||||
|
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen);
|
||||||
|
|
||||||
|
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt);
|
||||||
|
|
||||||
|
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
|
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
|
||||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_CacheDirectory);
|
|
||||||
|
|
||||||
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", false);
|
|
||||||
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
|
|
||||||
|
|
||||||
#if WAIT_ON_INPROGRESS_REQUESTS
|
|
||||||
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_LogLevel = assetConfig.GetInt("LogLevel", 0);
|
|
||||||
m_HitRateDisplay = (ulong)assetConfig.GetInt("HitRateDisplay", 1000);
|
|
||||||
|
|
||||||
m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
|
|
||||||
m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration));
|
|
||||||
if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
|
if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
|
||||||
{
|
{
|
||||||
m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
|
m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
|
||||||
|
@ -170,7 +182,6 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
m_CacheCleanTimer.Start();
|
m_CacheCleanTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1);
|
|
||||||
if (m_CacheDirectoryTiers < 1)
|
if (m_CacheDirectoryTiers < 1)
|
||||||
{
|
{
|
||||||
m_CacheDirectoryTiers = 1;
|
m_CacheDirectoryTiers = 1;
|
||||||
|
@ -180,7 +191,6 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
m_CacheDirectoryTiers = 3;
|
m_CacheDirectoryTiers = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", 3);
|
|
||||||
if (m_CacheDirectoryTierLen < 1)
|
if (m_CacheDirectoryTierLen < 1)
|
||||||
{
|
{
|
||||||
m_CacheDirectoryTierLen = 1;
|
m_CacheDirectoryTierLen = 1;
|
||||||
|
@ -190,14 +200,10 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
m_CacheDirectoryTierLen = 4;
|
m_CacheDirectoryTierLen = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", 30000);
|
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
||||||
|
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
|
||||||
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", false);
|
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
||||||
|
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
||||||
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
|
||||||
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand);
|
|
||||||
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
|
||||||
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -732,24 +738,39 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "clear":
|
case "clear":
|
||||||
if (cmdparams.Length < 3)
|
if (cmdparams.Length < 2)
|
||||||
{
|
{
|
||||||
m_log.Warn("[FLOTSAM ASSET CACHE] Please specify memory and/or file cache.");
|
m_log.Warn("[FLOTSAM ASSET CACHE] Usage is fcache clear [file] [memory]");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool clearMemory = false, clearFile = false;
|
||||||
|
|
||||||
|
if (cmdparams.Length == 2)
|
||||||
|
{
|
||||||
|
clearMemory = true;
|
||||||
|
clearFile = true;
|
||||||
|
}
|
||||||
foreach (string s in cmdparams)
|
foreach (string s in cmdparams)
|
||||||
{
|
{
|
||||||
if (s.ToLower() == "memory")
|
if (s.ToLower() == "memory")
|
||||||
{
|
clearMemory = true;
|
||||||
m_MemoryCache.Clear();
|
|
||||||
m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared.");
|
|
||||||
}
|
|
||||||
else if (s.ToLower() == "file")
|
else if (s.ToLower() == "file")
|
||||||
{
|
clearFile = true;
|
||||||
ClearFileCache();
|
|
||||||
m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clearMemory)
|
||||||
|
{
|
||||||
|
m_MemoryCache.Clear();
|
||||||
|
m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearFile)
|
||||||
|
{
|
||||||
|
ClearFileCache();
|
||||||
|
m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared.");
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||||
|
|
||||||
ScenePresence sp = m_scene.GetScenePresence(avatarID);
|
ScenePresence sp = m_scene.GetScenePresence(avatarID);
|
||||||
if (sp != null)
|
if (sp != null)
|
||||||
sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
|
sp.ControllingClient.SendDialog(
|
||||||
|
objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendUrlToUser(
|
public void SendUrlToUser(
|
||||||
|
|
|
@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
{
|
{
|
||||||
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
||||||
{
|
{
|
||||||
|
protected bool m_Enabled = false;
|
||||||
|
|
||||||
protected class UserFriendData
|
protected class UserFriendData
|
||||||
{
|
{
|
||||||
public UUID PrincipalID;
|
public UUID PrincipalID;
|
||||||
|
@ -67,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
|
protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected List<Scene> m_Scenes = new List<Scene>();
|
protected List<Scene> m_Scenes = new List<Scene>();
|
||||||
|
@ -130,7 +132,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region ISharedRegionModule
|
||||||
public void Initialise(IConfigSource config)
|
public void Initialise(IConfigSource config)
|
||||||
|
{
|
||||||
|
IConfig moduleConfig = config.Configs["Modules"];
|
||||||
|
if (moduleConfig != null)
|
||||||
|
{
|
||||||
|
string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
|
||||||
|
if (name == Name)
|
||||||
|
{
|
||||||
|
InitModule(config);
|
||||||
|
|
||||||
|
m_Enabled = true;
|
||||||
|
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void InitModule(IConfigSource config)
|
||||||
{
|
{
|
||||||
IConfig friendsConfig = config.Configs["Friends"];
|
IConfig friendsConfig = config.Configs["Friends"];
|
||||||
if (friendsConfig != null)
|
if (friendsConfig != null)
|
||||||
|
@ -153,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
|
m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
|
||||||
throw new Exception("Connector load error");
|
throw new Exception("Connector load error");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
|
@ -164,8 +182,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
public virtual void AddRegion(Scene scene)
|
||||||
{
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||||
|
|
||||||
m_Scenes.Add(scene);
|
m_Scenes.Add(scene);
|
||||||
scene.RegisterModuleInterface<IFriendsModule>(this);
|
scene.RegisterModuleInterface<IFriendsModule>(this);
|
||||||
|
|
||||||
|
@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
{
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
m_Scenes.Remove(scene);
|
m_Scenes.Remove(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public virtual string Name
|
||||||
{
|
{
|
||||||
get { return "FriendsModule"; }
|
get { return "FriendsModule"; }
|
||||||
}
|
}
|
||||||
|
@ -194,13 +219,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
get { return null; }
|
get { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetFriendPerms(UUID principalID, UUID friendID)
|
#endregion
|
||||||
|
|
||||||
|
public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||||
{
|
{
|
||||||
FriendInfo[] friends = GetFriends(principalID);
|
FriendInfo[] friends = GetFriends(principalID);
|
||||||
foreach (FriendInfo fi in friends)
|
FriendInfo finfo = GetFriend(friends, friendID);
|
||||||
|
if (finfo != null)
|
||||||
{
|
{
|
||||||
if (fi.Friend == friendID.ToString())
|
return (uint)finfo.TheirFlags;
|
||||||
return (uint)fi.TheirFlags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -214,30 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
client.OnTerminateFriendship += OnTerminateFriendship;
|
client.OnTerminateFriendship += OnTerminateFriendship;
|
||||||
client.OnGrantUserRights += OnGrantUserRights;
|
client.OnGrantUserRights += OnGrantUserRights;
|
||||||
|
|
||||||
// Asynchronously fetch the friends list or increment the refcount for the existing
|
Util.FireAndForget(delegate { FetchFriendslist(client); });
|
||||||
// friends list
|
}
|
||||||
Util.FireAndForget(
|
|
||||||
delegate(object o)
|
|
||||||
{
|
|
||||||
lock (m_Friends)
|
|
||||||
{
|
|
||||||
UserFriendData friendsData;
|
|
||||||
if (m_Friends.TryGetValue(client.AgentId, out friendsData))
|
|
||||||
{
|
|
||||||
friendsData.Refcount++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
friendsData = new UserFriendData();
|
|
||||||
friendsData.PrincipalID = client.AgentId;
|
|
||||||
friendsData.Friends = FriendsService.GetFriends(client.AgentId);
|
|
||||||
friendsData.Refcount = 1;
|
|
||||||
|
|
||||||
m_Friends[client.AgentId] = friendsData;
|
/// Fetch the friends list or increment the refcount for the existing
|
||||||
}
|
/// friends list
|
||||||
}
|
/// Returns true if the list was fetched, false if it wasn't
|
||||||
|
protected virtual bool FetchFriendslist(IClientAPI client)
|
||||||
|
{
|
||||||
|
UUID agentID = client.AgentId;
|
||||||
|
lock (m_Friends)
|
||||||
|
{
|
||||||
|
UserFriendData friendsData;
|
||||||
|
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||||
|
{
|
||||||
|
friendsData.Refcount++;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
);
|
else
|
||||||
|
{
|
||||||
|
friendsData = new UserFriendData();
|
||||||
|
friendsData.PrincipalID = agentID;
|
||||||
|
friendsData.Friends = GetFriendsFromService(client);
|
||||||
|
friendsData.Refcount = 1;
|
||||||
|
|
||||||
|
m_Friends[agentID] = friendsData;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientClosed(UUID agentID, Scene scene)
|
private void OnClientClosed(UUID agentID, Scene scene)
|
||||||
|
@ -263,14 +294,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
private void OnMakeRootAgent(ScenePresence sp)
|
private void OnMakeRootAgent(ScenePresence sp)
|
||||||
{
|
{
|
||||||
UUID agentID = sp.ControllingClient.AgentId;
|
RefetchFriends(sp.ControllingClient);
|
||||||
UpdateFriendsCache(agentID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientLogin(IClientAPI client)
|
private void OnClientLogin(IClientAPI client)
|
||||||
{
|
{
|
||||||
UUID agentID = client.AgentId;
|
UUID agentID = client.AgentId;
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[XXX]: OnClientLogin!");
|
||||||
// Inform the friends that this user is online
|
// Inform the friends that this user is online
|
||||||
StatusChange(agentID, true);
|
StatusChange(agentID, true);
|
||||||
|
|
||||||
|
@ -279,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
m_NeedsListOfFriends.Add(agentID);
|
m_NeedsListOfFriends.Add(agentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendFriendsOnlineIfNeeded(IClientAPI client)
|
public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||||
{
|
{
|
||||||
UUID agentID = client.AgentId;
|
UUID agentID = client.AgentId;
|
||||||
|
|
||||||
|
@ -287,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
lock (m_NeedsListOfFriends)
|
lock (m_NeedsListOfFriends)
|
||||||
{
|
{
|
||||||
if (!m_NeedsListOfFriends.Remove(agentID))
|
if (!m_NeedsListOfFriends.Remove(agentID))
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the friends online
|
// Send the friends online
|
||||||
|
@ -313,10 +344,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
foreach (string fid in outstanding)
|
foreach (string fid in outstanding)
|
||||||
{
|
{
|
||||||
UUID fromAgentID;
|
UUID fromAgentID;
|
||||||
if (!UUID.TryParse(fid, out fromAgentID))
|
string firstname = "Unknown", lastname = "User";
|
||||||
|
if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
|
|
||||||
|
|
||||||
PresenceInfo presence = null;
|
PresenceInfo presence = null;
|
||||||
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
|
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
|
||||||
|
@ -326,13 +359,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
im.offline = 0;
|
im.offline = 0;
|
||||||
|
|
||||||
im.fromAgentID = fromAgentID.Guid;
|
im.fromAgentID = fromAgentID.Guid;
|
||||||
im.fromAgentName = account.FirstName + " " + account.LastName;
|
im.fromAgentName = firstname + " " + lastname;
|
||||||
im.offline = (byte)((presence == null) ? 1 : 0);
|
im.offline = (byte)((presence == null) ? 1 : 0);
|
||||||
im.imSessionID = im.fromAgentID;
|
im.imSessionID = im.fromAgentID;
|
||||||
|
im.message = FriendshipMessage(fid);
|
||||||
|
|
||||||
// Finally
|
// Finally
|
||||||
LocalFriendshipOffered(agentID, im);
|
LocalFriendshipOffered(agentID, im);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string FriendshipMessage(string friendID)
|
||||||
|
{
|
||||||
|
return "Will you be my friend?";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||||
|
{
|
||||||
|
first = "Unknown"; last = "User";
|
||||||
|
if (!UUID.TryParse(fid, out agentID))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
|
||||||
|
if (account != null)
|
||||||
|
{
|
||||||
|
first = account.FirstName;
|
||||||
|
last = account.LastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<UUID> GetOnlineFriends(UUID userID)
|
List<UUID> GetOnlineFriends(UUID userID)
|
||||||
|
@ -348,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
|
|
||||||
if (friendList.Count > 0)
|
if (friendList.Count > 0)
|
||||||
{
|
GetOnlineFriends(userID, friendList, online);
|
||||||
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
|
||||||
foreach (PresenceInfo pi in presence)
|
|
||||||
{
|
|
||||||
UUID presenceID;
|
|
||||||
if (UUID.TryParse(pi.UserID, out presenceID))
|
|
||||||
online.Add(presenceID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return online;
|
return online;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||||
|
{
|
||||||
|
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||||
|
foreach (PresenceInfo pi in presence)
|
||||||
|
{
|
||||||
|
UUID presenceID;
|
||||||
|
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||||
|
online.Add(presenceID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find the client for a ID
|
/// Find the client for a ID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -415,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
Util.FireAndForget(
|
Util.FireAndForget(
|
||||||
delegate
|
delegate
|
||||||
{
|
{
|
||||||
foreach (FriendInfo fi in friendList)
|
m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
|
||||||
{
|
// Notify about this user status
|
||||||
//m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
|
StatusNotify(friendList, agentID, online);
|
||||||
// Notify about this user status
|
|
||||||
StatusNotify(fi, agentID, online);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StatusNotify(FriendInfo friend, UUID userID, bool online)
|
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||||
{
|
{
|
||||||
UUID friendID;
|
foreach (FriendInfo friend in friendList)
|
||||||
if (UUID.TryParse(friend.Friend, out friendID))
|
|
||||||
{
|
{
|
||||||
// Try local
|
UUID friendID;
|
||||||
if (LocalStatusNotification(userID, friendID, online))
|
if (UUID.TryParse(friend.Friend, out friendID))
|
||||||
return;
|
|
||||||
|
|
||||||
// The friend is not here [as root]. Let's forward.
|
|
||||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
|
||||||
if (friendSessions != null && friendSessions.Length > 0)
|
|
||||||
{
|
{
|
||||||
PresenceInfo friendSession = null;
|
// Try local
|
||||||
foreach (PresenceInfo pinfo in friendSessions)
|
if (LocalStatusNotification(userID, friendID, online))
|
||||||
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
|
return;
|
||||||
{
|
|
||||||
friendSession = pinfo;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (friendSession != null)
|
// The friend is not here [as root]. Let's forward.
|
||||||
|
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||||
|
if (friendSessions != null && friendSessions.Length > 0)
|
||||||
{
|
{
|
||||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
PresenceInfo friendSession = null;
|
||||||
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
|
foreach (PresenceInfo pinfo in friendSessions)
|
||||||
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
|
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
|
||||||
}
|
{
|
||||||
}
|
friendSession = pinfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Friend is not online. Ignore.
|
if (friendSession != null)
|
||||||
}
|
{
|
||||||
else
|
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||||
{
|
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
|
||||||
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
|
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Friend is not online. Ignore.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
// This user wants to be friends with the other user.
|
// This user wants to be friends with the other user.
|
||||||
// Let's add the relation backwards, in case the other is not online
|
// Let's add the relation backwards, in case the other is not online
|
||||||
FriendsService.StoreFriend(friendID, principalID.ToString(), 0);
|
StoreBackwards(friendID, principalID);
|
||||||
|
|
||||||
// Now let's ask the other user to be friends with this user
|
// Now let's ask the other user to be friends with this user
|
||||||
ForwardFriendshipOffer(principalID, friendID, im);
|
ForwardFriendshipOffer(principalID, friendID, im);
|
||||||
|
@ -487,11 +547,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
|
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
|
||||||
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
|
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
|
||||||
im.imSessionID = im.fromAgentID;
|
im.imSessionID = im.fromAgentID;
|
||||||
|
im.fromAgentName = GetFriendshipRequesterName(agentID);
|
||||||
|
|
||||||
// Try the local sim
|
// Try the local sim
|
||||||
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
|
|
||||||
im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
|
||||||
|
|
||||||
if (LocalFriendshipOffered(friendID, im))
|
if (LocalFriendshipOffered(friendID, im))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -509,12 +567,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
// If the prospective friend is not online, he'll get the message upon login.
|
// If the prospective friend is not online, he'll get the message upon login.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual string GetFriendshipRequesterName(UUID agentID)
|
||||||
|
{
|
||||||
|
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
|
||||||
|
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
|
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
|
||||||
|
|
||||||
FriendsService.StoreFriend(agentID, friendID.ToString(), 1);
|
StoreFriendships(agentID, friendID);
|
||||||
FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
|
|
||||||
|
|
||||||
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
|
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||||
if (ccm != null)
|
if (ccm != null)
|
||||||
|
@ -523,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the local cache
|
// Update the local cache
|
||||||
UpdateFriendsCache(agentID);
|
RefetchFriends(client);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Notify the friend
|
// Notify the friend
|
||||||
|
@ -554,8 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
|
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
|
||||||
|
|
||||||
FriendsService.Delete(agentID, friendID.ToString());
|
DeleteFriendship(agentID, friendID);
|
||||||
FriendsService.Delete(friendID, agentID.ToString());
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Notify the friend
|
// Notify the friend
|
||||||
|
@ -582,11 +644,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
|
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
|
||||||
{
|
{
|
||||||
FriendsService.Delete(agentID, exfriendID.ToString());
|
if (!DeleteFriendship(agentID, exfriendID))
|
||||||
FriendsService.Delete(exfriendID, agentID.ToString());
|
client.SendAlertMessage("Unable to terminate friendship on this sim.");
|
||||||
|
|
||||||
// Update local cache
|
// Update local cache
|
||||||
UpdateFriendsCache(agentID);
|
RefetchFriends(client);
|
||||||
|
|
||||||
client.SendTerminateFriend(exfriendID);
|
client.SendTerminateFriend(exfriendID);
|
||||||
|
|
||||||
|
@ -612,23 +674,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
||||||
|
|
||||||
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
||||||
if (friends.Length == 0)
|
if (friends.Length == 0)
|
||||||
return;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
|
||||||
// Let's find the friend in this user's friend list
|
|
||||||
FriendInfo friend = null;
|
|
||||||
foreach (FriendInfo fi in friends)
|
|
||||||
{
|
{
|
||||||
if (fi.Friend == target.ToString())
|
return;
|
||||||
friend = fi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Let's find the friend in this user's friend list
|
||||||
|
FriendInfo friend = GetFriend(friends, target);
|
||||||
|
|
||||||
if (friend != null) // Found it
|
if (friend != null) // Found it
|
||||||
{
|
{
|
||||||
// Store it on the DB
|
// Store it on the DB
|
||||||
FriendsService.StoreFriend(requester, target.ToString(), rights);
|
if (!StoreRights(requester, target, rights))
|
||||||
|
{
|
||||||
|
remoteClient.SendAlertMessage("Unable to grant rights.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Store it in the local cache
|
// Store it in the local cache
|
||||||
int myFlags = friend.MyFlags;
|
int myFlags = friend.MyFlags;
|
||||||
|
@ -658,6 +722,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
|
||||||
|
{
|
||||||
|
foreach (FriendInfo fi in friends)
|
||||||
|
{
|
||||||
|
if (fi.Friend == friendID.ToString())
|
||||||
|
return fi;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Local
|
#region Local
|
||||||
|
@ -693,7 +769,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
|
|
||||||
// Update the local cache
|
// Update the local cache
|
||||||
UpdateFriendsCache(friendID);
|
RefetchFriends(friendClient);
|
||||||
|
|
||||||
// we're done
|
// we're done
|
||||||
return true;
|
return true;
|
||||||
|
@ -726,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
// the friend in this sim as root agent
|
// the friend in this sim as root agent
|
||||||
friendClient.SendTerminateFriend(exfriendID);
|
friendClient.SendTerminateFriend(exfriendID);
|
||||||
// update local cache
|
// update local cache
|
||||||
UpdateFriendsCache(exfriendID);
|
RefetchFriends(friendClient);
|
||||||
// we're done
|
// we're done
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -756,15 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update local cache
|
// Update local cache
|
||||||
lock (m_Friends)
|
UpdateLocalCache(userID, friendID, rights);
|
||||||
{
|
|
||||||
FriendInfo[] friends = GetFriends(friendID);
|
|
||||||
foreach (FriendInfo finfo in friends)
|
|
||||||
{
|
|
||||||
if (finfo.Friend == userID.ToString())
|
|
||||||
finfo.TheirFlags = rights;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -775,10 +843,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
|
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
||||||
IClientAPI friendClient = LocateClientObject(friendID);
|
IClientAPI friendClient = LocateClientObject(friendID);
|
||||||
if (friendClient != null)
|
if (friendClient != null)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
|
||||||
// the friend in this sim as root agent
|
// the friend in this sim as root agent
|
||||||
if (online)
|
if (online)
|
||||||
friendClient.SendAgentOnline(new UUID[] { userID });
|
friendClient.SendAgentOnline(new UUID[] { userID });
|
||||||
|
@ -793,7 +861,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private FriendInfo[] GetFriends(UUID agentID)
|
#region Get / Set friends in several flavours
|
||||||
|
/// <summary>
|
||||||
|
/// Get friends from local cache only
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agentID"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected FriendInfo[] GetFriends(UUID agentID)
|
||||||
{
|
{
|
||||||
UserFriendData friendsData;
|
UserFriendData friendsData;
|
||||||
|
|
||||||
|
@ -806,14 +880,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
return EMPTY_FRIENDS;
|
return EMPTY_FRIENDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateFriendsCache(UUID agentID)
|
/// <summary>
|
||||||
|
/// Update loca cache only
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userID"></param>
|
||||||
|
/// <param name="friendID"></param>
|
||||||
|
/// <param name="rights"></param>
|
||||||
|
protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
|
||||||
{
|
{
|
||||||
|
// Update local cache
|
||||||
|
lock (m_Friends)
|
||||||
|
{
|
||||||
|
FriendInfo[] friends = GetFriends(friendID);
|
||||||
|
FriendInfo finfo = GetFriend(friends, userID);
|
||||||
|
finfo.TheirFlags = rights;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||||
|
{
|
||||||
|
return FriendsService.GetFriends(client.AgentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefetchFriends(IClientAPI client)
|
||||||
|
{
|
||||||
|
UUID agentID = client.AgentId;
|
||||||
lock (m_Friends)
|
lock (m_Friends)
|
||||||
{
|
{
|
||||||
UserFriendData friendsData;
|
UserFriendData friendsData;
|
||||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||||
friendsData.Friends = FriendsService.GetFriends(agentID);
|
friendsData.Friends = GetFriendsFromService(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
|
||||||
|
{
|
||||||
|
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void StoreBackwards(UUID friendID, UUID agentID)
|
||||||
|
{
|
||||||
|
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
|
||||||
|
{
|
||||||
|
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
|
||||||
|
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||||
|
{
|
||||||
|
FriendsService.Delete(agentID, exfriendID.ToString());
|
||||||
|
FriendsService.Delete(exfriendID, agentID.ToString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,623 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using Nwc.XmlRpc;
|
||||||
|
using Mono.Addins;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Services.Connectors.Hypergrid;
|
||||||
|
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||||
|
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||||
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
{
|
||||||
|
public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
#region ISharedRegionModule
|
||||||
|
public override string Name
|
||||||
|
{
|
||||||
|
get { return "HGFriendsModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
base.AddRegion(scene);
|
||||||
|
scene.RegisterModuleInterface<IFriendsSimConnector>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IFriendsSimConnector
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notify the user that the friend's status changed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userID">user to be notified</param>
|
||||||
|
/// <param name="friendID">friend whose status changed</param>
|
||||||
|
/// <param name="online">status</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool StatusNotify(UUID friendID, UUID userID, bool online)
|
||||||
|
{
|
||||||
|
return LocalStatusNotification(friendID, userID, online);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
protected override bool FetchFriendslist(IClientAPI client)
|
||||||
|
{
|
||||||
|
if (base.FetchFriendslist(client))
|
||||||
|
{
|
||||||
|
UUID agentID = client.AgentId;
|
||||||
|
// we do this only for the root agent
|
||||||
|
if (m_Friends[agentID].Refcount == 1)
|
||||||
|
{
|
||||||
|
// We need to preload the user management cache with the names
|
||||||
|
// of foreign friends, just like we do with SOPs' creators
|
||||||
|
foreach (FriendInfo finfo in m_Friends[agentID].Friends)
|
||||||
|
{
|
||||||
|
if (finfo.TheirFlags != -1)
|
||||||
|
{
|
||||||
|
UUID id;
|
||||||
|
if (!UUID.TryParse(finfo.Friend, out id))
|
||||||
|
{
|
||||||
|
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
||||||
|
if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
|
||||||
|
{
|
||||||
|
IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||||
|
uMan.AddUser(id, url + ";" + first + " " + last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||||
|
{
|
||||||
|
if (base.SendFriendsOnlineIfNeeded(client))
|
||||||
|
{
|
||||||
|
AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||||
|
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
|
||||||
|
{
|
||||||
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
|
||||||
|
if (account == null) // foreign
|
||||||
|
{
|
||||||
|
FriendInfo[] friends = GetFriends(client.AgentId);
|
||||||
|
foreach (FriendInfo f in friends)
|
||||||
|
{
|
||||||
|
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||||
|
{
|
||||||
|
List<string> fList = new List<string>();
|
||||||
|
foreach (string s in friendList)
|
||||||
|
fList.Add(s.Substring(0, 36));
|
||||||
|
|
||||||
|
PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
|
||||||
|
foreach (PresenceInfo pi in presence)
|
||||||
|
{
|
||||||
|
UUID presenceID;
|
||||||
|
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||||
|
online.Add(presenceID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||||
|
//{
|
||||||
|
// // Let's single out the UUIs
|
||||||
|
// List<string> localFriends = new List<string>();
|
||||||
|
// List<string> foreignFriends = new List<string>();
|
||||||
|
// string tmp = string.Empty;
|
||||||
|
|
||||||
|
// foreach (string s in friendList)
|
||||||
|
// {
|
||||||
|
// UUID id;
|
||||||
|
// if (UUID.TryParse(s, out id))
|
||||||
|
// localFriends.Add(s);
|
||||||
|
// else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
|
||||||
|
// {
|
||||||
|
// foreignFriends.Add(s);
|
||||||
|
// // add it here too, who knows maybe the foreign friends happens to be on this grid
|
||||||
|
// localFriends.Add(id.ToString());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // OK, see who's present on this grid
|
||||||
|
// List<string> toBeRemoved = new List<string>();
|
||||||
|
// PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
|
||||||
|
// foreach (PresenceInfo pi in presence)
|
||||||
|
// {
|
||||||
|
// UUID presenceID;
|
||||||
|
// if (UUID.TryParse(pi.UserID, out presenceID))
|
||||||
|
// {
|
||||||
|
// online.Add(presenceID);
|
||||||
|
// foreach (string s in foreignFriends)
|
||||||
|
// if (s.StartsWith(pi.UserID))
|
||||||
|
// toBeRemoved.Add(s);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// foreach (string s in toBeRemoved)
|
||||||
|
// foreignFriends.Remove(s);
|
||||||
|
|
||||||
|
// // OK, let's send this up the stack, and leave a closure here
|
||||||
|
// // collecting online friends in other grids
|
||||||
|
// Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
|
||||||
|
//{
|
||||||
|
// // let's divide the friends on a per-domain basis
|
||||||
|
// Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
|
||||||
|
// foreach (string friend in foreignFriends)
|
||||||
|
// {
|
||||||
|
// UUID friendID;
|
||||||
|
// if (!UUID.TryParse(friend, out friendID))
|
||||||
|
// {
|
||||||
|
// // it's a foreign friend
|
||||||
|
// string url = string.Empty, tmp = string.Empty;
|
||||||
|
// if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
|
||||||
|
// {
|
||||||
|
// if (!friendsPerDomain.ContainsKey(url))
|
||||||
|
// friendsPerDomain[url] = new List<string>();
|
||||||
|
// friendsPerDomain[url].Add(friend);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Now, call those worlds
|
||||||
|
|
||||||
|
// foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
|
||||||
|
// {
|
||||||
|
// List<string> ids = new List<string>();
|
||||||
|
// foreach (string f in kvp.Value)
|
||||||
|
// ids.Add(f);
|
||||||
|
// UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
|
||||||
|
// List<UUID> online = uConn.GetOnlineFriends(userID, ids);
|
||||||
|
// // Finally send the notifications to the user
|
||||||
|
// // this whole process may take a while, so let's check at every
|
||||||
|
// // iteration that the user is still here
|
||||||
|
// IClientAPI client = LocateClientObject(userID);
|
||||||
|
// if (client != null)
|
||||||
|
// client.SendAgentOnline(online.ToArray());
|
||||||
|
// else
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||||
|
{
|
||||||
|
// First, let's divide the friends on a per-domain basis
|
||||||
|
Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
|
||||||
|
foreach (FriendInfo friend in friendList)
|
||||||
|
{
|
||||||
|
UUID friendID;
|
||||||
|
if (UUID.TryParse(friend.Friend, out friendID))
|
||||||
|
{
|
||||||
|
if (!friendsPerDomain.ContainsKey("local"))
|
||||||
|
friendsPerDomain["local"] = new List<FriendInfo>();
|
||||||
|
friendsPerDomain["local"].Add(friend);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// it's a foreign friend
|
||||||
|
string url = string.Empty, tmp = string.Empty;
|
||||||
|
if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
|
||||||
|
{
|
||||||
|
// Let's try our luck in the local sim. Who knows, maybe it's here
|
||||||
|
if (LocalStatusNotification(userID, friendID, online))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!friendsPerDomain.ContainsKey(url))
|
||||||
|
friendsPerDomain[url] = new List<FriendInfo>();
|
||||||
|
friendsPerDomain[url].Add(friend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the local friends, just call the base method
|
||||||
|
// Let's do this first of all
|
||||||
|
if (friendsPerDomain.ContainsKey("local"))
|
||||||
|
base.StatusNotify(friendsPerDomain["local"], userID, online);
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
|
||||||
|
{
|
||||||
|
if (kvp.Key != "local")
|
||||||
|
{
|
||||||
|
// For the others, call the user agent service
|
||||||
|
List<string> ids = new List<string>();
|
||||||
|
foreach (FriendInfo f in kvp.Value)
|
||||||
|
ids.Add(f.Friend);
|
||||||
|
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
|
||||||
|
List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
|
||||||
|
|
||||||
|
if (online && friendsOnline.Count > 0)
|
||||||
|
{
|
||||||
|
IClientAPI client = LocateClientObject(userID);
|
||||||
|
if (client != null)
|
||||||
|
client.SendAgentOnline(friendsOnline.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||||
|
{
|
||||||
|
first = "Unknown"; last = "User";
|
||||||
|
if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// fid is not a UUID...
|
||||||
|
string url = string.Empty, tmp = string.Empty;
|
||||||
|
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
|
||||||
|
{
|
||||||
|
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||||
|
userMan.AddUser(agentID, first, last, url);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string GetFriendshipRequesterName(UUID agentID)
|
||||||
|
{
|
||||||
|
// For the time being we assume that HG friendship requests can only happen
|
||||||
|
// when avies are on the same region.
|
||||||
|
IClientAPI client = LocateClientObject(agentID);
|
||||||
|
if (client != null)
|
||||||
|
return client.FirstName + " " + client.LastName;
|
||||||
|
else
|
||||||
|
return base.GetFriendshipRequesterName(agentID);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string FriendshipMessage(string friendID)
|
||||||
|
{
|
||||||
|
UUID id;
|
||||||
|
if (UUID.TryParse(friendID, out id))
|
||||||
|
return base.FriendshipMessage(friendID);
|
||||||
|
|
||||||
|
return "Please confirm this friendship you made while you were away.";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
|
||||||
|
{
|
||||||
|
foreach (FriendInfo fi in friends)
|
||||||
|
{
|
||||||
|
if (fi.Friend.StartsWith(friendID.ToString()))
|
||||||
|
return fi;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||||
|
{
|
||||||
|
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
|
||||||
|
if (account1 != null)
|
||||||
|
return base.GetFriendsFromService(client);
|
||||||
|
|
||||||
|
FriendInfo[] finfos = new FriendInfo[0];
|
||||||
|
// Foreigner
|
||||||
|
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
|
||||||
|
if (agentClientCircuit != null)
|
||||||
|
{
|
||||||
|
string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||||
|
|
||||||
|
finfos = FriendsService.GetFriends(agentUUI);
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
|
||||||
|
}
|
||||||
|
return finfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
|
||||||
|
{
|
||||||
|
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||||
|
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
|
||||||
|
// Are they both local users?
|
||||||
|
if (account1 != null && account2 != null)
|
||||||
|
{
|
||||||
|
// local grid users
|
||||||
|
return base.StoreRights(agentID, friendID, rights);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account1 != null) // agent is local, friend is foreigner
|
||||||
|
{
|
||||||
|
FriendInfo[] finfos = GetFriends(agentID);
|
||||||
|
FriendInfo finfo = GetFriend(finfos, friendID);
|
||||||
|
if (finfo != null)
|
||||||
|
{
|
||||||
|
FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account2 != null) // agent is foreigner, friend is local
|
||||||
|
{
|
||||||
|
string agentUUI = GetUUI(friendID, agentID);
|
||||||
|
if (agentUUI != string.Empty)
|
||||||
|
{
|
||||||
|
FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void StoreBackwards(UUID friendID, UUID agentID)
|
||||||
|
{
|
||||||
|
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||||
|
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
|
||||||
|
// Are they both local users?
|
||||||
|
if (account1 != null && account2 != null)
|
||||||
|
{
|
||||||
|
// local grid users
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
|
||||||
|
base.StoreBackwards(friendID, agentID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no provision for this temporary friendship state
|
||||||
|
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void StoreFriendships(UUID agentID, UUID friendID)
|
||||||
|
{
|
||||||
|
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||||
|
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
|
||||||
|
// Are they both local users?
|
||||||
|
if (agentAccount != null && friendAccount != null)
|
||||||
|
{
|
||||||
|
// local grid users
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
|
||||||
|
base.StoreFriendships(agentID, friendID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok, at least one of them is foreigner, let's get their data
|
||||||
|
IClientAPI agentClient = LocateClientObject(agentID);
|
||||||
|
IClientAPI friendClient = LocateClientObject(friendID);
|
||||||
|
AgentCircuitData agentClientCircuit = null;
|
||||||
|
AgentCircuitData friendClientCircuit = null;
|
||||||
|
string agentUUI = string.Empty;
|
||||||
|
string friendUUI = string.Empty;
|
||||||
|
string agentFriendService = string.Empty;
|
||||||
|
string friendFriendService = string.Empty;
|
||||||
|
|
||||||
|
if (agentClient != null)
|
||||||
|
{
|
||||||
|
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
|
||||||
|
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||||
|
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||||
|
}
|
||||||
|
if (friendClient != null)
|
||||||
|
{
|
||||||
|
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
|
||||||
|
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
|
||||||
|
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
|
||||||
|
agentUUI, friendUUI, agentFriendService, friendFriendService);
|
||||||
|
|
||||||
|
// Generate a random 8-character hex number that will sign this friendship
|
||||||
|
string secret = UUID.Random().ToString().Substring(0, 8);
|
||||||
|
|
||||||
|
if (agentAccount != null) // agent is local, 'friend' is foreigner
|
||||||
|
{
|
||||||
|
// This may happen when the agent returned home, in which case the friend is not there
|
||||||
|
// We need to look for its information in the friends list itself
|
||||||
|
bool confirming = false;
|
||||||
|
if (friendUUI == string.Empty)
|
||||||
|
{
|
||||||
|
FriendInfo[] finfos = GetFriends(agentID);
|
||||||
|
foreach (FriendInfo finfo in finfos)
|
||||||
|
{
|
||||||
|
if (finfo.TheirFlags == -1)
|
||||||
|
{
|
||||||
|
if (finfo.Friend.StartsWith(friendID.ToString()))
|
||||||
|
{
|
||||||
|
friendUUI = finfo.Friend;
|
||||||
|
confirming = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's confirming the friendship, we already have the full friendUUI with the secret
|
||||||
|
string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
|
||||||
|
|
||||||
|
// store in the local friends service a reference to the foreign friend
|
||||||
|
FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
|
||||||
|
// and also the converse
|
||||||
|
FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
|
||||||
|
|
||||||
|
if (!confirming && friendClientCircuit != null)
|
||||||
|
{
|
||||||
|
// store in the foreign friends service a reference to the local agent
|
||||||
|
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
|
||||||
|
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (friendAccount != null) // 'friend' is local, agent is foreigner
|
||||||
|
{
|
||||||
|
// store in the local friends service a reference to the foreign agent
|
||||||
|
FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
|
||||||
|
// and also the converse
|
||||||
|
FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
|
||||||
|
|
||||||
|
if (agentClientCircuit != null)
|
||||||
|
{
|
||||||
|
// store in the foreign friends service a reference to the local agent
|
||||||
|
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
|
||||||
|
friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // They're both foreigners!
|
||||||
|
{
|
||||||
|
HGFriendsServicesConnector friendsConn;
|
||||||
|
if (agentClientCircuit != null)
|
||||||
|
{
|
||||||
|
friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
|
||||||
|
friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
|
||||||
|
}
|
||||||
|
if (friendClientCircuit != null)
|
||||||
|
{
|
||||||
|
friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
|
||||||
|
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// my brain hurts now
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||||
|
{
|
||||||
|
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||||
|
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
|
||||||
|
// Are they both local users?
|
||||||
|
if (agentAccount != null && friendAccount != null)
|
||||||
|
{
|
||||||
|
// local grid users
|
||||||
|
return base.DeleteFriendship(agentID, exfriendID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok, at least one of them is foreigner, let's get their data
|
||||||
|
string agentUUI = string.Empty;
|
||||||
|
string friendUUI = string.Empty;
|
||||||
|
|
||||||
|
if (agentAccount != null) // agent is local, 'friend' is foreigner
|
||||||
|
{
|
||||||
|
// We need to look for its information in the friends list itself
|
||||||
|
FriendInfo[] finfos = GetFriends(agentID);
|
||||||
|
FriendInfo finfo = GetFriend(finfos, exfriendID);
|
||||||
|
if (finfo != null)
|
||||||
|
{
|
||||||
|
friendUUI = finfo.Friend;
|
||||||
|
|
||||||
|
// delete in the local friends service the reference to the foreign friend
|
||||||
|
FriendsService.Delete(agentID, friendUUI);
|
||||||
|
// and also the converse
|
||||||
|
FriendsService.Delete(friendUUI, agentID.ToString());
|
||||||
|
|
||||||
|
// notify the exfriend's service
|
||||||
|
Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
|
||||||
|
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (friendAccount != null) // agent is foreigner, 'friend' is local
|
||||||
|
{
|
||||||
|
agentUUI = GetUUI(exfriendID, agentID);
|
||||||
|
|
||||||
|
if (agentUUI != string.Empty)
|
||||||
|
{
|
||||||
|
// delete in the local friends service the reference to the foreign agent
|
||||||
|
FriendsService.Delete(exfriendID, agentUUI);
|
||||||
|
// and also the converse
|
||||||
|
FriendsService.Delete(agentUUI, exfriendID.ToString());
|
||||||
|
|
||||||
|
// notify the agent's service?
|
||||||
|
Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
|
||||||
|
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else They're both foreigners! Can't handle this
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetUUI(UUID localUser, UUID foreignUser)
|
||||||
|
{
|
||||||
|
// Let's see if the user is here by any chance
|
||||||
|
FriendInfo[] finfos = GetFriends(localUser);
|
||||||
|
if (finfos != EMPTY_FRIENDS) // friend is here, cool
|
||||||
|
{
|
||||||
|
FriendInfo finfo = GetFriend(finfos, foreignUser);
|
||||||
|
if (finfo != null)
|
||||||
|
{
|
||||||
|
return finfo.Friend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // user is not currently on this sim, need to get from the service
|
||||||
|
{
|
||||||
|
finfos = FriendsService.GetFriends(localUser);
|
||||||
|
foreach (FriendInfo finfo in finfos)
|
||||||
|
{
|
||||||
|
if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
|
||||||
|
{
|
||||||
|
return finfo.Friend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Delete(UUID foreignUser, UUID localUser, string uui)
|
||||||
|
{
|
||||||
|
UUID id;
|
||||||
|
string url = string.Empty, secret = string.Empty, tmp = string.Empty;
|
||||||
|
if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
|
||||||
|
HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
|
||||||
|
friendConn.DeleteFriendship(foreignUser, localUser, secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,350 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using Nwc.XmlRpc;
|
||||||
|
using Mono.Addins;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Services.Connectors.InstantMessage;
|
||||||
|
using OpenSim.Services.Connectors.Hypergrid;
|
||||||
|
using OpenSim.Server.Handlers.Hypergrid;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
protected bool m_Enabled = false;
|
||||||
|
protected List<Scene> m_Scenes = new List<Scene>();
|
||||||
|
|
||||||
|
protected IInstantMessage m_IMService;
|
||||||
|
protected Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
|
||||||
|
|
||||||
|
public event UndeliveredMessage OnUndeliveredMessage;
|
||||||
|
|
||||||
|
IUserManagement m_uMan;
|
||||||
|
IUserManagement UserManagementModule
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (m_uMan == null)
|
||||||
|
m_uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||||
|
return m_uMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Initialise(IConfigSource config)
|
||||||
|
{
|
||||||
|
IConfig cnf = config.Configs["Messaging"];
|
||||||
|
if (cnf != null && cnf.GetString(
|
||||||
|
"MessageTransferModule", "MessageTransferModule") != Name)
|
||||||
|
{
|
||||||
|
m_log.Debug("[HG MESSAGE TRANSFER]: Disabled by configuration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstantMessageServerConnector imServer = new InstantMessageServerConnector(config, MainServer.Instance, this);
|
||||||
|
m_IMService = imServer.GetService();
|
||||||
|
m_Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (m_Scenes)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HG MESSAGE TRANSFER]: Message transfer module {0} active", Name);
|
||||||
|
scene.RegisterModuleInterface<IMessageTransferModule>(this);
|
||||||
|
m_Scenes.Add(scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void PostInitialise()
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void RegionLoaded(Scene scene)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (m_Scenes)
|
||||||
|
{
|
||||||
|
m_Scenes.Remove(scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string Name
|
||||||
|
{
|
||||||
|
get { return "HGMessageTransferModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
|
||||||
|
{
|
||||||
|
UUID toAgentID = new UUID(im.toAgentID);
|
||||||
|
|
||||||
|
// Try root avatar only first
|
||||||
|
foreach (Scene scene in m_Scenes)
|
||||||
|
{
|
||||||
|
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||||
|
scene.Entities[toAgentID] is ScenePresence)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
||||||
|
// toAgentID.ToString(), scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||||
|
if (!user.IsChildAgent)
|
||||||
|
{
|
||||||
|
// Local message
|
||||||
|
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
|
||||||
|
user.ControllingClient.SendInstantMessage(im);
|
||||||
|
|
||||||
|
// Message sent
|
||||||
|
result(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try child avatar second
|
||||||
|
foreach (Scene scene in m_Scenes)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||||
|
scene.Entities[toAgentID] is ScenePresence)
|
||||||
|
{
|
||||||
|
// Local message
|
||||||
|
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
|
||||||
|
user.ControllingClient.SendInstantMessage(im);
|
||||||
|
|
||||||
|
// Message sent
|
||||||
|
result(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
|
||||||
|
// Is the user a local user?
|
||||||
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
|
||||||
|
string url = string.Empty;
|
||||||
|
bool foreigner = false;
|
||||||
|
if (account == null) // foreign user
|
||||||
|
{
|
||||||
|
url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
|
||||||
|
foreigner = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Util.FireAndForget(delegate
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
if (foreigner && url == string.Empty) // we don't know about this user
|
||||||
|
{
|
||||||
|
string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
|
||||||
|
m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
|
||||||
|
if (recipientUUI != string.Empty)
|
||||||
|
{
|
||||||
|
UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
|
||||||
|
if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
|
||||||
|
{
|
||||||
|
success = m_IMService.OutgoingInstantMessage(im, u, true);
|
||||||
|
if (success)
|
||||||
|
UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
|
||||||
|
|
||||||
|
if (!success && !foreigner)
|
||||||
|
HandleUndeliveredMessage(im, result);
|
||||||
|
else
|
||||||
|
result(success);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool SendIMToScene(GridInstantMessage gim, UUID toAgentID)
|
||||||
|
{
|
||||||
|
bool successful = false;
|
||||||
|
foreach (Scene scene in m_Scenes)
|
||||||
|
{
|
||||||
|
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||||
|
scene.Entities[toAgentID] is ScenePresence)
|
||||||
|
{
|
||||||
|
ScenePresence user =
|
||||||
|
(ScenePresence)scene.Entities[toAgentID];
|
||||||
|
|
||||||
|
if (!user.IsChildAgent)
|
||||||
|
{
|
||||||
|
scene.EventManager.TriggerIncomingInstantMessage(gim);
|
||||||
|
successful = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!successful)
|
||||||
|
{
|
||||||
|
// If the message can't be delivered to an agent, it
|
||||||
|
// is likely to be a group IM. On a group IM, the
|
||||||
|
// imSessionID = toAgentID = group id. Raise the
|
||||||
|
// unhandled IM event to give the groups module
|
||||||
|
// a chance to pick it up. We raise that in a random
|
||||||
|
// scene, since the groups module is shared.
|
||||||
|
//
|
||||||
|
m_Scenes[0].EventManager.TriggerUnhandledInstantMessage(gim);
|
||||||
|
}
|
||||||
|
|
||||||
|
return successful;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
|
||||||
|
{
|
||||||
|
UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
|
||||||
|
|
||||||
|
// If this event has handlers, then an IM from an agent will be
|
||||||
|
// considered delivered. This will suppress the error message.
|
||||||
|
//
|
||||||
|
if (handlerUndeliveredMessage != null)
|
||||||
|
{
|
||||||
|
handlerUndeliveredMessage(im);
|
||||||
|
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
|
||||||
|
result(true);
|
||||||
|
else
|
||||||
|
result(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
|
||||||
|
result(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string TryGetRecipientUUI(UUID fromAgent, UUID toAgent)
|
||||||
|
{
|
||||||
|
// Let's call back the fromAgent's user agent service
|
||||||
|
// Maybe that service knows about the toAgent
|
||||||
|
IClientAPI client = LocateClientObject(fromAgent);
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
AgentCircuitData circuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||||
|
if (circuit != null)
|
||||||
|
{
|
||||||
|
if (circuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||||
|
{
|
||||||
|
string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
|
||||||
|
m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
|
||||||
|
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
|
||||||
|
return uasConn.GetUUI(fromAgent, toAgent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find the scene for an agent
|
||||||
|
/// </summary>
|
||||||
|
private Scene GetClientScene(UUID agentId)
|
||||||
|
{
|
||||||
|
lock (m_Scenes)
|
||||||
|
{
|
||||||
|
foreach (Scene scene in m_Scenes)
|
||||||
|
{
|
||||||
|
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||||
|
if (presence != null && !presence.IsChildAgent)
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find the client for a ID
|
||||||
|
/// </summary>
|
||||||
|
public IClientAPI LocateClientObject(UUID agentID)
|
||||||
|
{
|
||||||
|
Scene scene = GetClientScene(agentID);
|
||||||
|
if (scene != null)
|
||||||
|
{
|
||||||
|
ScenePresence presence = scene.GetScenePresence(agentID);
|
||||||
|
if (presence != null)
|
||||||
|
return presence.ControllingClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IInstantMessageSimConnector
|
||||||
|
public bool SendInstantMessage(GridInstantMessage im)
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("[XXX] Hook SendInstantMessage {0}", im.message);
|
||||||
|
UUID agentID = new UUID(im.toAgentID);
|
||||||
|
return SendIMToScene(im, agentID);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -149,14 +149,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder.
|
/// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder.
|
||||||
///
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
/// This method does not handle paths that contain multiple delimitors
|
/// This method does not handle paths that contain multiple delimitors
|
||||||
///
|
///
|
||||||
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
|
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
|
||||||
/// XPath like expression
|
/// XPath like expression
|
||||||
///
|
///
|
||||||
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
|
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
|
||||||
/// </summary>
|
/// </remarks>
|
||||||
///
|
///
|
||||||
/// <param name="inventoryService">
|
/// <param name="inventoryService">
|
||||||
/// Inventory service to query
|
/// Inventory service to query
|
||||||
|
@ -178,32 +179,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
|
|
||||||
return FindItemByPath(inventoryService, rootFolder, path);
|
return FindItemByPath(inventoryService, rootFolder, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
|
/// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
|
||||||
///
|
/// </summary>
|
||||||
/// This method does not handle paths that contain multiple delimitors
|
/// <remarks>
|
||||||
|
/// This method does not handle paths that contain multiple delimiters
|
||||||
///
|
///
|
||||||
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
|
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
|
||||||
/// XPath like expression
|
/// XPath like expression
|
||||||
///
|
///
|
||||||
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
|
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
|
||||||
/// </summary>
|
/// </remarks>
|
||||||
///
|
///
|
||||||
/// <param name="inventoryService">
|
/// <param name="inventoryService">Inventory service to query</param>
|
||||||
/// Inventory service to query
|
/// <param name="startFolder">The folder from which the path starts</param>
|
||||||
/// </param>
|
/// <param name="path">The path to the required item.</param>
|
||||||
/// <param name="startFolder">
|
|
||||||
/// The folder from which the path starts
|
|
||||||
/// </param>
|
|
||||||
/// <param name="path">
|
|
||||||
/// <param name="path">
|
|
||||||
/// The path to the required item.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>null if the item is not found</returns>
|
/// <returns>null if the item is not found</returns>
|
||||||
public static InventoryItemBase FindItemByPath(
|
public static InventoryItemBase FindItemByPath(
|
||||||
IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
|
IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
|
||||||
{
|
{
|
||||||
|
List<InventoryItemBase> foundItems = FindItemsByPath(inventoryService, startFolder, path);
|
||||||
|
|
||||||
|
if (foundItems.Count != 0)
|
||||||
|
return foundItems[0];
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<InventoryItemBase> FindItemsByPath(
|
||||||
|
IInventoryService inventoryService, UUID userId, string path)
|
||||||
|
{
|
||||||
|
InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
|
||||||
|
|
||||||
|
if (null == rootFolder)
|
||||||
|
return new List<InventoryItemBase>();
|
||||||
|
|
||||||
|
return FindItemsByPath(inventoryService, rootFolder, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find items that match a given PATH_DELIMITOR delimited path starting from this folder.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method does not handle paths that contain multiple delimiters
|
||||||
|
///
|
||||||
|
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
|
||||||
|
/// XPath like expression
|
||||||
|
///
|
||||||
|
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
|
||||||
|
/// </remarks>
|
||||||
|
///
|
||||||
|
/// <param name="inventoryService">Inventory service to query</param>
|
||||||
|
/// <param name="startFolder">The folder from which the path starts</param>
|
||||||
|
/// <param name="path">The path to the required item.</param>
|
||||||
|
/// <returns>The items that were found with this path. An empty list if no items were found.</returns>
|
||||||
|
public static List<InventoryItemBase> FindItemsByPath(
|
||||||
|
IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
|
||||||
|
{
|
||||||
|
List<InventoryItemBase> foundItems = new List<InventoryItemBase>();
|
||||||
|
|
||||||
// If the path isn't just / then trim any starting extraneous slashes
|
// If the path isn't just / then trim any starting extraneous slashes
|
||||||
path = path.TrimStart(new char[] { PATH_DELIMITER });
|
path = path.TrimStart(new char[] { PATH_DELIMITER });
|
||||||
|
|
||||||
|
@ -215,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
if (components.Length == 1)
|
if (components.Length == 1)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
|
// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
|
||||||
// components[0], startFolder.Name, startFolder.ID);
|
// components[0], startFolder.Name, startFolder.ID);
|
||||||
|
|
||||||
List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
|
List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
|
||||||
|
|
||||||
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
|
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
|
||||||
|
|
||||||
foreach (InventoryItemBase item in items)
|
foreach (InventoryItemBase item in items)
|
||||||
|
@ -227,24 +262,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
|
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
|
||||||
|
|
||||||
if (item.Name == components[0])
|
if (item.Name == components[0])
|
||||||
return item;
|
foundItems.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
|
// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
|
||||||
|
|
||||||
InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
|
InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
|
||||||
|
|
||||||
foreach (InventoryFolderBase folder in contents.Folders)
|
foreach (InventoryFolderBase folder in contents.Folders)
|
||||||
{
|
{
|
||||||
if (folder.Name == components[0])
|
if (folder.Name == components[0])
|
||||||
return FindItemByPath(inventoryService, folder, components[1]);
|
foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We didn't find an item or intermediate folder with the given name
|
return foundItems;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -146,6 +146,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
|
|
||||||
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
|
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
|
||||||
{
|
{
|
||||||
|
if (options.ContainsKey("verbose"))
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}",
|
||||||
|
inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID);
|
||||||
|
|
||||||
string filename = path + CreateArchiveItemName(inventoryItem);
|
string filename = path + CreateArchiveItemName(inventoryItem);
|
||||||
|
|
||||||
// Record the creator of this item for user record purposes (which might go away soon)
|
// Record the creator of this item for user record purposes (which might go away soon)
|
||||||
|
@ -154,7 +159,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
|
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
|
||||||
m_archiveWriter.WriteFile(filename, serialization);
|
m_archiveWriter.WriteFile(filename, serialization);
|
||||||
|
|
||||||
if (SaveAssets)
|
AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
|
||||||
|
|
||||||
|
// Don't chase down link asset items as they actually point to their target item IDs rather than an asset
|
||||||
|
if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
|
||||||
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
|
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,10 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
|
|
||||||
// The path may point to an item instead
|
// The path may point to an item instead
|
||||||
if (inventoryFolder == null)
|
if (inventoryFolder == null)
|
||||||
{
|
|
||||||
inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
|
inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
|
||||||
//inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null == inventoryFolder && null == inventoryItem)
|
if (null == inventoryFolder && null == inventoryItem)
|
||||||
{
|
{
|
||||||
|
@ -441,4 +446,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,244 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Mono.Addins;
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Connectors.Hypergrid;
|
||||||
|
|
||||||
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class HGLureModule : ISharedRegionModule
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(
|
||||||
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||||
|
|
||||||
|
private IMessageTransferModule m_TransferModule = null;
|
||||||
|
private bool m_Enabled = false;
|
||||||
|
|
||||||
|
private string m_ThisGridURL;
|
||||||
|
|
||||||
|
private ExpiringCache<UUID, GridInstantMessage> m_PendingLures = new ExpiringCache<UUID, GridInstantMessage>();
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource config)
|
||||||
|
{
|
||||||
|
if (config.Configs["Messaging"] != null)
|
||||||
|
{
|
||||||
|
if (config.Configs["Messaging"].GetString("LureModule", string.Empty) == "HGLureModule")
|
||||||
|
{
|
||||||
|
m_Enabled = true;
|
||||||
|
|
||||||
|
m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty);
|
||||||
|
m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (m_scenes)
|
||||||
|
{
|
||||||
|
m_scenes.Add(scene);
|
||||||
|
scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage;
|
||||||
|
scene.EventManager.OnNewClient += OnNewClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_TransferModule == null)
|
||||||
|
{
|
||||||
|
m_TransferModule =
|
||||||
|
scene.RequestModuleInterface<IMessageTransferModule>();
|
||||||
|
|
||||||
|
if (m_TransferModule == null)
|
||||||
|
{
|
||||||
|
m_log.Error("[LURE MODULE]: No message transfer module, lures will not work!");
|
||||||
|
|
||||||
|
m_Enabled = false;
|
||||||
|
m_scenes.Clear();
|
||||||
|
scene.EventManager.OnNewClient -= OnNewClient;
|
||||||
|
scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (m_scenes)
|
||||||
|
{
|
||||||
|
m_scenes.Remove(scene);
|
||||||
|
scene.EventManager.OnNewClient -= OnNewClient;
|
||||||
|
scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnNewClient(IClientAPI client)
|
||||||
|
{
|
||||||
|
client.OnInstantMessage += OnInstantMessage;
|
||||||
|
client.OnStartLure += OnStartLure;
|
||||||
|
client.OnTeleportLureRequest += OnTeleportLureRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "HGLureModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnInstantMessage(IClientAPI client, GridInstantMessage im)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnIncomingInstantMessage(GridInstantMessage im)
|
||||||
|
{
|
||||||
|
if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
|
||||||
|
{
|
||||||
|
UUID sessionID = new UUID(im.imSessionID);
|
||||||
|
m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
|
||||||
|
m_PendingLures.Add(sessionID, im, 7200); // 2 hours
|
||||||
|
|
||||||
|
// Forward. We do this, because the IM module explicitly rejects
|
||||||
|
// IMs of this type
|
||||||
|
if (m_TransferModule != null)
|
||||||
|
m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client)
|
||||||
|
{
|
||||||
|
if (!(client.Scene is Scene))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Scene scene = (Scene)(client.Scene);
|
||||||
|
ScenePresence presence = scene.GetScenePresence(client.AgentId);
|
||||||
|
|
||||||
|
message += "@" + m_ThisGridURL;
|
||||||
|
|
||||||
|
m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
|
||||||
|
|
||||||
|
GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
|
||||||
|
client.FirstName+" "+client.LastName, targetid,
|
||||||
|
(byte)InstantMessageDialog.RequestTeleport, false,
|
||||||
|
message, UUID.Random(), false, presence.AbsolutePosition,
|
||||||
|
new Byte[0]);
|
||||||
|
m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
|
||||||
|
|
||||||
|
if (m_TransferModule != null)
|
||||||
|
{
|
||||||
|
m_TransferModule.SendInstantMessage(m,
|
||||||
|
delegate(bool success) { });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client)
|
||||||
|
{
|
||||||
|
if (!(client.Scene is Scene))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Scene scene = (Scene)(client.Scene);
|
||||||
|
|
||||||
|
GridInstantMessage im = null;
|
||||||
|
if (m_PendingLures.TryGetValue(lureID, out im))
|
||||||
|
{
|
||||||
|
m_PendingLures.Remove(lureID);
|
||||||
|
Lure(client, teleportFlags, im);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im)
|
||||||
|
{
|
||||||
|
Scene scene = (Scene)(client.Scene);
|
||||||
|
GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID));
|
||||||
|
if (region != null)
|
||||||
|
scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags);
|
||||||
|
else // we don't have that region here. Check if it's HG
|
||||||
|
{
|
||||||
|
string[] parts = im.message.Split(new char[] { '@' });
|
||||||
|
if (parts.Length > 1)
|
||||||
|
{
|
||||||
|
string url = parts[parts.Length - 1]; // the last part
|
||||||
|
if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'}))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position);
|
||||||
|
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
|
||||||
|
GridRegion gatekeeper = new GridRegion();
|
||||||
|
gatekeeper.ServerURI = url;
|
||||||
|
GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID));
|
||||||
|
if (finalDestination != null)
|
||||||
|
{
|
||||||
|
ScenePresence sp = scene.GetScenePresence(client.AgentId);
|
||||||
|
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
|
||||||
|
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
|
||||||
|
if (transferMod != null && sp != null && eq != null)
|
||||||
|
transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,16 +45,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||||
private readonly List<Scene> m_scenes = new List<Scene>();
|
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||||
|
|
||||||
private IMessageTransferModule m_TransferModule = null;
|
private IMessageTransferModule m_TransferModule = null;
|
||||||
private bool m_Enabled = true;
|
private bool m_Enabled = false;
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
public void Initialise(IConfigSource config)
|
||||||
{
|
{
|
||||||
if (config.Configs["Messaging"] != null)
|
if (config.Configs["Messaging"] != null)
|
||||||
{
|
{
|
||||||
if (config.Configs["Messaging"].GetString(
|
if (config.Configs["Messaging"].GetString(
|
||||||
"LureModule", "LureModule") !=
|
"LureModule", "LureModule") ==
|
||||||
"LureModule")
|
"LureModule")
|
||||||
m_Enabled = false;
|
{
|
||||||
|
m_Enabled = true;
|
||||||
|
m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
public void RegionLoaded(Scene scene)
|
||||||
{
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
if (m_TransferModule == null)
|
if (m_TransferModule == null)
|
||||||
{
|
{
|
||||||
m_TransferModule =
|
m_TransferModule =
|
||||||
|
@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
{
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
lock (m_scenes)
|
lock (m_scenes)
|
||||||
{
|
{
|
||||||
m_scenes.Remove(scene);
|
m_scenes.Remove(scene);
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using Mono.Addins;
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.Avatar.Profile
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class BasicProfileModule : ISharedRegionModule
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Module vars
|
||||||
|
//
|
||||||
|
private List<Scene> m_Scenes = new List<Scene>();
|
||||||
|
private bool m_Enabled = false;
|
||||||
|
|
||||||
|
#region ISharedRegionModule
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource config)
|
||||||
|
{
|
||||||
|
if (config.Configs["Profile"] != null)
|
||||||
|
{
|
||||||
|
if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
|
||||||
|
m_Enabled = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (m_Scenes)
|
||||||
|
{
|
||||||
|
if (!m_Scenes.Contains(scene))
|
||||||
|
{
|
||||||
|
m_Scenes.Add(scene);
|
||||||
|
// Hook up events
|
||||||
|
scene.EventManager.OnNewClient += OnNewClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (m_Scenes)
|
||||||
|
{
|
||||||
|
m_Scenes.Remove(scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "BasicProfileModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// New Client Event Handler
|
||||||
|
private void OnNewClient(IClientAPI client)
|
||||||
|
{
|
||||||
|
//Profile
|
||||||
|
client.OnRequestAvatarProperties += RequestAvatarProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
|
||||||
|
{
|
||||||
|
IScene s = remoteClient.Scene;
|
||||||
|
if (!(s is Scene))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Scene scene = (Scene)s;
|
||||||
|
|
||||||
|
string profileUrl = String.Empty;
|
||||||
|
string aboutText = String.Empty;
|
||||||
|
string firstLifeAboutText = String.Empty;
|
||||||
|
UUID image = UUID.Zero;
|
||||||
|
UUID firstLifeImage = UUID.Zero;
|
||||||
|
UUID partner = UUID.Zero;
|
||||||
|
uint wantMask = 0;
|
||||||
|
string wantText = String.Empty;
|
||||||
|
uint skillsMask = 0;
|
||||||
|
string skillsText = String.Empty;
|
||||||
|
string languages = String.Empty;
|
||||||
|
|
||||||
|
Byte[] charterMember = Utils.StringToBytes("Avatar");
|
||||||
|
|
||||||
|
profileUrl = "No profile data";
|
||||||
|
aboutText = string.Empty;
|
||||||
|
firstLifeAboutText = string.Empty;
|
||||||
|
image = UUID.Zero;
|
||||||
|
firstLifeImage = UUID.Zero;
|
||||||
|
partner = UUID.Zero;
|
||||||
|
|
||||||
|
remoteClient.SendAvatarProperties(avatarID, aboutText,
|
||||||
|
Util.ToDateTime(0).ToString(
|
||||||
|
"M/d/yyyy", CultureInfo.InvariantCulture),
|
||||||
|
charterMember, firstLifeAboutText,
|
||||||
|
(uint)(0 & 0xff),
|
||||||
|
firstLifeImage, image, profileUrl, partner);
|
||||||
|
|
||||||
|
//Viewer expects interest data when it asks for properties.
|
||||||
|
remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
|
||||||
|
skillsMask, skillsText, languages);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
protected bool m_Enabled = false;
|
protected bool m_Enabled = false;
|
||||||
protected Scene m_aScene;
|
protected Scene m_aScene;
|
||||||
|
protected List<Scene> m_Scenes = new List<Scene>();
|
||||||
protected List<UUID> m_agentsInTransit;
|
protected List<UUID> m_agentsInTransit;
|
||||||
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
|
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
|
||||||
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
|
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
|
||||||
|
@ -96,13 +97,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
if (m_aScene == null)
|
if (m_aScene == null)
|
||||||
m_aScene = scene;
|
m_aScene = scene;
|
||||||
|
|
||||||
|
m_Scenes.Add(scene);
|
||||||
scene.RegisterModuleInterface<IEntityTransferModule>(this);
|
scene.RegisterModuleInterface<IEntityTransferModule>(this);
|
||||||
scene.EventManager.OnNewClient += OnNewClient;
|
scene.EventManager.OnNewClient += OnNewClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnNewClient(IClientAPI client)
|
protected virtual void OnNewClient(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnTeleportHomeRequest += TeleportHomeFired;
|
client.OnTeleportHomeRequest += TriggerTeleportHome;
|
||||||
|
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Close()
|
public virtual void Close()
|
||||||
|
@ -118,6 +121,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return;
|
return;
|
||||||
if (scene == m_aScene)
|
if (scene == m_aScene)
|
||||||
m_aScene = null;
|
m_aScene = null;
|
||||||
|
|
||||||
|
m_Scenes.Remove(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RegionLoaded(Scene scene)
|
public virtual void RegionLoaded(Scene scene)
|
||||||
|
@ -127,7 +132,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Agent Teleports
|
#region Agent Teleports
|
||||||
|
@ -249,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
|
public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
|
||||||
{
|
{
|
||||||
if (reg == null || finalDestination == null)
|
if (reg == null || finalDestination == null)
|
||||||
{
|
{
|
||||||
|
@ -557,9 +561,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Landmark Teleport
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to teleport agent to landmark.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="remoteClient"></param>
|
||||||
|
/// <param name="regionHandle"></param>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
|
||||||
|
{
|
||||||
|
GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
|
||||||
|
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
// can't find the region: Tell viewer and abort
|
||||||
|
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
|
||||||
|
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Teleport Home
|
#region Teleport Home
|
||||||
|
|
||||||
public void TeleportHomeFired(UUID id, IClientAPI client)
|
public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
|
||||||
{
|
{
|
||||||
TeleportHome(id, client);
|
TeleportHome(id, client);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
protected override void OnNewClient(IClientAPI client)
|
protected override void OnNewClient(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnTeleportHomeRequest += TeleportHomeFired;
|
client.OnTeleportHomeRequest += TriggerTeleportHome;
|
||||||
|
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
|
||||||
client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
|
client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,8 +147,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
{
|
{
|
||||||
base.AgentHasMovedAway(sp, logout);
|
base.AgentHasMovedAway(sp, logout);
|
||||||
if (logout)
|
if (logout)
|
||||||
|
{
|
||||||
// Log them out of this grid
|
// Log them out of this grid
|
||||||
m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
|
m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
|
protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
|
||||||
|
@ -178,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
|
return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TeleportHomeFired(UUID id, IClientAPI client)
|
public void TriggerTeleportHome(UUID id, IClientAPI client)
|
||||||
{
|
{
|
||||||
TeleportHome(id, client);
|
TeleportHome(id, client);
|
||||||
}
|
}
|
||||||
|
@ -233,6 +236,57 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
|
DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to teleport agent to landmark.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="remoteClient"></param>
|
||||||
|
/// <param name="regionHandle"></param>
|
||||||
|
/// <param name="position"></param>
|
||||||
|
public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
|
||||||
|
(lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
|
||||||
|
if (lm.Gatekeeper == string.Empty)
|
||||||
|
{
|
||||||
|
base.RequestTeleportLandmark(remoteClient, lm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
|
||||||
|
|
||||||
|
// Local region?
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
|
||||||
|
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Foreign region
|
||||||
|
Scene scene = (Scene)(remoteClient.Scene);
|
||||||
|
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
|
||||||
|
GridRegion gatekeeper = new GridRegion();
|
||||||
|
gatekeeper.ServerURI = lm.Gatekeeper;
|
||||||
|
GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID));
|
||||||
|
if (finalDestination != null)
|
||||||
|
{
|
||||||
|
ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
|
||||||
|
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
|
||||||
|
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
|
||||||
|
if (transferMod != null && sp != null && eq != null)
|
||||||
|
transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position,
|
||||||
|
Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// can't find the region: Tell viewer and abort
|
||||||
|
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IUserAgentVerificationModule
|
#region IUserAgentVerificationModule
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
|
|
||||||
private string m_ProfileServerURI;
|
private string m_ProfileServerURI;
|
||||||
private bool m_OutboundPermission;
|
private bool m_OutboundPermission;
|
||||||
|
private string m_ThisGatekeeper;
|
||||||
|
|
||||||
// private bool m_Initialized = false;
|
// private bool m_Initialized = false;
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
{
|
{
|
||||||
m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
|
m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
|
||||||
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
|
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
|
||||||
|
m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
|
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
|
||||||
|
@ -110,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
|
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
|
||||||
{
|
{
|
||||||
string userAssetServer = string.Empty;
|
string userAssetServer = string.Empty;
|
||||||
if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission)
|
if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
|
||||||
{
|
{
|
||||||
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
|
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
|
||||||
}
|
}
|
||||||
|
@ -119,6 +121,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Overrides of Basic Inventory Access methods
|
#region Overrides of Basic Inventory Access methods
|
||||||
|
|
||||||
|
protected override string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
|
||||||
|
{
|
||||||
|
UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, presence.UUID);
|
||||||
|
if (account == null)
|
||||||
|
prefix = "HG ";
|
||||||
|
else
|
||||||
|
prefix = string.Empty;
|
||||||
|
suffix = " @ " + m_ThisGatekeeper;
|
||||||
|
Vector3 pos = presence.AbsolutePosition;
|
||||||
|
return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n",
|
||||||
|
presence.Scene.RegionInfo.RegionID,
|
||||||
|
pos.X, pos.Y, pos.Z,
|
||||||
|
presence.RegionHandle,
|
||||||
|
m_ThisGatekeeper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// CapsUpdateInventoryItemAsset
|
/// CapsUpdateInventoryItemAsset
|
||||||
///
|
///
|
||||||
|
@ -180,10 +200,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
|
public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
|
||||||
{
|
{
|
||||||
string userAssetServer = string.Empty;
|
string userAssetServer = string.Empty;
|
||||||
if (IsForeignUser(sender, out userAssetServer))
|
if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty)
|
||||||
m_assMapper.Get(item.AssetID, sender, userAssetServer);
|
m_assMapper.Get(item.AssetID, sender, userAssetServer);
|
||||||
|
|
||||||
if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission)
|
if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
|
||||||
m_assMapper.Post(item.AssetID, receiver, userAssetServer);
|
m_assMapper.Post(item.AssetID, receiver, userAssetServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,9 +223,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
|
if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
|
||||||
{
|
{
|
||||||
assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
|
assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
|
||||||
assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true;
|
assetServerURL = assetServerURL.Trim(new char[] { '/' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI");
|
||||||
|
assetServerURL = assetServerURL.Trim(new char[] { '/' });
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
@ -128,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
|
|
||||||
protected virtual void OnNewClient(IClientAPI client)
|
protected virtual void OnNewClient(IClientAPI client)
|
||||||
{
|
{
|
||||||
|
client.OnCreateNewInventoryItem += CreateNewInventoryItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Close()
|
public virtual void Close()
|
||||||
|
@ -156,6 +157,87 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
|
|
||||||
#region Inventory Access
|
#region Inventory Access
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new inventory item. Called when the client creates a new item directly within their
|
||||||
|
/// inventory (e.g. by selecting a context inventory menu option).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="remoteClient"></param>
|
||||||
|
/// <param name="transactionID"></param>
|
||||||
|
/// <param name="folderID"></param>
|
||||||
|
/// <param name="callbackID"></param>
|
||||||
|
/// <param name="description"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <param name="invType"></param>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="wearableType"></param>
|
||||||
|
/// <param name="nextOwnerMask"></param>
|
||||||
|
public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
|
||||||
|
uint callbackID, string description, string name, sbyte invType,
|
||||||
|
sbyte assetType,
|
||||||
|
byte wearableType, uint nextOwnerMask, int creationDate)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
|
||||||
|
|
||||||
|
if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
|
||||||
|
InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f);
|
||||||
|
|
||||||
|
if (folder == null || folder.Owner != remoteClient.AgentId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (transactionID == UUID.Zero)
|
||||||
|
{
|
||||||
|
ScenePresence presence;
|
||||||
|
if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||||
|
{
|
||||||
|
byte[] data = null;
|
||||||
|
|
||||||
|
if (invType == (sbyte)InventoryType.Landmark && presence != null)
|
||||||
|
{
|
||||||
|
string suffix = string.Empty, prefix = string.Empty;
|
||||||
|
string strdata = GenerateLandmark(presence, out prefix, out suffix);
|
||||||
|
data = Encoding.ASCII.GetBytes(strdata);
|
||||||
|
name = prefix + name;
|
||||||
|
description += suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
|
||||||
|
m_Scene.AssetService.Store(asset);
|
||||||
|
|
||||||
|
m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat(
|
||||||
|
"ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
|
||||||
|
remoteClient.AgentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>();
|
||||||
|
if (agentTransactions != null)
|
||||||
|
{
|
||||||
|
agentTransactions.HandleItemCreationFromTransaction(
|
||||||
|
remoteClient, transactionID, folderID, callbackID, description,
|
||||||
|
name, invType, assetType, wearableType, nextOwnerMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
|
||||||
|
{
|
||||||
|
prefix = string.Empty;
|
||||||
|
suffix = string.Empty;
|
||||||
|
Vector3 pos = presence.AbsolutePosition;
|
||||||
|
return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
|
||||||
|
presence.Scene.RegionInfo.RegionID,
|
||||||
|
pos.X, pos.Y, pos.Z,
|
||||||
|
presence.RegionHandle);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Capability originating call to update the asset of an item in an agent's inventory
|
/// Capability originating call to update the asset of an item in an agent's inventory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -30,11 +30,13 @@ using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
|
||||||
using OpenSim.Region.Framework;
|
using OpenSim.Region.Framework;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Services.Connectors.Hypergrid;
|
||||||
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -47,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
public UUID Id;
|
public UUID Id;
|
||||||
public string FirstName;
|
public string FirstName;
|
||||||
public string LastName;
|
public string LastName;
|
||||||
public string ProfileURL;
|
public string HomeURL;
|
||||||
|
public Dictionary<string, object> ServerURLs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserManagementModule : ISharedRegionModule, IUserManagement
|
public class UserManagementModule : ISharedRegionModule, IUserManagement
|
||||||
|
@ -78,6 +81,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
MainConsole.Instance.Commands.AddCommand("grid", true,
|
||||||
|
"show names",
|
||||||
|
"show names",
|
||||||
|
"Show the bindings between user UUIDs and user names",
|
||||||
|
String.Empty,
|
||||||
|
HandleShowUsers);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsSharedModule
|
public bool IsSharedModule
|
||||||
|
@ -101,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
scene.RegisterModuleInterface<IUserManagement>(this);
|
scene.RegisterModuleInterface<IUserManagement>(this);
|
||||||
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
|
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
|
||||||
|
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -109,18 +121,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
m_Scenes.Remove(scene);
|
m_Scenes.Remove(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
public void RegionLoaded(Scene s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
{
|
{
|
||||||
foreach (Scene s in m_Scenes)
|
|
||||||
{
|
|
||||||
// let's sniff all the user names referenced by objects in the scene
|
|
||||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
|
|
||||||
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
@ -134,6 +140,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
#region Event Handlers
|
#region Event Handlers
|
||||||
|
|
||||||
|
void EventManager_OnPrimsLoaded(Scene s)
|
||||||
|
{
|
||||||
|
// let's sniff all the user names referenced by objects in the scene
|
||||||
|
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
|
||||||
|
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void EventManager_OnNewClient(IClientAPI client)
|
void EventManager_OnNewClient(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
|
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
|
||||||
|
@ -150,6 +164,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
string[] names = GetUserNames(uuid);
|
string[] names = GetUserNames(uuid);
|
||||||
if (names.Length == 2)
|
if (names.Length == 2)
|
||||||
{
|
{
|
||||||
|
//m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]);
|
||||||
remote_client.SendNameReply(uuid, names[0], names[1]);
|
remote_client.SendNameReply(uuid, names[0], names[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +225,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public string GetUserName(UUID uuid)
|
public string GetUserName(UUID uuid)
|
||||||
{
|
{
|
||||||
|
//m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
|
||||||
string[] names = GetUserNames(uuid);
|
string[] names = GetUserNames(uuid);
|
||||||
if (names.Length == 2)
|
if (names.Length == 2)
|
||||||
{
|
{
|
||||||
|
@ -222,6 +238,60 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
return "(hippos)";
|
return "(hippos)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetUserHomeURL(UUID userID)
|
||||||
|
{
|
||||||
|
if (m_UserCache.ContainsKey(userID))
|
||||||
|
return m_UserCache[userID].HomeURL;
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetUserServerURL(UUID userID, string serverType)
|
||||||
|
{
|
||||||
|
if (m_UserCache.ContainsKey(userID))
|
||||||
|
{
|
||||||
|
UserData userdata = m_UserCache[userID];
|
||||||
|
if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
|
||||||
|
return userdata.ServerURLs[serverType].ToString();
|
||||||
|
|
||||||
|
if (userdata.HomeURL != string.Empty)
|
||||||
|
{
|
||||||
|
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
|
||||||
|
userdata.ServerURLs = uConn.GetServerURLs(userID);
|
||||||
|
if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
|
||||||
|
return userdata.ServerURLs[serverType].ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetUserUUI(UUID userID)
|
||||||
|
{
|
||||||
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
|
||||||
|
if (account != null)
|
||||||
|
return userID.ToString();
|
||||||
|
|
||||||
|
if (m_UserCache.ContainsKey(userID))
|
||||||
|
{
|
||||||
|
UserData ud = m_UserCache[userID];
|
||||||
|
string homeURL = ud.HomeURL;
|
||||||
|
string first = ud.FirstName, last = ud.LastName;
|
||||||
|
if (ud.LastName.StartsWith("@"))
|
||||||
|
{
|
||||||
|
string[] parts = ud.FirstName.Split('.');
|
||||||
|
if (parts.Length >= 2)
|
||||||
|
{
|
||||||
|
first = parts[0];
|
||||||
|
last = parts[1];
|
||||||
|
}
|
||||||
|
return userID + ";" + homeURL + ";" + first + " " + last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return userID.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
public void AddUser(UUID id, string creatorData)
|
public void AddUser(UUID id, string creatorData)
|
||||||
{
|
{
|
||||||
if (m_UserCache.ContainsKey(id))
|
if (m_UserCache.ContainsKey(id))
|
||||||
|
@ -247,13 +317,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
string[] parts = creatorData.Split(';');
|
string[] parts = creatorData.Split(';');
|
||||||
if (parts.Length >= 1)
|
if (parts.Length >= 1)
|
||||||
{
|
{
|
||||||
user.ProfileURL = parts[0];
|
user.HomeURL = parts[0];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Uri uri = new Uri(parts[0]);
|
Uri uri = new Uri(parts[0]);
|
||||||
user.LastName = "@" + uri.Authority;
|
user.LastName = "@" + uri.Authority;
|
||||||
}
|
}
|
||||||
catch
|
catch (UriFormatException)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
|
m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
|
||||||
user.LastName = "@unknown";
|
user.LastName = "@unknown";
|
||||||
|
@ -272,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
lock (m_UserCache)
|
lock (m_UserCache)
|
||||||
m_UserCache[id] = user;
|
m_UserCache[id] = user;
|
||||||
|
|
||||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
|
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddUser(UUID uuid, string first, string last, string profileURL)
|
public void AddUser(UUID uuid, string first, string last, string profileURL)
|
||||||
|
@ -311,5 +381,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
//}
|
//}
|
||||||
|
|
||||||
#endregion IUserManagement
|
#endregion IUserManagement
|
||||||
|
|
||||||
|
private void HandleShowUsers(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
if (m_UserCache.Count == 0)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output("No users not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainConsole.Instance.Output("UUID User Name");
|
||||||
|
MainConsole.Instance.Output("-----------------------------------------------------------------------------");
|
||||||
|
foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output(String.Format("{0} {1} {2}",
|
||||||
|
kvp.Key, kvp.Value.FirstName, kvp.Value.LastName));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -40,7 +41,10 @@ namespace OpenSim.Region.CoreModules.Hypergrid
|
||||||
{
|
{
|
||||||
public class HGWorldMapModule : WorldMapModule
|
public class HGWorldMapModule : WorldMapModule
|
||||||
{
|
{
|
||||||
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
// Remember the map area that each client has been exposed to in this region
|
||||||
|
private Dictionary<UUID, List<MapBlockData>> m_SeenMapBlocks = new Dictionary<UUID, List<MapBlockData>>();
|
||||||
|
|
||||||
#region INonSharedRegionModule Members
|
#region INonSharedRegionModule Members
|
||||||
|
|
||||||
|
@ -51,6 +55,13 @@ namespace OpenSim.Region.CoreModules.Hypergrid
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
base.AddRegion(scene);
|
||||||
|
|
||||||
|
scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed);
|
||||||
|
}
|
||||||
|
|
||||||
public override string Name
|
public override string Name
|
||||||
{
|
{
|
||||||
get { return "HGWorldMap"; }
|
get { return "HGWorldMap"; }
|
||||||
|
@ -58,47 +69,70 @@ namespace OpenSim.Region.CoreModules.Hypergrid
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
protected override void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
|
void EventManager_OnClientClosed(UUID clientID, Scene scene)
|
||||||
{
|
{
|
||||||
List<MapBlockData> mapBlocks = new List<MapBlockData>();
|
ScenePresence sp = scene.GetScenePresence(clientID);
|
||||||
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
if (sp != null)
|
||||||
minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize,
|
|
||||||
minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize);
|
|
||||||
|
|
||||||
foreach (GridRegion r in regions)
|
|
||||||
{
|
{
|
||||||
MapBlockData block = new MapBlockData();
|
if (m_SeenMapBlocks.ContainsKey(clientID))
|
||||||
MapBlockFromGridRegion(block, r);
|
|
||||||
mapBlocks.Add(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Different from super
|
|
||||||
FillInMap(mapBlocks, minX, minY, maxX, maxY);
|
|
||||||
//
|
|
||||||
|
|
||||||
remoteClient.SendMapBlock(mapBlocks, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void FillInMap(List<MapBlockData> mapBlocks, int minX, int minY, int maxX, int maxY)
|
|
||||||
{
|
|
||||||
for (int x = minX; x <= maxX; x++)
|
|
||||||
{
|
|
||||||
for (int y = minY; y <= maxY; y++)
|
|
||||||
{
|
{
|
||||||
MapBlockData mblock = mapBlocks.Find(delegate(MapBlockData mb) { return ((mb.X == x) && (mb.Y == y)); });
|
List<MapBlockData> mapBlocks = m_SeenMapBlocks[clientID];
|
||||||
if (mblock == null)
|
foreach (MapBlockData b in mapBlocks)
|
||||||
{
|
{
|
||||||
mblock = new MapBlockData();
|
b.Name = string.Empty;
|
||||||
mblock.X = (ushort)x;
|
b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's
|
||||||
mblock.Y = (ushort)y;
|
|
||||||
mblock.Name = "";
|
|
||||||
mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's
|
|
||||||
mblock.MapImageId = UUID.Zero;
|
|
||||||
mapBlocks.Add(mblock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[HG MAP]: Reseting {0} blocks", mapBlocks.Count);
|
||||||
|
sp.ControllingClient.SendMapBlock(mapBlocks, 0);
|
||||||
|
m_SeenMapBlocks.Remove(clientID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
|
||||||
|
{
|
||||||
|
List<MapBlockData> mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag);
|
||||||
|
lock (m_SeenMapBlocks)
|
||||||
|
{
|
||||||
|
if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId))
|
||||||
|
{
|
||||||
|
m_SeenMapBlocks.Add(remoteClient.AgentId, mapBlocks);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<MapBlockData> seen = m_SeenMapBlocks[remoteClient.AgentId];
|
||||||
|
List<MapBlockData> newBlocks = new List<MapBlockData>();
|
||||||
|
foreach (MapBlockData b in mapBlocks)
|
||||||
|
if (seen.Find(delegate(MapBlockData bdata) { return bdata.X == b.X && bdata.Y == b.Y; }) == null)
|
||||||
|
newBlocks.Add(b);
|
||||||
|
seen.AddRange(newBlocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MapArea
|
||||||
|
{
|
||||||
|
public int minX;
|
||||||
|
public int minY;
|
||||||
|
public int maxX;
|
||||||
|
public int maxY;
|
||||||
|
|
||||||
|
public MapArea(int mix, int miy, int max, int may)
|
||||||
|
{
|
||||||
|
minX = mix;
|
||||||
|
minY = miy;
|
||||||
|
maxX = max;
|
||||||
|
maxY = may;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Print()
|
||||||
|
{
|
||||||
|
Console.WriteLine(String.Format(" --> Area is minX={0} minY={1} minY={2} maxY={3}", minX, minY, maxY, maxY));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
<RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
|
<RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
|
||||||
<RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
|
<RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
|
||||||
<RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" />
|
<RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" />
|
||||||
|
<RegionModule id="HGFriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.HGFriendsModule" />
|
||||||
<RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" />
|
<RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" />
|
||||||
<RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
|
<RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
|
||||||
<RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" />
|
<RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" />
|
||||||
|
|
|
@ -113,8 +113,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
|
||||||
ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
|
ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
|
||||||
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
|
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
|
||||||
|
|
||||||
new UserAgentServerConnector(m_Config, MainServer.Instance);
|
IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
|
||||||
|
new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
|
||||||
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
|
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
|
||||||
|
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
|
||||||
}
|
}
|
||||||
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
|
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using log4net;
|
||||||
|
using Mono.Addins;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
using OpenSim.Server.Handlers.MapImage;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class MapImageServiceInConnectorModule : ISharedRegionModule
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private static bool m_Enabled = false;
|
||||||
|
|
||||||
|
private IConfigSource m_Config;
|
||||||
|
bool m_Registered = false;
|
||||||
|
|
||||||
|
#region IRegionModule interface
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource config)
|
||||||
|
{
|
||||||
|
m_Config = config;
|
||||||
|
IConfig moduleConfig = config.Configs["Modules"];
|
||||||
|
if (moduleConfig != null)
|
||||||
|
{
|
||||||
|
m_Enabled = moduleConfig.GetBoolean("MapImageServiceInConnector", false);
|
||||||
|
if (m_Enabled)
|
||||||
|
{
|
||||||
|
m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled");
|
||||||
|
new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "MapImageServiceIn"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using log4net;
|
||||||
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
|
{
|
||||||
|
public class RegionInfoCache
|
||||||
|
{
|
||||||
|
private const double CACHE_EXPIRATION_SECONDS = 300.0; // 5 minutes
|
||||||
|
|
||||||
|
// private static readonly ILog m_log =
|
||||||
|
// LogManager.GetLogger(
|
||||||
|
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
internal struct ScopedRegionUUID
|
||||||
|
{
|
||||||
|
public UUID m_scopeID;
|
||||||
|
public UUID m_regionID;
|
||||||
|
public ScopedRegionUUID(UUID scopeID, UUID regionID)
|
||||||
|
{
|
||||||
|
m_scopeID = scopeID;
|
||||||
|
m_regionID = regionID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal struct ScopedRegionName
|
||||||
|
{
|
||||||
|
public UUID m_scopeID;
|
||||||
|
public string m_name;
|
||||||
|
public ScopedRegionName(UUID scopeID, string name)
|
||||||
|
{
|
||||||
|
m_scopeID = scopeID;
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExpiringCache<ScopedRegionUUID, GridRegion> m_UUIDCache;
|
||||||
|
private ExpiringCache<ScopedRegionName, ScopedRegionUUID> m_NameCache;
|
||||||
|
|
||||||
|
public RegionInfoCache()
|
||||||
|
{
|
||||||
|
m_UUIDCache = new ExpiringCache<ScopedRegionUUID, GridRegion>();
|
||||||
|
m_NameCache = new ExpiringCache<ScopedRegionName, ScopedRegionUUID>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cache(GridRegion rinfo)
|
||||||
|
{
|
||||||
|
if (rinfo != null)
|
||||||
|
this.Cache(rinfo.ScopeID,rinfo.RegionID,rinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cache(UUID scopeID, UUID regionID, GridRegion rinfo)
|
||||||
|
{
|
||||||
|
// for now, do not cache negative results; this is because
|
||||||
|
// we need to figure out how to handle regions coming online
|
||||||
|
// in a timely way
|
||||||
|
if (rinfo == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID);
|
||||||
|
|
||||||
|
// Cache even null accounts
|
||||||
|
m_UUIDCache.AddOrUpdate(id, rinfo, CACHE_EXPIRATION_SECONDS);
|
||||||
|
if (rinfo != null)
|
||||||
|
{
|
||||||
|
ScopedRegionName name = new ScopedRegionName(scopeID,rinfo.RegionName);
|
||||||
|
m_NameCache.AddOrUpdate(name, id, CACHE_EXPIRATION_SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache)
|
||||||
|
{
|
||||||
|
inCache = false;
|
||||||
|
|
||||||
|
GridRegion rinfo = null;
|
||||||
|
ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID);
|
||||||
|
if (m_UUIDCache.TryGetValue(id, out rinfo))
|
||||||
|
{
|
||||||
|
inCache = true;
|
||||||
|
return rinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridRegion Get(UUID scopeID, string name, out bool inCache)
|
||||||
|
{
|
||||||
|
inCache = false;
|
||||||
|
|
||||||
|
ScopedRegionName sname = new ScopedRegionName(scopeID,name);
|
||||||
|
|
||||||
|
ScopedRegionUUID id;
|
||||||
|
if (m_NameCache.TryGetValue(sname, out id))
|
||||||
|
{
|
||||||
|
GridRegion rinfo = null;
|
||||||
|
if (m_UUIDCache.TryGetValue(id, out rinfo))
|
||||||
|
{
|
||||||
|
inCache = true;
|
||||||
|
return rinfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,6 +53,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
private IGridService m_LocalGridService;
|
private IGridService m_LocalGridService;
|
||||||
private IGridService m_RemoteGridService;
|
private IGridService m_RemoteGridService;
|
||||||
|
|
||||||
|
private RegionInfoCache m_RegionInfoCache = new RegionInfoCache();
|
||||||
|
|
||||||
public RemoteGridServicesConnector()
|
public RemoteGridServicesConnector()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -169,10 +171,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
|
|
||||||
public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
|
public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
|
||||||
{
|
{
|
||||||
GridRegion rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID);
|
bool inCache = false;
|
||||||
|
GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache);
|
||||||
|
if (inCache)
|
||||||
|
return rinfo;
|
||||||
|
|
||||||
|
rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID);
|
||||||
if (rinfo == null)
|
if (rinfo == null)
|
||||||
rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID);
|
rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID);
|
||||||
|
|
||||||
|
m_RegionInfoCache.Cache(scopeID,regionID,rinfo);
|
||||||
return rinfo;
|
return rinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,10 +195,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
|
|
||||||
public GridRegion GetRegionByName(UUID scopeID, string regionName)
|
public GridRegion GetRegionByName(UUID scopeID, string regionName)
|
||||||
{
|
{
|
||||||
GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName);
|
bool inCache = false;
|
||||||
|
GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionName, out inCache);
|
||||||
|
if (inCache)
|
||||||
|
return rinfo;
|
||||||
|
|
||||||
|
rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName);
|
||||||
if (rinfo == null)
|
if (rinfo == null)
|
||||||
rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName);
|
rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName);
|
||||||
|
|
||||||
|
// can't cache negative results for name lookups
|
||||||
|
m_RegionInfoCache.Cache(rinfo);
|
||||||
return rinfo;
|
return rinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,8 +219,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionsByName {0} found {1} regions", name, grinfo.Count);
|
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionsByName {0} found {1} regions", name, grinfo.Count);
|
||||||
foreach (GridRegion r in grinfo)
|
foreach (GridRegion r in grinfo)
|
||||||
|
{
|
||||||
|
m_RegionInfoCache.Cache(r);
|
||||||
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
||||||
rinfo.Add(r);
|
rinfo.Add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rinfo;
|
return rinfo;
|
||||||
|
@ -221,8 +239,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionRange {0} found {1} regions", name, grinfo.Count);
|
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionRange {0} found {1} regions", name, grinfo.Count);
|
||||||
foreach (GridRegion r in grinfo)
|
foreach (GridRegion r in grinfo)
|
||||||
|
{
|
||||||
|
m_RegionInfoCache.Cache(r);
|
||||||
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
||||||
rinfo.Add(r);
|
rinfo.Add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rinfo;
|
return rinfo;
|
||||||
|
@ -238,8 +259,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultRegions {0} found {1} regions", name, grinfo.Count);
|
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultRegions {0} found {1} regions", name, grinfo.Count);
|
||||||
foreach (GridRegion r in grinfo)
|
foreach (GridRegion r in grinfo)
|
||||||
|
{
|
||||||
|
m_RegionInfoCache.Cache(r);
|
||||||
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
||||||
rinfo.Add(r);
|
rinfo.Add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rinfo;
|
return rinfo;
|
||||||
|
@ -255,8 +279,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetFallbackRegions {0} found {1} regions", name, grinfo.Count);
|
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetFallbackRegions {0} found {1} regions", name, grinfo.Count);
|
||||||
foreach (GridRegion r in grinfo)
|
foreach (GridRegion r in grinfo)
|
||||||
|
{
|
||||||
|
m_RegionInfoCache.Cache(r);
|
||||||
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
||||||
rinfo.Add(r);
|
rinfo.Add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rinfo;
|
return rinfo;
|
||||||
|
@ -272,8 +299,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetHyperlinks {0} found {1} regions", name, grinfo.Count);
|
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetHyperlinks {0} found {1} regions", name, grinfo.Count);
|
||||||
foreach (GridRegion r in grinfo)
|
foreach (GridRegion r in grinfo)
|
||||||
|
{
|
||||||
|
m_RegionInfoCache.Cache(r);
|
||||||
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
||||||
rinfo.Add(r);
|
rinfo.Add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rinfo;
|
return rinfo;
|
||||||
|
|
|
@ -58,6 +58,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
|
|
||||||
private List<Scene> m_Scenes = new List<Scene>();
|
private List<Scene> m_Scenes = new List<Scene>();
|
||||||
|
|
||||||
|
protected IUserManagement m_UserManagement;
|
||||||
|
protected IUserManagement UserManagementModule
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (m_UserManagement == null)
|
||||||
|
m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||||
|
return m_UserManagement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
{
|
{
|
||||||
get { return null; }
|
get { return null; }
|
||||||
|
@ -207,6 +218,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sp == null)
|
||||||
|
{
|
||||||
|
inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI");
|
||||||
|
if (inventoryURL != null && inventoryURL != string.Empty)
|
||||||
|
{
|
||||||
|
inventoryURL = inventoryURL.Trim(new char[] { '/' });
|
||||||
|
m_InventoryURLs.Add(userID, inventoryURL);
|
||||||
|
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,242 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Net;
|
||||||
|
using System.IO;
|
||||||
|
using System.Timers;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
|
||||||
|
using log4net;
|
||||||
|
using Mono.Addins;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// </remarks>
|
||||||
|
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class MapImageServiceModule : ISharedRegionModule
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private bool m_enabled = false;
|
||||||
|
private IMapImageService m_MapService;
|
||||||
|
|
||||||
|
private string m_serverUrl = String.Empty;
|
||||||
|
private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
|
||||||
|
|
||||||
|
private int m_refreshtime = 0;
|
||||||
|
private int m_lastrefresh = 0;
|
||||||
|
private System.Timers.Timer m_refreshTimer = new System.Timers.Timer();
|
||||||
|
|
||||||
|
#region ISharedRegionModule
|
||||||
|
|
||||||
|
public Type ReplaceableInterface { get { return null; } }
|
||||||
|
public string Name { get { return "MapImageServiceModule"; } }
|
||||||
|
public void RegionLoaded(Scene scene) { }
|
||||||
|
public void Close() { }
|
||||||
|
public void PostInitialise() { }
|
||||||
|
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
public void Initialise(IConfigSource source)
|
||||||
|
{
|
||||||
|
IConfig moduleConfig = source.Configs["Modules"];
|
||||||
|
if (moduleConfig != null)
|
||||||
|
{
|
||||||
|
string name = moduleConfig.GetString("MapImageService", "");
|
||||||
|
if (name != Name)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IConfig config = source.Configs["MapImageService"];
|
||||||
|
if (config == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime"));
|
||||||
|
if (refreshminutes <= 0)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_refreshtime = refreshminutes * 60 * 1000; // convert from minutes to ms
|
||||||
|
|
||||||
|
string service = config.GetString("LocalServiceModule", string.Empty);
|
||||||
|
if (service == string.Empty)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No service dll given in config. Unable to proceed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object[] args = new Object[] { source };
|
||||||
|
m_MapService = ServerUtils.LoadPlugin<IMapImageService>(service, args);
|
||||||
|
if (m_MapService == null)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Unable to load LocalServiceModule from {0}. MapService module disabled. Please fix the configuration.", service);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_refreshTimer.Enabled = true;
|
||||||
|
m_refreshTimer.AutoReset = true;
|
||||||
|
m_refreshTimer.Interval = m_refreshtime;
|
||||||
|
m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
|
||||||
|
|
||||||
|
m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}",
|
||||||
|
refreshminutes, service);
|
||||||
|
|
||||||
|
m_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
public void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (! m_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Every shared region module has to maintain an indepedent list of
|
||||||
|
// currently running regions
|
||||||
|
lock (m_scenes)
|
||||||
|
m_scenes[scene.RegionInfo.RegionID] = scene;
|
||||||
|
|
||||||
|
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
public void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (! m_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (m_scenes)
|
||||||
|
m_scenes.Remove(scene.RegionInfo.RegionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion ISharedRegionModule
|
||||||
|
|
||||||
|
void EventManager_OnPrimsLoaded(Scene s)
|
||||||
|
{
|
||||||
|
UploadMapTile(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
private void HandleMaptileRefresh(object sender, EventArgs ea)
|
||||||
|
{
|
||||||
|
// this approach is a bit convoluted becase we want to wait for the
|
||||||
|
// first upload to happen on startup but after all the objects are
|
||||||
|
// loaded and initialized
|
||||||
|
if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: map refresh!");
|
||||||
|
lock (m_scenes)
|
||||||
|
{
|
||||||
|
foreach (IScene scene in m_scenes.Values)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UploadMapTile(scene);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: something bad happened {0}", ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastrefresh = Util.EnvironmentTickCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
///
|
||||||
|
///</summary>
|
||||||
|
private void UploadMapTile(IScene scene)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: upload maptile for {0}", scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
// Create a JPG map tile and upload it to the AddMapTile API
|
||||||
|
byte[] jpgData = Utils.EmptyBytes;
|
||||||
|
IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>();
|
||||||
|
if (tileGenerator == null)
|
||||||
|
{
|
||||||
|
m_log.Warn("[MAP IMAGE SERVICE MODULE]: Cannot upload PNG map tile without an ImageGenerator");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (Image mapTile = tileGenerator.CreateMapTile())
|
||||||
|
{
|
||||||
|
using (MemoryStream stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
mapTile.Save(stream, ImageFormat.Jpeg);
|
||||||
|
jpgData = stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jpgData == Utils.EmptyBytes)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Tile image generation failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string reason = string.Empty;
|
||||||
|
if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}",
|
||||||
|
scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -506,6 +506,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
currentRegionSettings.Elevation2SE = loadedRegionSettings.Elevation2SE;
|
currentRegionSettings.Elevation2SE = loadedRegionSettings.Elevation2SE;
|
||||||
currentRegionSettings.Elevation2SW = loadedRegionSettings.Elevation2SW;
|
currentRegionSettings.Elevation2SW = loadedRegionSettings.Elevation2SW;
|
||||||
currentRegionSettings.FixedSun = loadedRegionSettings.FixedSun;
|
currentRegionSettings.FixedSun = loadedRegionSettings.FixedSun;
|
||||||
|
currentRegionSettings.SunPosition = loadedRegionSettings.SunPosition;
|
||||||
currentRegionSettings.ObjectBonus = loadedRegionSettings.ObjectBonus;
|
currentRegionSettings.ObjectBonus = loadedRegionSettings.ObjectBonus;
|
||||||
currentRegionSettings.RestrictPushing = loadedRegionSettings.RestrictPushing;
|
currentRegionSettings.RestrictPushing = loadedRegionSettings.RestrictPushing;
|
||||||
currentRegionSettings.TerrainLowerLimit = loadedRegionSettings.TerrainLowerLimit;
|
currentRegionSettings.TerrainLowerLimit = loadedRegionSettings.TerrainLowerLimit;
|
||||||
|
@ -518,6 +519,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight;
|
currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight;
|
||||||
|
|
||||||
currentRegionSettings.Save();
|
currentRegionSettings.Save();
|
||||||
|
|
||||||
|
m_scene.TriggerEstateSunUpdate();
|
||||||
|
|
||||||
IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
|
IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
|
||||||
|
|
||||||
|
|
|
@ -198,11 +198,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT);
|
"[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT);
|
||||||
|
|
||||||
m_log.Error("[ARCHIVER]: OAR save aborted. PLEASE DO NOT USE THIS OAR, IT WILL BE INCOMPLETE.");
|
m_log.Error("[ARCHIVER]: Archive save aborted. PLEASE DO NOT USE THIS ARCHIVE, IT WILL BE INCOMPLETE.");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}", e);
|
m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}{1}", e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -230,6 +230,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
/// <param name="asset"></param>
|
/// <param name="asset"></param>
|
||||||
public void AssetRequestCallback(string id, object sender, AssetBase asset)
|
public void AssetRequestCallback(string id, object sender, AssetBase asset)
|
||||||
{
|
{
|
||||||
|
Culture.SetCurrentCulture();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (this)
|
lock (this)
|
||||||
|
@ -289,6 +291,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void PerformAssetsRequestCallback(object o)
|
protected void PerformAssetsRequestCallback(object o)
|
||||||
{
|
{
|
||||||
|
Culture.SetCurrentCulture();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);
|
m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);
|
||||||
|
|
|
@ -440,6 +440,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
rs.Elevation2SE = 9.2;
|
rs.Elevation2SE = 9.2;
|
||||||
rs.Elevation2SW = 2.1;
|
rs.Elevation2SW = 2.1;
|
||||||
rs.FixedSun = true;
|
rs.FixedSun = true;
|
||||||
|
rs.SunPosition = 12.0;
|
||||||
rs.ObjectBonus = 1.4;
|
rs.ObjectBonus = 1.4;
|
||||||
rs.RestrictPushing = true;
|
rs.RestrictPushing = true;
|
||||||
rs.TerrainLowerLimit = 0.4;
|
rs.TerrainLowerLimit = 0.4;
|
||||||
|
@ -485,6 +486,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2));
|
Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2));
|
||||||
Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1));
|
Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1));
|
||||||
Assert.That(loadedRs.FixedSun, Is.True);
|
Assert.That(loadedRs.FixedSun, Is.True);
|
||||||
|
Assert.AreEqual(12.0, loadedRs.SunPosition);
|
||||||
Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4));
|
Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4));
|
||||||
Assert.That(loadedRs.RestrictPushing, Is.True);
|
Assert.That(loadedRs.RestrictPushing, Is.True);
|
||||||
Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4));
|
Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4));
|
||||||
|
|
|
@ -548,18 +548,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
|
|
||||||
// libomv will moan about PrimFlags.ObjectYouOfficer being
|
// libomv will moan about PrimFlags.ObjectYouOfficer being
|
||||||
// deprecated
|
// deprecated
|
||||||
#pragma warning disable 0612
|
#pragma warning disable 0612
|
||||||
objflags &= (uint)
|
objflags &= (uint)
|
||||||
~(PrimFlags.ObjectCopy | // Tells client you can copy the object
|
~(PrimFlags.ObjectCopy | // Tells client you can copy the object
|
||||||
PrimFlags.ObjectModify | // tells client you can modify the object
|
PrimFlags.ObjectModify | // tells client you can modify the object
|
||||||
PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
|
PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
|
||||||
PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
|
PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
|
||||||
PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
|
PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
|
||||||
PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
|
PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
|
||||||
PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
|
PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
|
||||||
PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
|
PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
|
||||||
);
|
);
|
||||||
#pragma warning restore 0612
|
#pragma warning restore 0612
|
||||||
|
|
||||||
// Creating the three ObjectFlags options for this method to choose from.
|
// Creating the three ObjectFlags options for this method to choose from.
|
||||||
// Customize the OwnerMask
|
// Customize the OwnerMask
|
||||||
|
@ -576,22 +576,27 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
|
|
||||||
if (m_bypassPermissions)
|
if (m_bypassPermissions)
|
||||||
return objectOwnerMask;
|
return objectOwnerMask;
|
||||||
|
|
||||||
// Object owners should be able to edit their own content
|
// Object owners should be able to edit their own content
|
||||||
if (user == objectOwner)
|
if (user == objectOwner)
|
||||||
return objectOwnerMask;
|
return objectOwnerMask;
|
||||||
|
|
||||||
if (IsFriendWithPerms(user, objectOwner))
|
|
||||||
return objectOwnerMask;
|
|
||||||
|
|
||||||
|
if (IsFriendWithPerms(user, objectOwner))
|
||||||
|
{
|
||||||
|
return objectOwnerMask;
|
||||||
|
}
|
||||||
// Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
|
// Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
|
||||||
if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
|
if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
|
||||||
|
{
|
||||||
return objectOwnerMask;
|
return objectOwnerMask;
|
||||||
|
}
|
||||||
|
|
||||||
// Admin should be able to edit anything in the sim (including admin objects)
|
// Admin should be able to edit anything in the sim (including admin objects)
|
||||||
if (IsAdministrator(user))
|
if (IsAdministrator(user))
|
||||||
|
{
|
||||||
return objectOwnerMask;
|
return objectOwnerMask;
|
||||||
|
}
|
||||||
|
|
||||||
// Users should be able to edit what is over their land.
|
// Users should be able to edit what is over their land.
|
||||||
Vector3 taskPos = task.AbsolutePosition;
|
Vector3 taskPos = task.AbsolutePosition;
|
||||||
ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
|
ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
|
||||||
|
@ -599,13 +604,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
{
|
{
|
||||||
// Admin objects should not be editable by the above
|
// Admin objects should not be editable by the above
|
||||||
if (!IsAdministrator(objectOwner))
|
if (!IsAdministrator(objectOwner))
|
||||||
|
{
|
||||||
return objectOwnerMask;
|
return objectOwnerMask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group permissions
|
// Group permissions
|
||||||
if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
|
if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
|
||||||
return objectGroupMask | objectEveryoneMask;
|
return objectGroupMask | objectEveryoneMask;
|
||||||
|
|
||||||
return objectEveryoneMask;
|
return objectEveryoneMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
//
|
//
|
||||||
// Nobody but the object owner can set permissions on an object
|
// Nobody but the object owner can set permissions on an object
|
||||||
//
|
//
|
||||||
|
|
||||||
if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
|
if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -704,6 +710,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
// Return immediately, so that the administrator can shares group objects
|
// Return immediately, so that the administrator can shares group objects
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Friends with benefits should be able to edit the objects too
|
||||||
|
if (IsFriendWithPerms(currentUser, objectOwner))
|
||||||
|
// Return immediately, so that the administrator can share objects with friends
|
||||||
|
return true;
|
||||||
|
|
||||||
// Users should be able to edit what is over their land.
|
// Users should be able to edit what is over their land.
|
||||||
ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);
|
ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule
|
public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule
|
||||||
{
|
{
|
||||||
private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3");
|
private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3");
|
||||||
private static readonly Color4 WATER_COLOR = new Color4(29, 71, 95, 216);
|
private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216);
|
||||||
|
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
private IRendering m_primMesher;
|
private IRendering m_primMesher;
|
||||||
private IConfigSource m_config;
|
private IConfigSource m_config;
|
||||||
private Dictionary<UUID, Color4> m_colors = new Dictionary<UUID, Color4>();
|
private Dictionary<UUID, Color4> m_colors = new Dictionary<UUID, Color4>();
|
||||||
private bool m_useAntiAliasing = true; // TODO: Make this a config option
|
private bool m_useAntiAliasing = false; // TODO: Make this a config option
|
||||||
private bool m_Enabled = false;
|
private bool m_Enabled = false;
|
||||||
|
|
||||||
#region IRegionModule Members
|
#region IRegionModule Members
|
||||||
|
@ -192,8 +192,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
#endregion Camera
|
#endregion Camera
|
||||||
|
|
||||||
renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(0.2f, 0.2f, 1f), 0xffffff, 320, 80));
|
renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40));
|
||||||
renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 100, 40));
|
renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40));
|
||||||
|
|
||||||
CreateWater(renderer);
|
CreateWater(renderer);
|
||||||
CreateTerrain(renderer, textureTerrain);
|
CreateTerrain(renderer, textureTerrain);
|
||||||
|
@ -237,6 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f);
|
renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f);
|
||||||
|
|
||||||
renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR));
|
renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR));
|
||||||
|
renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif
|
||||||
renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f));
|
renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f));
|
||||||
renderer.SetObjectMaterial("Water", "WaterColor");
|
renderer.SetObjectMaterial("Water", "WaterColor");
|
||||||
}
|
}
|
||||||
|
@ -322,6 +323,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
warp_Material material = new warp_Material(texture);
|
warp_Material material = new warp_Material(texture);
|
||||||
material.setReflectivity(50);
|
material.setReflectivity(50);
|
||||||
renderer.Scene.addMaterial("TerrainColor", material);
|
renderer.Scene.addMaterial("TerrainColor", material);
|
||||||
|
renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif
|
||||||
renderer.SetObjectMaterial("Terrain", "TerrainColor");
|
renderer.SetObjectMaterial("Terrain", "TerrainColor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,4 +655,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -208,52 +208,65 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
//m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
|
//m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
|
||||||
// path, param, agentID.ToString());
|
// path, param, agentID.ToString());
|
||||||
|
|
||||||
// this is here because CAPS map requests work even beyond the 10,000 limit.
|
// There is a major hack going on in this method. The viewer doesn't request
|
||||||
ScenePresence avatarPresence = null;
|
// map blocks (RequestMapBlocks) above 2048. That means that if we don't hack,
|
||||||
|
// grids above that cell don't have a map at all. So, here's the hack: we wait
|
||||||
|
// for this CAP request to come, and we inject the map blocks at this point.
|
||||||
|
// In a normal scenario, this request simply sends back the MapLayer (the blue color).
|
||||||
|
// In the hacked scenario, it also sends the map blocks via UDP.
|
||||||
|
//
|
||||||
|
// 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
|
||||||
|
// a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
|
||||||
|
|
||||||
m_scene.TryGetScenePresence(agentID, out avatarPresence);
|
if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
|
||||||
|
|
||||||
if (avatarPresence != null)
|
|
||||||
{
|
{
|
||||||
bool lookup = false;
|
ScenePresence avatarPresence = null;
|
||||||
|
|
||||||
lock (cachedMapBlocks)
|
m_scene.TryGetScenePresence(agentID, out avatarPresence);
|
||||||
|
|
||||||
|
if (avatarPresence != null)
|
||||||
{
|
{
|
||||||
if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
|
bool lookup = false;
|
||||||
{
|
|
||||||
List<MapBlockData> mapBlocks;
|
|
||||||
|
|
||||||
mapBlocks = cachedMapBlocks;
|
|
||||||
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lookup = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lookup)
|
|
||||||
{
|
|
||||||
List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
|
|
||||||
|
|
||||||
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
|
||||||
(int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
|
|
||||||
(int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
|
|
||||||
(int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
|
|
||||||
(int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
|
|
||||||
foreach (GridRegion r in regions)
|
|
||||||
{
|
|
||||||
MapBlockData block = new MapBlockData();
|
|
||||||
MapBlockFromGridRegion(block, r);
|
|
||||||
mapBlocks.Add(block);
|
|
||||||
}
|
|
||||||
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
|
|
||||||
|
|
||||||
lock (cachedMapBlocks)
|
lock (cachedMapBlocks)
|
||||||
cachedMapBlocks = mapBlocks;
|
{
|
||||||
|
if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
|
||||||
|
{
|
||||||
|
List<MapBlockData> mapBlocks;
|
||||||
|
|
||||||
cachedTime = Util.UnixTimeSinceEpoch();
|
mapBlocks = cachedMapBlocks;
|
||||||
|
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lookup = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lookup)
|
||||||
|
{
|
||||||
|
List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
|
||||||
|
|
||||||
|
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
||||||
|
(int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
|
||||||
|
(int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
|
||||||
|
(int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
|
||||||
|
(int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
|
||||||
|
foreach (GridRegion r in regions)
|
||||||
|
{
|
||||||
|
MapBlockData block = new MapBlockData();
|
||||||
|
MapBlockFromGridRegion(block, r);
|
||||||
|
mapBlocks.Add(block);
|
||||||
|
}
|
||||||
|
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
|
||||||
|
|
||||||
|
lock (cachedMapBlocks)
|
||||||
|
cachedMapBlocks = mapBlocks;
|
||||||
|
|
||||||
|
cachedTime = Util.UnixTimeSinceEpoch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
|
LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
|
||||||
mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
|
mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
|
||||||
return mapResponse.ToString();
|
return mapResponse.ToString();
|
||||||
|
@ -823,7 +836,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
block.Access = 254; // means 'simulator is offline'
|
block.Access = 254; // means 'simulator is offline'
|
||||||
response.Add(block);
|
response.Add(block);
|
||||||
}
|
}
|
||||||
remoteClient.SendMapBlock(response, 0);
|
if ((flag & 2) == 2) // V2 !!!
|
||||||
|
remoteClient.SendMapBlock(response, 2);
|
||||||
|
else
|
||||||
|
remoteClient.SendMapBlock(response, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -832,7 +848,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
|
protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
|
||||||
{
|
{
|
||||||
List<MapBlockData> mapBlocks = new List<MapBlockData>();
|
List<MapBlockData> mapBlocks = new List<MapBlockData>();
|
||||||
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
||||||
|
@ -846,7 +862,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
MapBlockFromGridRegion(block, r);
|
MapBlockFromGridRegion(block, r);
|
||||||
mapBlocks.Add(block);
|
mapBlocks.Add(block);
|
||||||
}
|
}
|
||||||
remoteClient.SendMapBlock(mapBlocks, 0);
|
if ((flag & 2) == 2) // V2 !!!
|
||||||
|
remoteClient.SendMapBlock(mapBlocks, 2);
|
||||||
|
else
|
||||||
|
remoteClient.SendMapBlock(mapBlocks, 0);
|
||||||
|
|
||||||
|
return mapBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r)
|
protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r)
|
||||||
|
|
|
@ -540,7 +540,7 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
|
public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,9 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
|
|
||||||
bool TeleportHome(UUID id, IClientAPI client);
|
bool TeleportHome(UUID id, IClientAPI client);
|
||||||
|
|
||||||
|
void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
|
||||||
|
Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq);
|
||||||
|
|
||||||
bool Cross(ScenePresence agent, bool isFlying);
|
bool Cross(ScenePresence agent, bool isFlying);
|
||||||
|
|
||||||
void AgentArrivedAtDestination(UUID agent);
|
void AgentArrivedAtDestination(UUID agent);
|
||||||
|
|
|
@ -34,6 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
public interface IFriendsModule
|
public interface IFriendsModule
|
||||||
{
|
{
|
||||||
uint GetFriendPerms(UUID PrincipalID, UUID FriendID);
|
uint GetFriendPerms(UUID PrincipalID, UUID FriendID);
|
||||||
void SendFriendsOnlineIfNeeded(IClientAPI client);
|
bool SendFriendsOnlineIfNeeded(IClientAPI client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
public interface IUserManagement
|
public interface IUserManagement
|
||||||
{
|
{
|
||||||
string GetUserName(UUID uuid);
|
string GetUserName(UUID uuid);
|
||||||
|
string GetUserHomeURL(UUID uuid);
|
||||||
|
string GetUserUUI(UUID uuid);
|
||||||
|
string GetUserServerURL(UUID uuid, string serverType);
|
||||||
void AddUser(UUID uuid, string userData);
|
void AddUser(UUID uuid, string userData);
|
||||||
void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
|
void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -393,6 +393,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public delegate void RegionUp(GridRegion region);
|
public delegate void RegionUp(GridRegion region);
|
||||||
public event RegionUp OnRegionUp;
|
public event RegionUp OnRegionUp;
|
||||||
|
|
||||||
|
public delegate void LoginsEnabled(string regionName);
|
||||||
|
public event LoginsEnabled OnLoginsEnabled;
|
||||||
|
|
||||||
|
public delegate void PrimsLoaded(Scene s);
|
||||||
|
public event PrimsLoaded OnPrimsLoaded;
|
||||||
|
|
||||||
public class MoneyTransferArgs : EventArgs
|
public class MoneyTransferArgs : EventArgs
|
||||||
{
|
{
|
||||||
public UUID sender;
|
public UUID sender;
|
||||||
|
@ -2242,5 +2248,47 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TriggerLoginsEnabled (string regionName)
|
||||||
|
{
|
||||||
|
LoginsEnabled handler = OnLoginsEnabled;
|
||||||
|
|
||||||
|
if ( handler != null)
|
||||||
|
{
|
||||||
|
foreach (LoginsEnabled d in handler.GetInvocationList())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d(regionName);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[EVENT MANAGER]: Delegate for LoginsEnabled failed - continuing {0} - {1}",
|
||||||
|
e.Message, e.StackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TriggerPrimsLoaded(Scene s)
|
||||||
|
{
|
||||||
|
PrimsLoaded handler = OnPrimsLoaded;
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
foreach (PrimsLoaded d in handler.GetInvocationList())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d(s);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[EVENT MANAGER]: Delegate for PrimsLoaded failed - continuing {0} - {1}",
|
||||||
|
e.Message, e.StackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -408,192 +408,198 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
InventoryItemBase item = new InventoryItemBase(itemId, senderId);
|
InventoryItemBase item = new InventoryItemBase(itemId, senderId);
|
||||||
item = InventoryService.GetItem(item);
|
item = InventoryService.GetItem(item);
|
||||||
|
|
||||||
if ((item != null) && (item.Owner == senderId))
|
if (item == null)
|
||||||
{
|
{
|
||||||
IUserManagement uman = RequestModuleInterface<IUserManagement>();
|
m_log.WarnFormat(
|
||||||
if (uman != null)
|
"[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient);
|
||||||
uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
|
||||||
|
|
||||||
if (!Permissions.BypassPermissions())
|
|
||||||
{
|
|
||||||
if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert a copy of the item into the recipient
|
|
||||||
InventoryItemBase itemCopy = new InventoryItemBase();
|
|
||||||
itemCopy.Owner = recipient;
|
|
||||||
itemCopy.CreatorId = item.CreatorId;
|
|
||||||
itemCopy.CreatorData = item.CreatorData;
|
|
||||||
itemCopy.ID = UUID.Random();
|
|
||||||
itemCopy.AssetID = item.AssetID;
|
|
||||||
itemCopy.Description = item.Description;
|
|
||||||
itemCopy.Name = item.Name;
|
|
||||||
itemCopy.AssetType = item.AssetType;
|
|
||||||
itemCopy.InvType = item.InvType;
|
|
||||||
itemCopy.Folder = recipientFolderId;
|
|
||||||
|
|
||||||
if (Permissions.PropagatePermissions() && recipient != senderId)
|
|
||||||
{
|
|
||||||
// Trying to do this right this time. This is evil. If
|
|
||||||
// you believe in Good, go elsewhere. Vampires and other
|
|
||||||
// evil creatores only beyond this point. You have been
|
|
||||||
// warned.
|
|
||||||
|
|
||||||
// We're going to mask a lot of things by the next perms
|
|
||||||
// Tweak the next perms to be nicer to our data
|
|
||||||
//
|
|
||||||
// In this mask, all the bits we do NOT want to mess
|
|
||||||
// with are set. These are:
|
|
||||||
//
|
|
||||||
// Transfer
|
|
||||||
// Copy
|
|
||||||
// Modufy
|
|
||||||
uint permsMask = ~ ((uint)PermissionMask.Copy |
|
|
||||||
(uint)PermissionMask.Transfer |
|
|
||||||
(uint)PermissionMask.Modify);
|
|
||||||
|
|
||||||
// Now, reduce the next perms to the mask bits
|
|
||||||
// relevant to the operation
|
|
||||||
uint nextPerms = permsMask | (item.NextPermissions &
|
|
||||||
((uint)PermissionMask.Copy |
|
|
||||||
(uint)PermissionMask.Transfer |
|
|
||||||
(uint)PermissionMask.Modify));
|
|
||||||
|
|
||||||
// nextPerms now has all bits set, except for the actual
|
|
||||||
// next permission bits.
|
|
||||||
|
|
||||||
// This checks for no mod, no copy, no trans.
|
|
||||||
// This indicates an error or messed up item. Do it like
|
|
||||||
// SL and assume trans
|
|
||||||
if (nextPerms == permsMask)
|
|
||||||
nextPerms |= (uint)PermissionMask.Transfer;
|
|
||||||
|
|
||||||
// Inventory owner perms are the logical AND of the
|
|
||||||
// folded perms and the root prim perms, however, if
|
|
||||||
// the root prim is mod, the inventory perms will be
|
|
||||||
// mod. This happens on "take" and is of little concern
|
|
||||||
// here, save for preventing escalation
|
|
||||||
|
|
||||||
// This hack ensures that items previously permalocked
|
|
||||||
// get unlocked when they're passed or rezzed
|
|
||||||
uint basePerms = item.BasePermissions |
|
|
||||||
(uint)PermissionMask.Move;
|
|
||||||
uint ownerPerms = item.CurrentPermissions;
|
|
||||||
|
|
||||||
// If this is an object, root prim perms may be more
|
|
||||||
// permissive than folded perms. Use folded perms as
|
|
||||||
// a mask
|
|
||||||
if (item.InvType == (int)InventoryType.Object)
|
|
||||||
{
|
|
||||||
// Create a safe mask for the current perms
|
|
||||||
uint foldedPerms = (item.CurrentPermissions & 7) << 13;
|
|
||||||
foldedPerms |= permsMask;
|
|
||||||
|
|
||||||
bool isRootMod = (item.CurrentPermissions &
|
|
||||||
(uint)PermissionMask.Modify) != 0 ?
|
|
||||||
true : false;
|
|
||||||
|
|
||||||
// Mask the owner perms to the folded perms
|
|
||||||
ownerPerms &= foldedPerms;
|
|
||||||
basePerms &= foldedPerms;
|
|
||||||
|
|
||||||
// If the root was mod, let the mask reflect that
|
|
||||||
// We also need to adjust the base here, because
|
|
||||||
// we should be able to edit in-inventory perms
|
|
||||||
// for the root prim, if it's mod.
|
|
||||||
if (isRootMod)
|
|
||||||
{
|
|
||||||
ownerPerms |= (uint)PermissionMask.Modify;
|
|
||||||
basePerms |= (uint)PermissionMask.Modify;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// These will be applied to the root prim at next rez.
|
|
||||||
// The slam bit (bit 3) and folded permission (bits 0-2)
|
|
||||||
// are preserved due to the above mangling
|
|
||||||
ownerPerms &= nextPerms;
|
|
||||||
|
|
||||||
// Mask the base permissions. This is a conservative
|
|
||||||
// approach altering only the three main perms
|
|
||||||
basePerms &= nextPerms;
|
|
||||||
|
|
||||||
// Assign to the actual item. Make sure the slam bit is
|
|
||||||
// set, if it wasn't set before.
|
|
||||||
itemCopy.BasePermissions = basePerms;
|
|
||||||
itemCopy.CurrentPermissions = ownerPerms;
|
|
||||||
itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
|
|
||||||
|
|
||||||
itemCopy.NextPermissions = item.NextPermissions;
|
|
||||||
|
|
||||||
// This preserves "everyone can move"
|
|
||||||
itemCopy.EveryOnePermissions = item.EveryOnePermissions &
|
|
||||||
nextPerms;
|
|
||||||
|
|
||||||
// Intentionally killing "share with group" here, as
|
|
||||||
// the recipient will not have the group this is
|
|
||||||
// set to
|
|
||||||
itemCopy.GroupPermissions = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
itemCopy.CurrentPermissions = item.CurrentPermissions;
|
|
||||||
itemCopy.NextPermissions = item.NextPermissions;
|
|
||||||
itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
|
|
||||||
itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
|
|
||||||
itemCopy.BasePermissions = item.BasePermissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemCopy.Folder == UUID.Zero)
|
|
||||||
{
|
|
||||||
InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
|
|
||||||
|
|
||||||
if (folder != null)
|
|
||||||
{
|
|
||||||
itemCopy.Folder = folder.ID;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
|
|
||||||
|
|
||||||
if (root != null)
|
|
||||||
itemCopy.Folder = root.ID;
|
|
||||||
else
|
|
||||||
return null; // No destination
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
itemCopy.GroupID = UUID.Zero;
|
|
||||||
itemCopy.GroupOwned = false;
|
|
||||||
itemCopy.Flags = item.Flags;
|
|
||||||
itemCopy.SalePrice = item.SalePrice;
|
|
||||||
itemCopy.SaleType = item.SaleType;
|
|
||||||
|
|
||||||
if (AddInventoryItem(itemCopy))
|
|
||||||
{
|
|
||||||
IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
|
|
||||||
if (invAccess != null)
|
|
||||||
invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Permissions.BypassPermissions())
|
|
||||||
{
|
|
||||||
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
|
|
||||||
{
|
|
||||||
List<UUID> items = new List<UUID>();
|
|
||||||
items.Add(itemId);
|
|
||||||
InventoryService.DeleteItems(senderId, items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemCopy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.Owner != senderId)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}",
|
||||||
|
item.Name, item.ID, recipient, senderId, item.Owner);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IUserManagement uman = RequestModuleInterface<IUserManagement>();
|
||||||
|
if (uman != null)
|
||||||
|
uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
||||||
|
|
||||||
|
if (!Permissions.BypassPermissions())
|
||||||
|
{
|
||||||
|
if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert a copy of the item into the recipient
|
||||||
|
InventoryItemBase itemCopy = new InventoryItemBase();
|
||||||
|
itemCopy.Owner = recipient;
|
||||||
|
itemCopy.CreatorId = item.CreatorId;
|
||||||
|
itemCopy.CreatorData = item.CreatorData;
|
||||||
|
itemCopy.ID = UUID.Random();
|
||||||
|
itemCopy.AssetID = item.AssetID;
|
||||||
|
itemCopy.Description = item.Description;
|
||||||
|
itemCopy.Name = item.Name;
|
||||||
|
itemCopy.AssetType = item.AssetType;
|
||||||
|
itemCopy.InvType = item.InvType;
|
||||||
|
itemCopy.Folder = recipientFolderId;
|
||||||
|
|
||||||
|
if (Permissions.PropagatePermissions() && recipient != senderId)
|
||||||
|
{
|
||||||
|
// Trying to do this right this time. This is evil. If
|
||||||
|
// you believe in Good, go elsewhere. Vampires and other
|
||||||
|
// evil creatores only beyond this point. You have been
|
||||||
|
// warned.
|
||||||
|
|
||||||
|
// We're going to mask a lot of things by the next perms
|
||||||
|
// Tweak the next perms to be nicer to our data
|
||||||
|
//
|
||||||
|
// In this mask, all the bits we do NOT want to mess
|
||||||
|
// with are set. These are:
|
||||||
|
//
|
||||||
|
// Transfer
|
||||||
|
// Copy
|
||||||
|
// Modufy
|
||||||
|
uint permsMask = ~ ((uint)PermissionMask.Copy |
|
||||||
|
(uint)PermissionMask.Transfer |
|
||||||
|
(uint)PermissionMask.Modify);
|
||||||
|
|
||||||
|
// Now, reduce the next perms to the mask bits
|
||||||
|
// relevant to the operation
|
||||||
|
uint nextPerms = permsMask | (item.NextPermissions &
|
||||||
|
((uint)PermissionMask.Copy |
|
||||||
|
(uint)PermissionMask.Transfer |
|
||||||
|
(uint)PermissionMask.Modify));
|
||||||
|
|
||||||
|
// nextPerms now has all bits set, except for the actual
|
||||||
|
// next permission bits.
|
||||||
|
|
||||||
|
// This checks for no mod, no copy, no trans.
|
||||||
|
// This indicates an error or messed up item. Do it like
|
||||||
|
// SL and assume trans
|
||||||
|
if (nextPerms == permsMask)
|
||||||
|
nextPerms |= (uint)PermissionMask.Transfer;
|
||||||
|
|
||||||
|
// Inventory owner perms are the logical AND of the
|
||||||
|
// folded perms and the root prim perms, however, if
|
||||||
|
// the root prim is mod, the inventory perms will be
|
||||||
|
// mod. This happens on "take" and is of little concern
|
||||||
|
// here, save for preventing escalation
|
||||||
|
|
||||||
|
// This hack ensures that items previously permalocked
|
||||||
|
// get unlocked when they're passed or rezzed
|
||||||
|
uint basePerms = item.BasePermissions |
|
||||||
|
(uint)PermissionMask.Move;
|
||||||
|
uint ownerPerms = item.CurrentPermissions;
|
||||||
|
|
||||||
|
// If this is an object, root prim perms may be more
|
||||||
|
// permissive than folded perms. Use folded perms as
|
||||||
|
// a mask
|
||||||
|
if (item.InvType == (int)InventoryType.Object)
|
||||||
|
{
|
||||||
|
// Create a safe mask for the current perms
|
||||||
|
uint foldedPerms = (item.CurrentPermissions & 7) << 13;
|
||||||
|
foldedPerms |= permsMask;
|
||||||
|
|
||||||
|
bool isRootMod = (item.CurrentPermissions &
|
||||||
|
(uint)PermissionMask.Modify) != 0 ?
|
||||||
|
true : false;
|
||||||
|
|
||||||
|
// Mask the owner perms to the folded perms
|
||||||
|
ownerPerms &= foldedPerms;
|
||||||
|
basePerms &= foldedPerms;
|
||||||
|
|
||||||
|
// If the root was mod, let the mask reflect that
|
||||||
|
// We also need to adjust the base here, because
|
||||||
|
// we should be able to edit in-inventory perms
|
||||||
|
// for the root prim, if it's mod.
|
||||||
|
if (isRootMod)
|
||||||
|
{
|
||||||
|
ownerPerms |= (uint)PermissionMask.Modify;
|
||||||
|
basePerms |= (uint)PermissionMask.Modify;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// These will be applied to the root prim at next rez.
|
||||||
|
// The slam bit (bit 3) and folded permission (bits 0-2)
|
||||||
|
// are preserved due to the above mangling
|
||||||
|
ownerPerms &= nextPerms;
|
||||||
|
|
||||||
|
// Mask the base permissions. This is a conservative
|
||||||
|
// approach altering only the three main perms
|
||||||
|
basePerms &= nextPerms;
|
||||||
|
|
||||||
|
// Assign to the actual item. Make sure the slam bit is
|
||||||
|
// set, if it wasn't set before.
|
||||||
|
itemCopy.BasePermissions = basePerms;
|
||||||
|
itemCopy.CurrentPermissions = ownerPerms;
|
||||||
|
itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
|
||||||
|
|
||||||
|
itemCopy.NextPermissions = item.NextPermissions;
|
||||||
|
|
||||||
|
// This preserves "everyone can move"
|
||||||
|
itemCopy.EveryOnePermissions = item.EveryOnePermissions &
|
||||||
|
nextPerms;
|
||||||
|
|
||||||
|
// Intentionally killing "share with group" here, as
|
||||||
|
// the recipient will not have the group this is
|
||||||
|
// set to
|
||||||
|
itemCopy.GroupPermissions = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemCopy.CurrentPermissions = item.CurrentPermissions;
|
||||||
|
itemCopy.NextPermissions = item.NextPermissions;
|
||||||
|
itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
|
||||||
|
itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
|
||||||
|
itemCopy.BasePermissions = item.BasePermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemCopy.Folder == UUID.Zero)
|
||||||
|
{
|
||||||
|
InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
|
||||||
|
|
||||||
|
if (folder != null)
|
||||||
|
{
|
||||||
|
itemCopy.Folder = folder.ID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
|
||||||
|
|
||||||
|
if (root != null)
|
||||||
|
itemCopy.Folder = root.ID;
|
||||||
|
else
|
||||||
|
return null; // No destination
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
itemCopy.GroupID = UUID.Zero;
|
||||||
|
itemCopy.GroupOwned = false;
|
||||||
|
itemCopy.Flags = item.Flags;
|
||||||
|
itemCopy.SalePrice = item.SalePrice;
|
||||||
|
itemCopy.SaleType = item.SaleType;
|
||||||
|
|
||||||
|
if (AddInventoryItem(itemCopy))
|
||||||
|
{
|
||||||
|
IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
|
||||||
|
if (invAccess != null)
|
||||||
|
invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Permissions.BypassPermissions())
|
||||||
|
{
|
||||||
|
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
|
||||||
|
{
|
||||||
|
List<UUID> items = new List<UUID>();
|
||||||
|
items.Add(itemId);
|
||||||
|
InventoryService.DeleteItems(senderId, items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -781,7 +787,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="asset"></param>
|
/// <param name="asset"></param>
|
||||||
/// <param name="invType"></param>
|
/// <param name="invType"></param>
|
||||||
/// <param name="nextOwnerMask"></param>
|
/// <param name="nextOwnerMask"></param>
|
||||||
private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
|
public void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
|
||||||
AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
|
AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
|
||||||
{
|
{
|
||||||
CreateNewInventoryItem(
|
CreateNewInventoryItem(
|
||||||
|
@ -835,78 +841,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new inventory item. Called when the client creates a new item directly within their
|
|
||||||
/// inventory (e.g. by selecting a context inventory menu option).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="remoteClient"></param>
|
|
||||||
/// <param name="transactionID"></param>
|
|
||||||
/// <param name="folderID"></param>
|
|
||||||
/// <param name="callbackID"></param>
|
|
||||||
/// <param name="description"></param>
|
|
||||||
/// <param name="name"></param>
|
|
||||||
/// <param name="invType"></param>
|
|
||||||
/// <param name="type"></param>
|
|
||||||
/// <param name="wearableType"></param>
|
|
||||||
/// <param name="nextOwnerMask"></param>
|
|
||||||
public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
|
|
||||||
uint callbackID, string description, string name, sbyte invType,
|
|
||||||
sbyte assetType,
|
|
||||||
byte wearableType, uint nextOwnerMask, int creationDate)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
|
|
||||||
|
|
||||||
if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
|
|
||||||
return;
|
|
||||||
|
|
||||||
InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
|
|
||||||
InventoryFolderBase folder = InventoryService.GetFolder(f);
|
|
||||||
|
|
||||||
if (folder == null || folder.Owner != remoteClient.AgentId)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (transactionID == UUID.Zero)
|
|
||||||
{
|
|
||||||
ScenePresence presence;
|
|
||||||
if (TryGetScenePresence(remoteClient.AgentId, out presence))
|
|
||||||
{
|
|
||||||
byte[] data = null;
|
|
||||||
|
|
||||||
if (invType == (sbyte)InventoryType.Landmark && presence != null)
|
|
||||||
{
|
|
||||||
Vector3 pos = presence.AbsolutePosition;
|
|
||||||
string strdata = String.Format(
|
|
||||||
"Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
|
|
||||||
presence.Scene.RegionInfo.RegionID,
|
|
||||||
pos.X, pos.Y, pos.Z,
|
|
||||||
presence.RegionHandle);
|
|
||||||
data = Encoding.ASCII.GetBytes(strdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
|
|
||||||
AssetService.Store(asset);
|
|
||||||
|
|
||||||
CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
|
|
||||||
remoteClient.AgentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
|
||||||
if (agentTransactions != null)
|
|
||||||
{
|
|
||||||
agentTransactions.HandleItemCreationFromTransaction(
|
|
||||||
remoteClient, transactionID, folderID, callbackID, description,
|
|
||||||
name, invType, assetType, wearableType, nextOwnerMask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Link an inventory item to an existing item.
|
/// Link an inventory item to an existing item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -95,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public bool m_strictAccessControl = true;
|
public bool m_strictAccessControl = true;
|
||||||
public bool m_seeIntoBannedRegion = false;
|
public bool m_seeIntoBannedRegion = false;
|
||||||
public int MaxUndoCount = 5;
|
public int MaxUndoCount = 5;
|
||||||
|
// Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
|
||||||
|
public bool LoginLock = false;
|
||||||
public bool LoginsDisabled = true;
|
public bool LoginsDisabled = true;
|
||||||
|
public bool StartDisabled = false;
|
||||||
public bool LoadingPrims;
|
public bool LoadingPrims;
|
||||||
public IXfer XferManager;
|
public IXfer XferManager;
|
||||||
|
|
||||||
|
@ -1399,10 +1402,26 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
IConfig startupConfig = m_config.Configs["Startup"];
|
IConfig startupConfig = m_config.Configs["Startup"];
|
||||||
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
|
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
|
||||||
{
|
{
|
||||||
|
// This handles a case of a region having no scripts for the RegionReady module
|
||||||
|
if (m_sceneGraph.GetActiveScriptsCount() == 0)
|
||||||
|
{
|
||||||
|
// need to be able to tell these have changed in RegionReady
|
||||||
|
LoginLock = false;
|
||||||
|
EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
|
||||||
|
}
|
||||||
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
|
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
|
||||||
LoginsDisabled = false;
|
// For RegionReady lockouts
|
||||||
|
if( LoginLock == false)
|
||||||
|
{
|
||||||
|
LoginsDisabled = false;
|
||||||
|
}
|
||||||
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
|
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartDisabled = true;
|
||||||
|
LoginsDisabled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NotImplementedException)
|
catch (NotImplementedException)
|
||||||
|
@ -1765,6 +1784,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
|
m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
|
||||||
LoadingPrims = false;
|
LoadingPrims = false;
|
||||||
|
EventManager.TriggerPrimsLoaded(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1930,6 +1950,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
sceneObject.SetGroup(groupID, null);
|
sceneObject.SetGroup(groupID, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IUserManagement uman = RequestModuleInterface<IUserManagement>();
|
||||||
|
if (uman != null)
|
||||||
|
sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
|
||||||
|
|
||||||
sceneObject.ScheduleGroupForFullUpdate();
|
sceneObject.ScheduleGroupForFullUpdate();
|
||||||
|
|
||||||
return sceneObject;
|
return sceneObject;
|
||||||
|
@ -2658,6 +2682,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (TryGetScenePresence(client.AgentId, out presence))
|
if (TryGetScenePresence(client.AgentId, out presence))
|
||||||
{
|
{
|
||||||
m_LastLogin = Util.EnvironmentTickCount();
|
m_LastLogin = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
|
// Cache the user's name
|
||||||
|
CacheUserName(aCircuit);
|
||||||
|
|
||||||
EventManager.TriggerOnNewClient(client);
|
EventManager.TriggerOnNewClient(client);
|
||||||
if (vialogin)
|
if (vialogin)
|
||||||
{
|
{
|
||||||
|
@ -2671,6 +2699,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CacheUserName(AgentCircuitData aCircuit)
|
||||||
|
{
|
||||||
|
IUserManagement uMan = RequestModuleInterface<IUserManagement>();
|
||||||
|
if (uMan != null)
|
||||||
|
{
|
||||||
|
string homeURL = string.Empty;
|
||||||
|
string first = aCircuit.firstname, last = aCircuit.lastname;
|
||||||
|
if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||||
|
homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
|
||||||
|
if (aCircuit.lastname.StartsWith("@"))
|
||||||
|
{
|
||||||
|
string[] parts = aCircuit.firstname.Split('.');
|
||||||
|
if (parts.Length >= 2)
|
||||||
|
{
|
||||||
|
first = parts[0];
|
||||||
|
last = parts[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
|
private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
|
||||||
{
|
{
|
||||||
vialogin = false;
|
vialogin = false;
|
||||||
|
@ -2813,7 +2863,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
|
public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnCreateNewInventoryItem += CreateNewInventoryItem;
|
|
||||||
client.OnLinkInventoryItem += HandleLinkInventoryItem;
|
client.OnLinkInventoryItem += HandleLinkInventoryItem;
|
||||||
client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
|
client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
|
||||||
client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
|
client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
|
||||||
|
@ -2837,7 +2887,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
|
public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnTeleportLocationRequest += RequestTeleportLocation;
|
client.OnTeleportLocationRequest += RequestTeleportLocation;
|
||||||
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SubscribeToClientScriptEvents(IClientAPI client)
|
public virtual void SubscribeToClientScriptEvents(IClientAPI client)
|
||||||
|
@ -2941,7 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
|
public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnCreateNewInventoryItem -= CreateNewInventoryItem;
|
|
||||||
client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
|
client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
|
||||||
client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
|
client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
|
||||||
client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
|
client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
|
||||||
|
@ -2963,7 +3012,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
|
public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnTeleportLocationRequest -= RequestTeleportLocation;
|
client.OnTeleportLocationRequest -= RequestTeleportLocation;
|
||||||
client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
|
//client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
|
||||||
//client.OnTeleportHomeRequest -= TeleportClientHome;
|
//client.OnTeleportHomeRequest -= TeleportClientHome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4064,26 +4113,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to teleport agent to landmark.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="remoteClient"></param>
|
|
||||||
/// <param name="regionHandle"></param>
|
|
||||||
/// <param name="position"></param>
|
|
||||||
public void RequestTeleportLandmark(IClientAPI remoteClient, UUID regionID, Vector3 position)
|
|
||||||
{
|
|
||||||
GridRegion info = GridService.GetRegionByUUID(UUID.Zero, regionID);
|
|
||||||
|
|
||||||
if (info == null)
|
|
||||||
{
|
|
||||||
// can't find the region: Tell viewer and abort
|
|
||||||
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark));
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
|
public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
|
||||||
{
|
{
|
||||||
if (m_teleportModule != null)
|
if (m_teleportModule != null)
|
||||||
|
|
|
@ -1584,7 +1584,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Handle a prim description set request from a viewer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="primLocalID"></param>
|
/// <param name="primLocalID"></param>
|
||||||
/// <param name="description"></param>
|
/// <param name="description"></param>
|
||||||
|
@ -1601,8 +1601,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set a click action for the prim.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="remoteClient"></param>
|
||||||
|
/// <param name="primLocalID"></param>
|
||||||
|
/// <param name="clickAction"></param>
|
||||||
protected internal void PrimClickAction(IClientAPI remoteClient, uint primLocalID, string clickAction)
|
protected internal void PrimClickAction(IClientAPI remoteClient, uint primLocalID, string clickAction)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENEGRAPH]: User {0} set click action for {1} to {2}", remoteClient.Name, primLocalID, clickAction);
|
||||||
|
|
||||||
SceneObjectGroup group = GetGroupByPrim(primLocalID);
|
SceneObjectGroup group = GetGroupByPrim(primLocalID);
|
||||||
if (group != null)
|
if (group != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -563,6 +563,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
// ~SceneObjectGroup()
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat("[SCENE OBJECT GROUP]: Destructor called for {0}, local id {1}", Name, LocalId);
|
||||||
|
// }
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -357,6 +357,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#endregion Fields
|
#endregion Fields
|
||||||
|
|
||||||
|
// ~SceneObjectPart()
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE OBJECT PART]: Destructor called for {0}, local id {1}, parent {2} {3}",
|
||||||
|
// Name, LocalId, ParentGroup.Name, ParentGroup.LocalId);
|
||||||
|
// }
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1636,7 +1643,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
|
PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
|
||||||
PhysActor.SOPDescription = this.Description;
|
PhysActor.SOPDescription = this.Description;
|
||||||
PhysActor.LocalID = LocalId;
|
|
||||||
DoPhysicsPropertyUpdate(RigidBody, true);
|
DoPhysicsPropertyUpdate(RigidBody, true);
|
||||||
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
|
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
@ -4428,6 +4434,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
// It's not phantom anymore. So make sure the physics engine get's knowledge of it
|
// It's not phantom anymore. So make sure the physics engine get's knowledge of it
|
||||||
PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
|
PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
|
||||||
|
LocalId,
|
||||||
string.Format("{0}/{1}", Name, UUID),
|
string.Format("{0}/{1}", Name, UUID),
|
||||||
Shape,
|
Shape,
|
||||||
AbsolutePosition,
|
AbsolutePosition,
|
||||||
|
@ -4439,7 +4446,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
pa = PhysActor;
|
pa = PhysActor;
|
||||||
if (pa != null)
|
if (pa != null)
|
||||||
{
|
{
|
||||||
pa.LocalID = LocalId;
|
|
||||||
DoPhysicsPropertyUpdate(UsePhysics, true);
|
DoPhysicsPropertyUpdate(UsePhysics, true);
|
||||||
if (m_parentGroup != null)
|
if (m_parentGroup != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -121,7 +121,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serialize a scene object to the original xml format
|
/// Serialize a scene object to the original xml format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -572,7 +571,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
|
|
||||||
private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
|
||||||
{
|
{
|
||||||
obj.Shape = ReadShape(reader, "Shape");
|
bool errors = false;
|
||||||
|
obj.Shape = ReadShape(reader, "Shape", out errors);
|
||||||
|
|
||||||
|
if (errors)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors. Please see earlier log entries.",
|
||||||
|
obj.Name, obj.UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
|
||||||
|
@ -1173,7 +1178,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture));
|
writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture));
|
||||||
writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture));
|
writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture));
|
||||||
writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture));
|
writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture));
|
||||||
writer.WriteElementString("A", sop.Color.G.ToString(Utils.EnUsCulture));
|
writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture));
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
|
|
||||||
writer.WriteElementString("Text", sop.Text);
|
writer.WriteElementString("Text", sop.Text);
|
||||||
|
@ -1479,7 +1484,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing {0}: {1}", nodeName, e);
|
m_log.DebugFormat(
|
||||||
|
"[SceneObjectSerializer]: exception while parsing {0} in object {1} {2}: {3}{4}",
|
||||||
|
obj.Name, obj.UUID, nodeName, e.Message, e.StackTrace);
|
||||||
if (reader.NodeType == XmlNodeType.EndElement)
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
reader.Read();
|
reader.Read();
|
||||||
}
|
}
|
||||||
|
@ -1531,8 +1538,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
return tinv;
|
return tinv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name)
|
/// <summary>
|
||||||
|
/// Read a shape from xml input
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader"></param>
|
||||||
|
/// <param name="name">The name of the xml element containing the shape</param>
|
||||||
|
/// <param name="errors">true if any errors were encountered during parsing, false otherwise</param>
|
||||||
|
/// <returns>The shape parsed</returns>
|
||||||
|
static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
|
||||||
{
|
{
|
||||||
|
errors = false;
|
||||||
|
|
||||||
PrimitiveBaseShape shape = new PrimitiveBaseShape();
|
PrimitiveBaseShape shape = new PrimitiveBaseShape();
|
||||||
|
|
||||||
reader.ReadStartElement(name, String.Empty); // Shape
|
reader.ReadStartElement(name, String.Empty); // Shape
|
||||||
|
@ -1551,7 +1567,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing Shape {0}: {1}", nodeName, e);
|
errors = true;
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SceneObjectSerializer]: exception while parsing Shape property {0}: {1}{2}",
|
||||||
|
nodeName, e.Message, e.StackTrace);
|
||||||
|
|
||||||
if (reader.NodeType == XmlNodeType.EndElement)
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
reader.Read();
|
reader.Read();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Timers;
|
||||||
|
using Timer=System.Timers.Timer;
|
||||||
|
using Nini.Config;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.Assets;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Communications;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
|
||||||
|
using OpenSim.Region.CoreModules.World.Serialiser;
|
||||||
|
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Framework.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class UserInventoryTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestGiveInventoryItem()
|
||||||
|
{
|
||||||
|
TestHelper.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001);
|
||||||
|
UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002);
|
||||||
|
InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID);
|
||||||
|
|
||||||
|
scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID);
|
||||||
|
|
||||||
|
InventoryItemBase retrievedItem1
|
||||||
|
= UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Notecards/item1");
|
||||||
|
|
||||||
|
Assert.That(retrievedItem1, Is.Not.Null);
|
||||||
|
|
||||||
|
// Try giving back the freshly received item
|
||||||
|
scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID);
|
||||||
|
|
||||||
|
List<InventoryItemBase> reretrievedItems
|
||||||
|
= UserInventoryHelpers.GetInventoryItems(scene.InventoryService, user1.PrincipalID, "Notecards/item1");
|
||||||
|
|
||||||
|
Assert.That(reretrievedItems.Count, Is.EqualTo(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestGiveInventoryFolder()
|
||||||
|
{
|
||||||
|
TestHelper.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001);
|
||||||
|
UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002);
|
||||||
|
InventoryFolderBase folder1
|
||||||
|
= UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1");
|
||||||
|
|
||||||
|
scene.GiveInventoryFolder(user2.PrincipalID, user1.PrincipalID, folder1.ID, UUID.Zero);
|
||||||
|
|
||||||
|
InventoryFolderBase retrievedFolder1
|
||||||
|
= UserInventoryHelpers.GetInventoryFolder(scene.InventoryService, user2.PrincipalID, "folder1");
|
||||||
|
|
||||||
|
Assert.That(retrievedFolder1, Is.Not.Null);
|
||||||
|
|
||||||
|
// Try giving back the freshly received folder
|
||||||
|
scene.GiveInventoryFolder(user1.PrincipalID, user2.PrincipalID, retrievedFolder1.ID, UUID.Zero);
|
||||||
|
|
||||||
|
List<InventoryFolderBase> reretrievedFolders
|
||||||
|
= UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, "folder1");
|
||||||
|
|
||||||
|
Assert.That(reretrievedFolders.Count, Is.EqualTo(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1183,7 +1183,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
IRC_SendChannelPrivmsg(objectname,url);
|
IRC_SendChannelPrivmsg(objectname,url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
|
public void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1223,6 +1223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a list of groups memberships for the agent that are marked "ListInProfile"
|
/// Get a list of groups memberships for the agent that are marked "ListInProfile"
|
||||||
|
/// (unless that agent has a godLike aspect, in which case get all groups)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataForAgentID"></param>
|
/// <param name="dataForAgentID"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
@ -1231,20 +1232,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID);
|
List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID);
|
||||||
GroupMembershipData[] membershipArray;
|
GroupMembershipData[] membershipArray;
|
||||||
|
|
||||||
if (requestingClient.AgentId != dataForAgentID)
|
// cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for
|
||||||
{
|
// those with a GodLike aspect.
|
||||||
Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership)
|
Scene cScene = (Scene)requestingClient.Scene;
|
||||||
{
|
bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId);
|
||||||
return membership.ListInProfile;
|
|
||||||
};
|
|
||||||
|
|
||||||
membershipArray = membershipData.FindAll(showInProfile).ToArray();
|
if (isGod)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
membershipArray = membershipData.ToArray();
|
membershipArray = membershipData.ToArray();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (requestingClient.AgentId != dataForAgentID)
|
||||||
|
{
|
||||||
|
Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership)
|
||||||
|
{
|
||||||
|
return membership.ListInProfile;
|
||||||
|
};
|
||||||
|
|
||||||
|
membershipArray = membershipData.FindAll(showInProfile).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
membershipArray = membershipData.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_debugEnabled)
|
if (m_debugEnabled)
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
|
m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
|
||||||
|
@ -1257,6 +1270,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
return membershipArray;
|
return membershipArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle)
|
private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle)
|
||||||
{
|
{
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||||
|
|
|
@ -1,161 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// AuraMetaEntity.cs created with MonoDevelop
|
|
||||||
// User: bongiojp at 3:03 PM 8/6/2008
|
|
||||||
//
|
|
||||||
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class AuraMetaEntity : PointMetaEntity
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
//transparency of root part, NOT particle system. Should probably add support for changing particle system transparency.
|
|
||||||
public AuraMetaEntity(Scene scene, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
|
|
||||||
: base(scene, groupPos, transparency)
|
|
||||||
{
|
|
||||||
SetAura(color, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuraMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
|
|
||||||
: base(scene, uuid, groupPos, transparency)
|
|
||||||
{
|
|
||||||
SetAura(color, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
private float Average(Vector3 values)
|
|
||||||
{
|
|
||||||
return (values.X + values.Y + values.Z)/3f;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public void SetAura(Vector3 color, Vector3 scale)
|
|
||||||
{
|
|
||||||
SetAura(color, Average(scale) * 2.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAura(Vector3 color, float radius)
|
|
||||||
{
|
|
||||||
SceneObjectPart From = m_Entity.RootPart;
|
|
||||||
|
|
||||||
//m_log.Debug("[META ENTITY] BEFORE: radius = " + radius);
|
|
||||||
float burstRadius = 0.1f;
|
|
||||||
Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None;
|
|
||||||
float age = 1.5f;
|
|
||||||
float burstRate = 0.4f;
|
|
||||||
if (radius >= 8.0f)
|
|
||||||
{
|
|
||||||
//float sizeOfObject = radius / 2.0f;
|
|
||||||
burstRadius = (radius - 8.0f)/3f;
|
|
||||||
burstRate = 1.5f;
|
|
||||||
radius = 7.99f;
|
|
||||||
patternFlags = Primitive.ParticleSystem.SourcePattern.Explode;
|
|
||||||
age = 4.0f;
|
|
||||||
}
|
|
||||||
SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAura(SceneObjectPart From, Vector3 color, float radius, float burstRadius, float age, float burstRate, Primitive.ParticleSystem.SourcePattern patternFlags)
|
|
||||||
{
|
|
||||||
Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
|
|
||||||
//prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
|
|
||||||
// Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
|
|
||||||
//prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
|
|
||||||
// Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
|
|
||||||
prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
|
|
||||||
prules.PartStartColor.G = color.Y;
|
|
||||||
prules.PartStartColor.B = color.Z;
|
|
||||||
prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency
|
|
||||||
prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
|
|
||||||
prules.PartEndColor.G = color.Y;
|
|
||||||
prules.PartEndColor.B = color.Z;
|
|
||||||
prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency
|
|
||||||
/*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE
|
|
||||||
prules.PartStartScaleY = 0.5f;
|
|
||||||
prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE
|
|
||||||
prules.PartEndScaleY = 0.5f;
|
|
||||||
*/
|
|
||||||
prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE
|
|
||||||
prules.PartStartScaleY = radius;
|
|
||||||
prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE
|
|
||||||
prules.PartEndScaleY = radius;
|
|
||||||
prules.PartMaxAge = age; //PSYS_PART_MAX_AGE
|
|
||||||
prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
|
|
||||||
prules.PartAcceleration.Y = 0.0f;
|
|
||||||
prules.PartAcceleration.Z = 0.0f;
|
|
||||||
prules.Pattern = patternFlags; //PSYS_SRC_PATTERN
|
|
||||||
//prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
|
|
||||||
prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE
|
|
||||||
prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT
|
|
||||||
//prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS
|
|
||||||
prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS
|
|
||||||
prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN
|
|
||||||
prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX
|
|
||||||
prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
|
|
||||||
//prules.Target = To; //PSYS_SRC_TARGET_KEY
|
|
||||||
prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
|
|
||||||
prules.AngularVelocity.Y = 0.0f;
|
|
||||||
prules.AngularVelocity.Z = 0.0f;
|
|
||||||
prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
|
|
||||||
prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
|
|
||||||
|
|
||||||
prules.CRC = 1; //activates the particle system??
|
|
||||||
From.AddNewParticleSystem(prules);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// BeamMetaEntity.cs created with MonoDevelop
|
|
||||||
// User: bongiojp at 3:03 PM 8/6/2008
|
|
||||||
//
|
|
||||||
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class BeamMetaEntity : PointMetaEntity
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public BeamMetaEntity(Scene scene, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
|
|
||||||
: base(scene, groupPos, transparency)
|
|
||||||
{
|
|
||||||
SetBeamToUUID(To, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BeamMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
|
|
||||||
: base(scene, uuid, groupPos, transparency)
|
|
||||||
{
|
|
||||||
SetBeamToUUID(To, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public void SetBeamToUUID(SceneObjectPart To, Vector3 color)
|
|
||||||
{
|
|
||||||
SceneObjectPart From = m_Entity.RootPart;
|
|
||||||
//Scale size of particles to distance objects are apart (for better visibility)
|
|
||||||
Vector3 FromPos = From.GetWorldPosition();
|
|
||||||
Vector3 ToPos = From.GetWorldPosition();
|
|
||||||
// UUID toUUID = To.UUID;
|
|
||||||
float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) +
|
|
||||||
Math.Pow(FromPos.X-ToPos.Y, 2) +
|
|
||||||
Math.Pow(FromPos.X-ToPos.Z, 2)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
//float rate = (float) (distance/4f);
|
|
||||||
float rate = 0.5f;
|
|
||||||
float scale = (float) (distance/128f);
|
|
||||||
float speed = (float) (2.0f - distance/128f);
|
|
||||||
|
|
||||||
SetBeamToUUID(From, To, color, rate, scale, speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, Vector3 color, float rate, float scale, float speed)
|
|
||||||
{
|
|
||||||
Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
|
|
||||||
//prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
|
|
||||||
// Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
|
|
||||||
prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
|
|
||||||
Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
|
|
||||||
prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
|
|
||||||
prules.PartStartColor.G = color.Y;
|
|
||||||
prules.PartStartColor.B = color.Z;
|
|
||||||
prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency
|
|
||||||
prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
|
|
||||||
prules.PartEndColor.G = color.Y;
|
|
||||||
prules.PartEndColor.B = color.Z;
|
|
||||||
prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency
|
|
||||||
prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE
|
|
||||||
prules.PartStartScaleY = scale;
|
|
||||||
prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE
|
|
||||||
prules.PartEndScaleY = scale;
|
|
||||||
prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE
|
|
||||||
prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
|
|
||||||
prules.PartAcceleration.Y = 0.0f;
|
|
||||||
prules.PartAcceleration.Z = 0.0f;
|
|
||||||
//prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN
|
|
||||||
//prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
|
|
||||||
prules.BurstRate = rate; //PSYS_SRC_BURST_RATE
|
|
||||||
prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT
|
|
||||||
prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS
|
|
||||||
prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN
|
|
||||||
prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX
|
|
||||||
prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
|
|
||||||
prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY
|
|
||||||
prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
|
|
||||||
prules.AngularVelocity.Y = 0.0f;
|
|
||||||
prules.AngularVelocity.Z = 0.0f;
|
|
||||||
prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
|
|
||||||
prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
|
|
||||||
|
|
||||||
prules.CRC = 1; //activates the particle system??
|
|
||||||
From.AddNewParticleSystem(prules);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,756 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// CMController.cs
|
|
||||||
// User: bongiojp
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread,
|
|
||||||
/// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system.
|
|
||||||
/// </summary>
|
|
||||||
public class CMController
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue.
|
|
||||||
/// </value>
|
|
||||||
private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>();
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
//bool init = false;
|
|
||||||
int m_channel = -1;
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers.
|
|
||||||
/// </value>
|
|
||||||
IEstateModule m_estateModule = null;
|
|
||||||
|
|
||||||
//These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop)
|
|
||||||
CMModel m_model = null;
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region.
|
|
||||||
/// </value>
|
|
||||||
Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable());
|
|
||||||
State m_state = State.NONE;
|
|
||||||
CMView m_view = null;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="model">
|
|
||||||
/// <see cref="CMModel"/>
|
|
||||||
/// </param>
|
|
||||||
/// <param name="view">
|
|
||||||
/// <see cref="CMView"/>
|
|
||||||
/// </param>
|
|
||||||
/// <param name="scene">
|
|
||||||
/// The first scene to keep track of. <see cref="Scene"/>
|
|
||||||
/// </param>
|
|
||||||
/// <param name="channel">
|
|
||||||
/// The simchat channel number to listen to for instructions <see cref="System.Int32"/>
|
|
||||||
/// </param>
|
|
||||||
public CMController(CMModel model, CMView view, Scene scene, int channel)
|
|
||||||
{
|
|
||||||
m_model = model; m_view = view; m_channel = channel;
|
|
||||||
RegisterNewRegion(scene);
|
|
||||||
Initialize(model, view, scene, channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
//------------------------------------------------ EVENTS ----------------------------------------------------//
|
|
||||||
// private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned.
|
|
||||||
/// </summary>
|
|
||||||
private SceneObjectGroup GetGroupByPrim(uint localID)
|
|
||||||
{
|
|
||||||
foreach (Object currScene in m_sceneList.Values)
|
|
||||||
{
|
|
||||||
foreach (EntityBase ent in ((Scene)currScene).GetEntities())
|
|
||||||
{
|
|
||||||
if (ent is SceneObjectGroup)
|
|
||||||
{
|
|
||||||
if (((SceneObjectGroup)ent).HasChildPrim(localID))
|
|
||||||
return (SceneObjectGroup)ent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initialize(CMModel model, CMView view, Scene scene, int channel)
|
|
||||||
{
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
m_estateModule = scene.RequestModuleInterface<IEstateModule>();
|
|
||||||
Watchdog.StartThread(MainLoop, "Content Management", ThreadPriority.Normal, true);
|
|
||||||
m_state = State.NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions.
|
|
||||||
/// </summary>
|
|
||||||
private void MainLoop()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CMModel model = m_model; CMView view = m_view; int channel = m_channel;
|
|
||||||
Work currentJob = new Work();
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
currentJob = m_WorkQueue.Dequeue();
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request");
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type);
|
|
||||||
switch (currentJob.Type)
|
|
||||||
{
|
|
||||||
case WorkType.NONE:
|
|
||||||
break;
|
|
||||||
case WorkType.OBJECTATTRIBUTECHANGE:
|
|
||||||
ObjectAttributeChanged(model, view, currentJob.LocalId);
|
|
||||||
break;
|
|
||||||
case WorkType.PRIMITIVEADDED:
|
|
||||||
PrimitiveAdded(model, view, currentJob);
|
|
||||||
break;
|
|
||||||
case WorkType.OBJECTDUPLICATED:
|
|
||||||
ObjectDuplicated(model, view, currentJob.LocalId);
|
|
||||||
break;
|
|
||||||
case WorkType.OBJECTKILLED:
|
|
||||||
ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1);
|
|
||||||
break;
|
|
||||||
case WorkType.UNDODID:
|
|
||||||
UndoDid(model, view, currentJob.UUID);
|
|
||||||
break;
|
|
||||||
case WorkType.NEWCLIENT:
|
|
||||||
NewClient(view, (IClientAPI) currentJob.Data1);
|
|
||||||
break;
|
|
||||||
case WorkType.SIMCHAT:
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message);
|
|
||||||
SimChat(model, view, (OSChatMessage) currentJob.Data1, channel);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Watchdog.UpdateThread();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[CONTENT MANAGEMENT]: Content management thread terminating with exception. PLEASE REBOOT YOUR SIM - CONTENT MANAGEMENT WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}",
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Watchdog.RemoveThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled.
|
|
||||||
/// </summary>
|
|
||||||
private void NewClient(CMView view, IClientAPI client)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
view.SendMetaEntitiesToNewClient(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop.
|
|
||||||
/// </summary>
|
|
||||||
private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId)
|
|
||||||
{
|
|
||||||
SceneObjectGroup group = null;
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
group = GetGroupByPrim(LocalId);
|
|
||||||
if (group != null)
|
|
||||||
{
|
|
||||||
view.DisplayAuras(model.UpdateNormalEntityEffects(group)); //Might be a normal entity (green aura)
|
|
||||||
m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied.
|
|
||||||
/// </summary>
|
|
||||||
private void ObjectDuplicated(CMModel model, CMView view, uint localId)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
view.DisplayAuras(model.CheckForNewEntitiesMissingAuras(GetGroupByPrim(localId).Scene));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop.
|
|
||||||
/// </summary>
|
|
||||||
private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
view.RemoveOrUpdateDeletedEntity(group);
|
|
||||||
model.RemoveOrUpdateDeletedEntity(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop.
|
|
||||||
/// </summary>
|
|
||||||
private void PrimitiveAdded(CMModel model, CMView view, Work currentJob)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
foreach (Object scene in m_sceneList.Values)
|
|
||||||
m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop.
|
|
||||||
/// </summary>
|
|
||||||
private void UndoDid(CMModel model, CMView view, UUID uuid)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid);
|
|
||||||
if (ent != null)
|
|
||||||
view.DisplayEntity(ent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Protected Methods
|
|
||||||
|
|
||||||
protected void GroupBeingDeleted(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!");
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTKILLED;
|
|
||||||
moreWork.Data1 = group.Copy();
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void ObjectDuplicated(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTDUPLICATED;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] dup queue");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
|
|
||||||
UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
|
|
||||||
bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTDUPLICATED;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] dup queue");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.NEWCLIENT;
|
|
||||||
moreWork.Data1 = client;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] new client");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnUnDid(IClientAPI remoteClient, UUID primId)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.UNDODID;
|
|
||||||
moreWork.UUID = primId;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] undid");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument.
|
|
||||||
/// </summary>
|
|
||||||
protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity(Hashtable sceneList, Scene scene)
|
|
||||||
{
|
|
||||||
int somethingAddedToList = 1;
|
|
||||||
System.Collections.Generic.List<Scene> newList = new List<Scene>();
|
|
||||||
newList.Add(scene);
|
|
||||||
|
|
||||||
if (!sceneList.ContainsValue(scene))
|
|
||||||
{
|
|
||||||
foreach (Object sceneObj in sceneList)
|
|
||||||
newList.Add((Scene) sceneObj);
|
|
||||||
return newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (somethingAddedToList > 0)
|
|
||||||
{
|
|
||||||
somethingAddedToList = 0;
|
|
||||||
for (int i = 0; i < newList.Count; i++)
|
|
||||||
{
|
|
||||||
foreach (Object sceneObj in sceneList.Values)
|
|
||||||
{
|
|
||||||
if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (!newList.Contains((Scene)sceneObj)))
|
|
||||||
{
|
|
||||||
newList.Add((Scene)sceneObj);
|
|
||||||
somethingAddedToList++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Object sceneObj in sceneList.Values)
|
|
||||||
if (!newList.Contains((Scene)sceneObj))
|
|
||||||
newList.Add((Scene)sceneObj);
|
|
||||||
|
|
||||||
return newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This is stupid, the same information is contained in the first and second argument
|
|
||||||
protected void SimChatSent(Object x, OSChatMessage e)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!");
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message);
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.SIMCHAT;
|
|
||||||
moreWork.Data1 = e;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions.
|
|
||||||
/// </summary>
|
|
||||||
protected void StartManaging(IClientAPI client)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services.");
|
|
||||||
// client.OnChatFromClient += SimChatSent;
|
|
||||||
//init = true;
|
|
||||||
|
|
||||||
OnNewClient(client);
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client.");
|
|
||||||
client.OnUpdatePrimScale += UpdateSingleScale;
|
|
||||||
client.OnUpdatePrimGroupScale += UpdateMultipleScale;
|
|
||||||
client.OnUpdatePrimGroupPosition += UpdateMultiplePosition;
|
|
||||||
client.OnUpdatePrimSinglePosition += UpdateSinglePosition;
|
|
||||||
client.OnUpdatePrimGroupRotation += UpdateMultipleRotation;
|
|
||||||
client.OnUpdatePrimSingleRotation += UpdateSingleRotation;
|
|
||||||
client.OnAddPrim += UpdateNewParts;
|
|
||||||
client.OnObjectDuplicate += ObjectDuplicated;
|
|
||||||
client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay;
|
|
||||||
client.OnUndo += OnUnDid;
|
|
||||||
//client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
protected void StopManaging(UUID clientUUID)
|
|
||||||
{
|
|
||||||
foreach (Object sceneobj in m_sceneList.Values)
|
|
||||||
{
|
|
||||||
ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID);
|
|
||||||
if (presence != null)
|
|
||||||
{
|
|
||||||
IClientAPI client = presence.ControllingClient;
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services.");
|
|
||||||
// client.OnChatFromViewer -= SimChatSent;
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client");
|
|
||||||
client.OnUpdatePrimScale -= UpdateSingleScale;
|
|
||||||
client.OnUpdatePrimGroupScale -= UpdateMultipleScale;
|
|
||||||
client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition;
|
|
||||||
client.OnUpdatePrimSinglePosition -= UpdateSinglePosition;
|
|
||||||
client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation;
|
|
||||||
client.OnUpdatePrimSingleRotation -= UpdateSingleRotation;
|
|
||||||
client.OnAddPrim -= UpdateNewParts;
|
|
||||||
client.OnObjectDuplicate -= ObjectDuplicated;
|
|
||||||
client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay;
|
|
||||||
client.OnUndo -= OnUnDid;
|
|
||||||
//client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateMultiplePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] pos");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateMultipleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] rot");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateMultipleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT]scale");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateNewParts(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
|
|
||||||
byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
|
|
||||||
byte RayEndIsIntersection)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.PRIMITIVEADDED;
|
|
||||||
moreWork.UUID = ownerID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] new parts");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateSinglePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] move");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
protected void UpdateSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] rot");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateSingleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] scale");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called from within the SimChat method.
|
|
||||||
/// </summary>
|
|
||||||
protected void commit(string message, Scene scene, CMModel model, CMView view)
|
|
||||||
{
|
|
||||||
System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
|
|
||||||
|
|
||||||
string[] args = message.Split(new char[] {' '});
|
|
||||||
|
|
||||||
char[] logMessage = {' '};
|
|
||||||
if (args.Length > 1)
|
|
||||||
{
|
|
||||||
logMessage = new char[message.Length - (args[0].Length)];
|
|
||||||
message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region.");
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
{
|
|
||||||
model.CommitRegion(currScene, new String(logMessage));
|
|
||||||
view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.SendSimChatMessage(scene, "Successfully saved all regions.");
|
|
||||||
m_state |= State.DIRTY;
|
|
||||||
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES
|
|
||||||
{
|
|
||||||
view.SendSimChatMessage(scene, "Updating differences between new revision and current environment.");
|
|
||||||
//Hide objects from users and Forget about them
|
|
||||||
view.HideAllMetaEntities();
|
|
||||||
view.HideAllAuras();
|
|
||||||
model.DeleteAllMetaObjects();
|
|
||||||
|
|
||||||
//Recreate them from backend files
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
{
|
|
||||||
model.UpdateCMEntities(currScene);
|
|
||||||
view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Display new objects to users1
|
|
||||||
view.DisplayRecentChanges();
|
|
||||||
view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE.");
|
|
||||||
m_state &= ~(State.DIRTY);
|
|
||||||
m_state |= State.SHOWING_CHANGES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called from within the SimChat method.
|
|
||||||
/// </summary>
|
|
||||||
protected void diffmode(Scene scene, CMModel model, CMView view)
|
|
||||||
{
|
|
||||||
System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
|
|
||||||
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF
|
|
||||||
{
|
|
||||||
view.SendSimChatMessage(scene, "Hiding all meta objects.");
|
|
||||||
view.HideAllMetaEntities();
|
|
||||||
view.HideAllAuras();
|
|
||||||
view.SendSimChatMessage(scene, "Diff-mode = OFF");
|
|
||||||
|
|
||||||
m_state &= ~State.SHOWING_CHANGES;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else // TURN ON
|
|
||||||
{
|
|
||||||
if ((m_state & State.DIRTY) != 0 || m_state == State.NONE)
|
|
||||||
{
|
|
||||||
view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision");
|
|
||||||
//Hide objects from users and Forget about them
|
|
||||||
view.HideAllMetaEntities();
|
|
||||||
view.HideAllAuras();
|
|
||||||
model.DeleteAllMetaObjects();
|
|
||||||
//Recreate them from backend files
|
|
||||||
foreach (Object currScene in m_sceneList.Values)
|
|
||||||
model.UpdateCMEntities((Scene) currScene);
|
|
||||||
}
|
|
||||||
else if ((m_state & State.DIRTY) != 0) {
|
|
||||||
view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision");
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
model.UpdateCMEntities(currScene);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment");
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
model.CheckForNewEntitiesMissingAuras(currScene);
|
|
||||||
view.DisplayRecentChanges();
|
|
||||||
|
|
||||||
view.SendSimChatMessage(scene, "Diff-mode = ON");
|
|
||||||
m_state |= State.SHOWING_CHANGES;
|
|
||||||
m_state &= ~State.DIRTY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called from within the SimChat method. Hides all auras and meta entities,
|
|
||||||
/// retrieves the current scene object list with the most recent revision retrieved from the model for each scene,
|
|
||||||
/// then lets the view update the clients of the new objects.
|
|
||||||
/// </summary>
|
|
||||||
protected void rollback(Scene scene, CMModel model, CMView view)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
view.HideAllAuras();
|
|
||||||
view.HideAllMetaEntities();
|
|
||||||
}
|
|
||||||
|
|
||||||
System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
model.RollbackRegion(currScene);
|
|
||||||
|
|
||||||
if ((m_state & State.DIRTY) != 0)
|
|
||||||
{
|
|
||||||
model.DeleteAllMetaObjects();
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
model.UpdateCMEntities(currScene);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
view.DisplayRecentChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Protected Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scene">
|
|
||||||
/// A <see cref="Scene"/>
|
|
||||||
/// </param>
|
|
||||||
public void RegisterNewRegion(Scene scene)
|
|
||||||
{
|
|
||||||
m_sceneList.Add(scene.RegionInfo.RegionID, scene);
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System.");
|
|
||||||
|
|
||||||
scene.EventManager.OnNewClient += StartManaging;
|
|
||||||
scene.EventManager.OnChatFromClient += SimChatSent;
|
|
||||||
scene.EventManager.OnRemovePresence += StopManaging;
|
|
||||||
// scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
|
|
||||||
scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command.
|
|
||||||
/// </summary>
|
|
||||||
public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel)
|
|
||||||
{
|
|
||||||
if (e.Channel != channel)
|
|
||||||
return;
|
|
||||||
if (e.Sender == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message);
|
|
||||||
|
|
||||||
IClientAPI client = e.Sender;
|
|
||||||
Scene scene = (Scene) e.Scene;
|
|
||||||
string message = e.Message;
|
|
||||||
string[] args = e.Message.Split(new char[] {' '});
|
|
||||||
|
|
||||||
ScenePresence avatar = scene.GetScenePresence(client.AgentId);
|
|
||||||
|
|
||||||
if (!(m_estateModule.IsManager(avatar.UUID)))
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring.");
|
|
||||||
view.SendSimChatMessage(scene, "You must be an estate manager to perform that action.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args[0])
|
|
||||||
{
|
|
||||||
case "ci":
|
|
||||||
case "commit":
|
|
||||||
commit(message, scene, model, view);
|
|
||||||
break;
|
|
||||||
case "dm":
|
|
||||||
case "diff-mode":
|
|
||||||
diffmode(scene, model, view);
|
|
||||||
break;
|
|
||||||
case "rb":
|
|
||||||
case "rollback":
|
|
||||||
rollback(scene, model, view);
|
|
||||||
break;
|
|
||||||
case "help":
|
|
||||||
m_view.DisplayHelpMenu(scene);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
view.SendSimChatMessage(scene, "Command not found: " + args[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
|
|
||||||
#region Other
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk.
|
|
||||||
/// </value>
|
|
||||||
[Flags]
|
|
||||||
private enum State
|
|
||||||
{
|
|
||||||
NONE = 0,
|
|
||||||
DIRTY = 1, // The meta entities may not correctly represent the last revision.
|
|
||||||
SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem.
|
|
||||||
/// </value>
|
|
||||||
private struct Work
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
public Object Data1; //Just space for holding data.
|
|
||||||
public Object Data2; //Just more space for holding data.
|
|
||||||
public uint LocalId; //Convenient
|
|
||||||
public WorkType Type;
|
|
||||||
public UUID UUID; //Convenient
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// Identifies what the data in struct Work should be used for.
|
|
||||||
/// </value>
|
|
||||||
private enum WorkType
|
|
||||||
{
|
|
||||||
NONE,
|
|
||||||
OBJECTATTRIBUTECHANGE,
|
|
||||||
PRIMITIVEADDED,
|
|
||||||
OBJECTDUPLICATED,
|
|
||||||
OBJECTKILLED,
|
|
||||||
UNDODID,
|
|
||||||
NEWCLIENT,
|
|
||||||
SIMCHAT
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Other
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,193 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// CMEntityCollection.cs created with MonoDevelop
|
|
||||||
// User: bongiojp at 10:09 AM 7/7/2008
|
|
||||||
//
|
|
||||||
// Creates, Deletes, Stores ContentManagementEntities
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class CMEntityCollection
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
// private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
// Any ContentManagementEntities that represent old versions of current SceneObjectGroups or
|
|
||||||
// old versions of deleted SceneObjectGroups will be stored in this hash table.
|
|
||||||
// The UUID keys are from the SceneObjectGroup RootPart UUIDs
|
|
||||||
protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //UUID to ContentManagementEntity
|
|
||||||
|
|
||||||
// SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable
|
|
||||||
// The UUID keys are from the SceneObjectPart that they are supposed to be on.
|
|
||||||
protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //UUID to AuraMetaEntity
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public CMEntityCollection()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public Hashtable Auras
|
|
||||||
{
|
|
||||||
get {return m_NewlyCreatedEntityAura; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hashtable Entities
|
|
||||||
{
|
|
||||||
get { return m_CMEntityHash; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public bool AddAura(ContentManagementEntity aura)
|
|
||||||
{
|
|
||||||
if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID))
|
|
||||||
return false;
|
|
||||||
m_NewlyCreatedEntityAura.Add(aura.UUID, aura);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddEntity(ContentManagementEntity ent)
|
|
||||||
{
|
|
||||||
if (m_CMEntityHash.ContainsKey(ent.UUID))
|
|
||||||
return false;
|
|
||||||
m_CMEntityHash.Add(ent.UUID, ent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash
|
|
||||||
public System.Collections.ArrayList CheckForMissingEntities(EntityBase[] currList)
|
|
||||||
{
|
|
||||||
System.Collections.ArrayList missingList = new System.Collections.ArrayList();
|
|
||||||
SceneObjectGroup temp = null;
|
|
||||||
foreach (EntityBase currObj in currList)
|
|
||||||
{
|
|
||||||
if (!(currObj is SceneObjectGroup))
|
|
||||||
continue;
|
|
||||||
temp = (SceneObjectGroup) currObj;
|
|
||||||
|
|
||||||
if (m_CMEntityHash.ContainsKey(temp.UUID))
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in temp.Parts)
|
|
||||||
if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
|
|
||||||
missingList.Add(part);
|
|
||||||
}
|
|
||||||
else //Entire group is missing from revision. (and is a new part in region)
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in temp.Parts)
|
|
||||||
missingList.Add(part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return missingList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearAll()
|
|
||||||
{
|
|
||||||
m_CMEntityHash.Clear();
|
|
||||||
m_NewlyCreatedEntityAura.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Old uuid and new sceneobjectgroup
|
|
||||||
public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part)
|
|
||||||
{
|
|
||||||
AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene,
|
|
||||||
part.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(0,254,0),
|
|
||||||
part.Scale
|
|
||||||
);
|
|
||||||
m_NewlyCreatedEntityAura.Add(part.UUID, ent);
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Old uuid and new sceneobjectgroup
|
|
||||||
public ContentManagementEntity CreateNewEntity(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
ContentManagementEntity ent = new ContentManagementEntity(group, false);
|
|
||||||
m_CMEntityHash.Add(group.UUID, ent);
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentManagementEntity CreateNewEntity(String xml, Scene scene)
|
|
||||||
{
|
|
||||||
ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false);
|
|
||||||
if (ent == null)
|
|
||||||
return null;
|
|
||||||
m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent);
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveEntity(UUID uuid)
|
|
||||||
{
|
|
||||||
if (!m_CMEntityHash.ContainsKey(uuid))
|
|
||||||
return false;
|
|
||||||
m_CMEntityHash.Remove(uuid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveNewlyCreatedEntityAura(UUID uuid)
|
|
||||||
{
|
|
||||||
if (!m_NewlyCreatedEntityAura.ContainsKey(uuid))
|
|
||||||
return false;
|
|
||||||
m_NewlyCreatedEntityAura.Remove(uuid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,366 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class CMModel
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
static float TimeToUpdate = 0;
|
|
||||||
static float TimeToConvertXml = 0;
|
|
||||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// The class that contains all auras and metaentities used in the CMS.
|
|
||||||
/// </value>
|
|
||||||
CMEntityCollection m_MetaEntityCollection = new CMEntityCollection();
|
|
||||||
IContentDatabase m_database = null;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public CMModel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public CMEntityCollection MetaEntityCollection
|
|
||||||
{
|
|
||||||
get { return m_MetaEntityCollection; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity
|
|
||||||
/// it is a new part that must have a green aura (for diff mode).
|
|
||||||
/// Returns list of ContentManagementEntities
|
|
||||||
/// </summary>
|
|
||||||
public ArrayList CheckForNewEntitiesMissingAuras(Scene scene)
|
|
||||||
{
|
|
||||||
ArrayList missingList = null;
|
|
||||||
ArrayList newList = new ArrayList();
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName);
|
|
||||||
|
|
||||||
//Check if the current scene has groups not included in the current list of MetaEntities
|
|
||||||
//If so, then the current scene's parts that are new should be marked green.
|
|
||||||
missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities());
|
|
||||||
|
|
||||||
foreach (Object missingPart in missingList)
|
|
||||||
{
|
|
||||||
if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID))
|
|
||||||
continue;
|
|
||||||
newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart));
|
|
||||||
}
|
|
||||||
m_log.Info("Number of missing objects found: " + newList.Count);
|
|
||||||
return newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message.
|
|
||||||
/// </summary>
|
|
||||||
public void CommitRegion(Scene scene, String logMessage)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length);
|
|
||||||
m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage);
|
|
||||||
m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteAllMetaObjects()
|
|
||||||
{
|
|
||||||
m_MetaEntityCollection.ClearAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentManagementEntity FindMetaEntityAffectedByUndo(UUID uuid)
|
|
||||||
{
|
|
||||||
ContentManagementEntity ent = GetMetaGroupByPrim(uuid);
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------- HELPERS --------------------------------------------------------------------//
|
|
||||||
public ContentManagementEntity GetMetaGroupByPrim(UUID uuid)
|
|
||||||
{
|
|
||||||
foreach (Object ent in m_MetaEntityCollection.Entities.Values)
|
|
||||||
{
|
|
||||||
if (((ContentManagementEntity)ent).HasChildPrim(uuid))
|
|
||||||
return (ContentManagementEntity)ent;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(string database)
|
|
||||||
{
|
|
||||||
if (database == "FileSystemDatabase")
|
|
||||||
m_database = new FileSystemDatabase();
|
|
||||||
else if (database == "GitDatabase")
|
|
||||||
m_database = new GitDatabase();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InitialiseDatabase(Scene scene, string dir)
|
|
||||||
{
|
|
||||||
m_database.Initialise(scene, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should be called just once to finish initializing the database.
|
|
||||||
/// </summary>
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
m_database.PostInitialise();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes the green aura when an a new scene object group is deleted.
|
|
||||||
/// </summary>
|
|
||||||
public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
// Deal with new parts not revisioned that have been deleted.
|
|
||||||
SceneObjectPart[] parts = group.Parts;
|
|
||||||
for (int i = 0; i < parts.Length; i++)
|
|
||||||
{
|
|
||||||
if (m_MetaEntityCollection.Auras.ContainsKey(parts[i].UUID))
|
|
||||||
m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(parts[i].UUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves the latest revision of a region in xml form,
|
|
||||||
/// converts it to scene object groups and scene presences,
|
|
||||||
/// swaps the current scene's entity list with the revision's list.
|
|
||||||
/// Note: Since deleted objects while
|
|
||||||
/// </summary>
|
|
||||||
public void RollbackRegion(Scene scene)
|
|
||||||
{
|
|
||||||
System.Collections.ArrayList xmllist = null;
|
|
||||||
SceneObjectGroup temp = null;
|
|
||||||
System.Collections.Hashtable deleteListUUIDs = new Hashtable();
|
|
||||||
// Dictionary<LLUUID, EntityBase> SearchList = new Dictionary<LLUUID,EntityBase>();
|
|
||||||
Dictionary<UUID, EntityBase> ReplacementList = new Dictionary<UUID,EntityBase>();
|
|
||||||
int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID);
|
|
||||||
// EntityBase[] searchArray;
|
|
||||||
|
|
||||||
xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision);
|
|
||||||
if (xmllist == null)
|
|
||||||
{
|
|
||||||
m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ").");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ").");
|
|
||||||
m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count);
|
|
||||||
m_log.Info("[CMMODEL]: Converting scene entities list to specified revision.");
|
|
||||||
|
|
||||||
m_log.ErrorFormat("[CMMODEL]: 1");
|
|
||||||
|
|
||||||
foreach (string xml in xmllist)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
temp = SceneObjectSerializer.FromXml2Format(xml);
|
|
||||||
temp.SetScene(scene);
|
|
||||||
|
|
||||||
SceneObjectPart[] parts = temp.Parts;
|
|
||||||
for (int i = 0; i < parts.Length; i++)
|
|
||||||
parts[i].RegionHandle = scene.RegionInfo.RegionHandle;
|
|
||||||
|
|
||||||
ReplacementList.Add(temp.UUID, (EntityBase)temp);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//If in scene but not in revision and not a client, remove them
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (EntityBase entity in scene.GetEntities())
|
|
||||||
{
|
|
||||||
if (entity == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (entity is ScenePresence)
|
|
||||||
{
|
|
||||||
ReplacementList.Add(entity.UUID, entity);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else //if (!ReplacementList.ContainsKey(entity.UUID))
|
|
||||||
deleteListUUIDs.Add(entity.UUID, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[CMMODEL]: " + e);
|
|
||||||
deleteListUUIDs.Clear();
|
|
||||||
ReplacementList.Clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (UUID uuid in deleteListUUIDs.Keys)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles.
|
|
||||||
((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup();
|
|
||||||
scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor);
|
|
||||||
scene.SendKillObject(new List<uint>() { scene.Entities[uuid].LocalId });
|
|
||||||
scene.SceneGraph.DeleteSceneObject(uuid, false);
|
|
||||||
((SceneObjectGroup)scene.Entities[uuid]).DeleteGroupFromScene(false);
|
|
||||||
scene.SendKillObject(new List<uint>() { ((SceneObjectGroup)scene.Entities[uuid]).LocalId });
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (scene)
|
|
||||||
{
|
|
||||||
scene.Entities.Clear();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<UUID,EntityBase> kvp in ReplacementList)
|
|
||||||
{
|
|
||||||
scene.Entities.Add(kvp.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (EntityBase ent in ReplacementList.Values)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!(ent is SceneObjectGroup))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) PrimFlags.Phantom) == 0)
|
|
||||||
((SceneObjectGroup)ent).ApplyPhysics(true);
|
|
||||||
((SceneObjectGroup)ent).AttachToBackup();
|
|
||||||
((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected.
|
|
||||||
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup.");
|
|
||||||
scene.Backup(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences
|
|
||||||
/// and display the differences to clients.
|
|
||||||
/// </summary>
|
|
||||||
public void UpdateCMEntities(Scene scene)
|
|
||||||
{
|
|
||||||
Stopwatch x = new Stopwatch();
|
|
||||||
x.Start();
|
|
||||||
|
|
||||||
System.Collections.ArrayList xmllist = null;
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Retrieving object xml files for region: " + scene.RegionInfo.RegionID);
|
|
||||||
xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID);
|
|
||||||
m_log.Info("[FSDB]: got list");
|
|
||||||
if (xmllist == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Stopwatch y = new Stopwatch();
|
|
||||||
y.Start();
|
|
||||||
foreach (string xml in xmllist)
|
|
||||||
m_MetaEntityCollection.CreateNewEntity(xml, scene);
|
|
||||||
y.Stop();
|
|
||||||
TimeToConvertXml += y.ElapsedMilliseconds;
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds);
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml);
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras");
|
|
||||||
CheckForNewEntitiesMissingAuras(scene);
|
|
||||||
|
|
||||||
x.Stop();
|
|
||||||
TimeToUpdate += x.ElapsedMilliseconds;
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds);
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Detects if a scene object group from the scene list has moved or changed scale. The green aura
|
|
||||||
/// that surrounds the object is then moved or scaled with the group.
|
|
||||||
/// </summary>
|
|
||||||
public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
System.Collections.ArrayList auraList = new System.Collections.ArrayList();
|
|
||||||
if (group == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
SceneObjectPart[] parts = group.Parts;
|
|
||||||
for (int i = 0; i < parts.Length; i++)
|
|
||||||
{
|
|
||||||
SceneObjectPart part = parts[i];
|
|
||||||
if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
|
||||||
{
|
|
||||||
((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0, 254, 0), part.Scale);
|
|
||||||
((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
|
|
||||||
auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return auraList;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,206 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// CMView.cs created with MonoDevelop
|
|
||||||
// User: bongiojp at 11:57 AM 7/3/2008
|
|
||||||
//
|
|
||||||
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class CMView
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
CMModel m_model = null;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public CMView()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
// Auras To
|
|
||||||
public void DisplayAuras(CMEntityCollection auraCollection)
|
|
||||||
{
|
|
||||||
foreach (Object ent in auraCollection.Auras.Values)
|
|
||||||
((AuraMetaEntity)ent).SendFullUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auras To Client
|
|
||||||
public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client)
|
|
||||||
{
|
|
||||||
foreach (Object ent in auraCollection.Auras.Values)
|
|
||||||
((AuraMetaEntity)ent).SendFullUpdate(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auras from List To ALL
|
|
||||||
public void DisplayAuras(ArrayList list)
|
|
||||||
{
|
|
||||||
foreach (Object ent in list)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW");
|
|
||||||
((AuraMetaEntity)ent).SendFullUpdateToAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entities to ALL
|
|
||||||
public void DisplayEntities(CMEntityCollection entityCollection)
|
|
||||||
{
|
|
||||||
foreach (Object ent in entityCollection.Entities.Values)
|
|
||||||
((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entities to Client
|
|
||||||
public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client)
|
|
||||||
{
|
|
||||||
foreach (Object ent in entityCollection.Entities.Values)
|
|
||||||
((ContentManagementEntity)ent).SendFullDiffUpdate(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entities from List to ALL
|
|
||||||
public void DisplayEntities(ArrayList list)
|
|
||||||
{
|
|
||||||
foreach (Object ent in list)
|
|
||||||
((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entity to ALL
|
|
||||||
public void DisplayEntity(ContentManagementEntity ent)
|
|
||||||
{
|
|
||||||
ent.SendFullDiffUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisplayHelpMenu(Scene scene)
|
|
||||||
{
|
|
||||||
string menu = "Menu:\n";
|
|
||||||
menu += "commit (ci) - saves current state of the region to a database on the server\n";
|
|
||||||
menu += "diff-mode (dm) - displays those aspects of region that have not been saved but changed since the very last revision. Will dynamically update as you change environment.\n";
|
|
||||||
SendSimChatMessage(scene, menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisplayMetaEntity(UUID uuid)
|
|
||||||
{
|
|
||||||
ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid);
|
|
||||||
if (group != null)
|
|
||||||
group.SendFullDiffUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// update all clients of red/green/blue auras and meta entities that the model knows about.
|
|
||||||
/// </summary>
|
|
||||||
public void DisplayRecentChanges()
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects.");
|
|
||||||
DisplayEntities(m_model.MetaEntityCollection);
|
|
||||||
DisplayAuras(m_model.MetaEntityCollection);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Hide(ContentManagementEntity ent)
|
|
||||||
{
|
|
||||||
ent.HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HideAllAuras()
|
|
||||||
{
|
|
||||||
foreach (Object obj in m_model.MetaEntityCollection.Auras.Values)
|
|
||||||
((MetaEntity)obj).HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HideAllMetaEntities()
|
|
||||||
{
|
|
||||||
foreach (Object obj in m_model.MetaEntityCollection.Entities.Values)
|
|
||||||
((ContentManagementEntity)obj).HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(CMModel model)
|
|
||||||
{
|
|
||||||
m_model = model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted.
|
|
||||||
/// If it's a new scene object, any green aura attached to it is deleted.
|
|
||||||
/// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will
|
|
||||||
/// figure out that there should be a red aura and not a blue aura/beam.
|
|
||||||
/// </summary>
|
|
||||||
public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
// Deal with revisioned parts that have been deleted.
|
|
||||||
if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID))
|
|
||||||
((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
|
|
||||||
|
|
||||||
// Deal with new parts not revisioned that have been deleted.
|
|
||||||
foreach (SceneObjectPart part in group.Parts)
|
|
||||||
if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
|
||||||
((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendMetaEntitiesToNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendSimChatMessage(Scene scene, string message)
|
|
||||||
{
|
|
||||||
scene.SimChat(Utils.StringToBytes(message),
|
|
||||||
ChatTypeEnum.Broadcast, 0, new Vector3(0,0,0), "Content Manager", UUID.Zero, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,375 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class ContentManagementEntity : MetaEntity
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
// static float TimeToDiff = 0;
|
|
||||||
// static float TimeToCreateEntities = 0;
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
protected Dictionary<UUID, AuraMetaEntity> m_AuraEntities = new Dictionary<UUID, AuraMetaEntity>();
|
|
||||||
protected Dictionary<UUID, BeamMetaEntity> m_BeamEntities = new Dictionary<UUID, BeamMetaEntity>();
|
|
||||||
|
|
||||||
// The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different.
|
|
||||||
// This can come in handy.
|
|
||||||
protected SceneObjectGroup m_UnchangedEntity = null;
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list.
|
|
||||||
/// </value>
|
|
||||||
bool DiffersFromSceneGroup = false;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics)
|
|
||||||
: base(Unchanged, false)
|
|
||||||
{
|
|
||||||
m_UnchangedEntity = Unchanged.Copy(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentManagementEntity(string objectXML, Scene scene, bool physics)
|
|
||||||
: base(objectXML, scene, false)
|
|
||||||
{
|
|
||||||
m_UnchangedEntity = SceneObjectSerializer.FromXml2Format(objectXML);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public SceneObjectGroup UnchangedEntity
|
|
||||||
{
|
|
||||||
get { return m_UnchangedEntity; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if an entitybase list (like that returned by scene.GetEntities()) contains a group with the rootpart uuid that matches the current uuid.
|
|
||||||
/// </summary>
|
|
||||||
private bool ContainsKey(List<EntityBase> list, UUID uuid)
|
|
||||||
{
|
|
||||||
foreach (EntityBase part in list)
|
|
||||||
if (part.UUID == uuid)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, UUID uuid)
|
|
||||||
{
|
|
||||||
foreach (EntityBase ent in list)
|
|
||||||
{
|
|
||||||
if (ent is SceneObjectGroup)
|
|
||||||
if (ent.UUID == uuid)
|
|
||||||
return (SceneObjectGroup)ent;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Search for a corresponding group UUID in the scene. If not found, then the revisioned group this CMEntity represents has been deleted. Mark the metaentity appropriately.
|
|
||||||
/// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately.
|
|
||||||
/// </summary>
|
|
||||||
public void FindDifferences()
|
|
||||||
{
|
|
||||||
List<EntityBase> sceneEntityList = new List<EntityBase>(m_Entity.Scene.GetEntities());
|
|
||||||
DiffersFromSceneGroup = false;
|
|
||||||
// if group is not contained in scene's list
|
|
||||||
if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in m_UnchangedEntity.Parts)
|
|
||||||
{
|
|
||||||
// if scene list no longer contains this part, display translucent part and mark with red aura
|
|
||||||
if (!ContainsKey(sceneEntityList, part.UUID))
|
|
||||||
{
|
|
||||||
// if already displaying a red aura over part, make sure its red
|
|
||||||
if (m_AuraEntities.ContainsKey(part.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[part.UUID].SetAura(new Vector3(254, 0, 0), part.Scale);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
|
||||||
part.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(254, 0, 0),
|
|
||||||
part.Scale
|
|
||||||
);
|
|
||||||
m_AuraEntities.Add(part.UUID, auraGroup);
|
|
||||||
}
|
|
||||||
SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
|
|
||||||
SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
|
|
||||||
}
|
|
||||||
// otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
|
|
||||||
}
|
|
||||||
|
|
||||||
// a deleted part has no where to point a beam particle system,
|
|
||||||
// if a metapart had a particle system (maybe it represented a moved part) remove it
|
|
||||||
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
|
||||||
{
|
|
||||||
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
|
||||||
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
|
||||||
}
|
|
||||||
|
|
||||||
DiffersFromSceneGroup = true;
|
|
||||||
}
|
|
||||||
// if scene list does contain group, compare each part in group for differences and display beams and auras appropriately
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID.
|
|
||||||
/// </summary>
|
|
||||||
public bool HasChildPrim(UUID uuid)
|
|
||||||
{
|
|
||||||
return m_UnchangedEntity.ContainsPart(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
|
|
||||||
/// </summary>
|
|
||||||
public bool HasChildPrim(uint localID)
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in m_UnchangedEntity.Parts)
|
|
||||||
if (part.LocalId == localID)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Hide(IClientAPI client)
|
|
||||||
{
|
|
||||||
base.Hide(client);
|
|
||||||
foreach (MetaEntity group in m_AuraEntities.Values)
|
|
||||||
group.Hide(client);
|
|
||||||
foreach (MetaEntity group in m_BeamEntities.Values)
|
|
||||||
group.Hide(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HideFromAll()
|
|
||||||
{
|
|
||||||
base.HideFromAll();
|
|
||||||
foreach (MetaEntity group in m_AuraEntities.Values)
|
|
||||||
group.HideFromAll();
|
|
||||||
foreach (MetaEntity group in m_BeamEntities.Values)
|
|
||||||
group.HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if there was a change between meta entity and the entity group, false otherwise.
|
|
||||||
/// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated).
|
|
||||||
/// </summary>
|
|
||||||
public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup)
|
|
||||||
{
|
|
||||||
SceneObjectPart sceneEntityPart;
|
|
||||||
SceneObjectPart metaEntityPart;
|
|
||||||
Diff differences;
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
// Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
|
|
||||||
// had originally saved.
|
|
||||||
// m_Entity will NOT necessarily be the same entity as the user had saved.
|
|
||||||
foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Parts)
|
|
||||||
{
|
|
||||||
//This is the part that we use to show changes.
|
|
||||||
metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
|
|
||||||
if (sceneEntityGroup.ContainsPart(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
sceneEntityPart = sceneEntityGroup.GetChildPart(UnchangedPart.UUID);
|
|
||||||
differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
|
|
||||||
if (differences != Diff.NONE)
|
|
||||||
metaEntityPart.Text = "CHANGE: " + differences.ToString();
|
|
||||||
if (differences != 0)
|
|
||||||
{
|
|
||||||
// Root Part that has been modified
|
|
||||||
if ((differences & Diff.POSITION) > 0)
|
|
||||||
{
|
|
||||||
// If the position of any part has changed, make sure the RootPart of the
|
|
||||||
// meta entity is pointing with a beam particle system
|
|
||||||
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
|
||||||
{
|
|
||||||
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
|
||||||
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
|
||||||
}
|
|
||||||
BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
|
|
||||||
m_UnchangedEntity.RootPart.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
sceneEntityPart,
|
|
||||||
new Vector3(0, 0, 254)
|
|
||||||
);
|
|
||||||
m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
|
||||||
m_AuraEntities.Remove(UnchangedPart.UUID);
|
|
||||||
}
|
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
|
||||||
UnchangedPart.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(0, 0, 254),
|
|
||||||
UnchangedPart.Scale
|
|
||||||
);
|
|
||||||
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
|
|
||||||
SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
|
|
||||||
|
|
||||||
DiffersFromSceneGroup = true;
|
|
||||||
}
|
|
||||||
else // no differences between scene part and meta part
|
|
||||||
{
|
|
||||||
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
|
||||||
{
|
|
||||||
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
|
||||||
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
|
||||||
}
|
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
|
||||||
m_AuraEntities.Remove(UnchangedPart.UUID);
|
|
||||||
}
|
|
||||||
SetPartTransparency(metaEntityPart, MetaEntity.NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
|
|
||||||
{
|
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
|
||||||
m_AuraEntities.Remove(UnchangedPart.UUID);
|
|
||||||
}
|
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
|
||||||
UnchangedPart.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(254, 0, 0),
|
|
||||||
UnchangedPart.Scale
|
|
||||||
);
|
|
||||||
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
|
|
||||||
SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
|
|
||||||
|
|
||||||
DiffersFromSceneGroup = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullAuraUpdate(IClientAPI client)
|
|
||||||
{
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
foreach (AuraMetaEntity group in m_AuraEntities.Values)
|
|
||||||
group.SendFullUpdate(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullAuraUpdateToAll()
|
|
||||||
{
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
foreach (AuraMetaEntity group in m_AuraEntities.Values)
|
|
||||||
group.SendFullUpdateToAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullBeamUpdate(IClientAPI client)
|
|
||||||
{
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
foreach (BeamMetaEntity group in m_BeamEntities.Values)
|
|
||||||
group.SendFullUpdate(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullBeamUpdateToAll()
|
|
||||||
{
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
foreach (BeamMetaEntity group in m_BeamEntities.Values)
|
|
||||||
group.SendFullUpdateToAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullDiffUpdate(IClientAPI client)
|
|
||||||
{
|
|
||||||
FindDifferences();
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
SendFullUpdate(client);
|
|
||||||
SendFullAuraUpdate(client);
|
|
||||||
SendFullBeamUpdate(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullDiffUpdateToAll()
|
|
||||||
{
|
|
||||||
FindDifferences();
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
SendFullUpdateToAll();
|
|
||||||
SendFullAuraUpdateToAll();
|
|
||||||
SendFullBeamUpdateToAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,163 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// ContentManagementModule.cs
|
|
||||||
// User: bongiojp
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class ContentManagementModule : IRegionModule
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
bool initialised = false;
|
|
||||||
CMController m_control = null;
|
|
||||||
bool m_enabled = false;
|
|
||||||
CMModel m_model = null;
|
|
||||||
bool m_posted = false;
|
|
||||||
CMView m_view = null;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public bool IsSharedModule
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "ContentManagementModule"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(Scene scene, IConfigSource source)
|
|
||||||
{
|
|
||||||
string databaseDir = "./";
|
|
||||||
string database = "FileSystemDatabase";
|
|
||||||
int channel = 345;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (source.Configs["CMS"] == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_enabled = source.Configs["CMS"].GetBoolean("enabled", false);
|
|
||||||
databaseDir = source.Configs["CMS"].GetString("directory", databaseDir);
|
|
||||||
database = source.Configs["CMS"].GetString("database", database);
|
|
||||||
channel = source.Configs["CMS"].GetInt("channel", channel);
|
|
||||||
|
|
||||||
if (database != "FileSystemDatabase" && database != "GitDatabase")
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[Content Management]: The Database attribute must be defined as either FileSystemDatabase or GitDatabase");
|
|
||||||
m_enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e);
|
|
||||||
m_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_enabled)
|
|
||||||
{
|
|
||||||
m_log.Info("[Content Management]: Content Management System is not Enabled.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
if (!initialised) //only init once
|
|
||||||
{
|
|
||||||
m_view = new CMView();
|
|
||||||
m_model = new CMModel();
|
|
||||||
m_control = new CMController(m_model, m_view, scene, channel);
|
|
||||||
m_model.Initialise(database);
|
|
||||||
m_view.Initialise(m_model);
|
|
||||||
|
|
||||||
initialised = true;
|
|
||||||
m_model.InitialiseDatabase(scene, databaseDir);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_model.InitialiseDatabase(scene, databaseDir);
|
|
||||||
m_control.RegisterNewRegion(scene);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
if (! m_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
if (!m_posted) //only post once
|
|
||||||
{
|
|
||||||
m_model.PostInitialise();
|
|
||||||
m_posted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,317 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// FileSystemDatabase.cs
|
|
||||||
// User: bongiojp
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using Slash = System.IO.Path;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
|
||||||
using OpenSim.Region.CoreModules.World.Terrain;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class FileSystemDatabase : IContentDatabase
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
public static float TimeToDownload = 0;
|
|
||||||
public static float TimeToSave = 0;
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
private string m_repodir = null;
|
|
||||||
private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
|
|
||||||
private Dictionary<UUID, IRegionSerialiserModule> m_serialiser = new Dictionary<UUID, IRegionSerialiserModule>();
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public FileSystemDatabase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
// called by postinitialise
|
|
||||||
private void CreateDirectory()
|
|
||||||
{
|
|
||||||
string scenedir;
|
|
||||||
if (!Directory.Exists(m_repodir))
|
|
||||||
Directory.CreateDirectory(m_repodir);
|
|
||||||
|
|
||||||
foreach (UUID region in m_scenes.Keys)
|
|
||||||
{
|
|
||||||
scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar;
|
|
||||||
if (!Directory.Exists(scenedir))
|
|
||||||
Directory.CreateDirectory(scenedir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// called by postinitialise
|
|
||||||
private void SetupSerialiser()
|
|
||||||
{
|
|
||||||
if (m_serialiser.Count == 0)
|
|
||||||
{
|
|
||||||
foreach (UUID region in m_scenes.Keys)
|
|
||||||
{
|
|
||||||
m_serialiser.Add(region, m_scenes[region].RequestModuleInterface<IRegionSerialiserModule>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public int GetMostRecentRevision(UUID regionid)
|
|
||||||
{
|
|
||||||
return NumOfRegionRev(regionid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectHeightMap(UUID regionid)
|
|
||||||
{
|
|
||||||
String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
|
|
||||||
Slash.DirectorySeparatorChar + "heightmap.r32";
|
|
||||||
FileStream fs = new FileStream(filename, FileMode.Open);
|
|
||||||
StreamReader sr = new StreamReader(fs);
|
|
||||||
String result = sr.ReadToEnd();
|
|
||||||
sr.Close();
|
|
||||||
fs.Close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectHeightMap(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
|
|
||||||
Slash.DirectorySeparatorChar + "heightmap.r32";
|
|
||||||
FileStream fs = new FileStream(filename, FileMode.Open);
|
|
||||||
StreamReader sr = new StreamReader(fs);
|
|
||||||
String result = sr.ReadToEnd();
|
|
||||||
sr.Close();
|
|
||||||
fs.Close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
System.Collections.ArrayList objectList = new System.Collections.ArrayList();
|
|
||||||
string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
|
|
||||||
+ revision + Slash.DirectorySeparatorChar + "objects.xml";
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
XmlNode rootNode;
|
|
||||||
//int primCount = 0;
|
|
||||||
//SceneObjectGroup obj = null;
|
|
||||||
|
|
||||||
if (File.Exists(filename))
|
|
||||||
{
|
|
||||||
XmlTextReader reader = new XmlTextReader(filename);
|
|
||||||
reader.WhitespaceHandling = WhitespaceHandling.None;
|
|
||||||
doc.Load(reader);
|
|
||||||
reader.Close();
|
|
||||||
rootNode = doc.FirstChild;
|
|
||||||
foreach (XmlNode aPrimNode in rootNode.ChildNodes)
|
|
||||||
{
|
|
||||||
objectList.Add(aPrimNode.OuterXml);
|
|
||||||
}
|
|
||||||
return objectList;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
|
|
||||||
{
|
|
||||||
int revision = NumOfRegionRev(regionid);
|
|
||||||
m_log.Info("[FSDB]: found revisions:" + revision);
|
|
||||||
System.Collections.ArrayList xmlList = new System.Collections.ArrayList();
|
|
||||||
string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
|
|
||||||
+ revision + Slash.DirectorySeparatorChar + "objects.xml";
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
XmlNode rootNode;
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: Checking if " + filename + " exists.");
|
|
||||||
if (File.Exists(filename))
|
|
||||||
{
|
|
||||||
Stopwatch x = new Stopwatch();
|
|
||||||
x.Start();
|
|
||||||
|
|
||||||
XmlTextReader reader = new XmlTextReader(filename);
|
|
||||||
reader.WhitespaceHandling = WhitespaceHandling.None;
|
|
||||||
doc.Load(reader);
|
|
||||||
reader.Close();
|
|
||||||
rootNode = doc.FirstChild;
|
|
||||||
|
|
||||||
foreach (XmlNode aPrimNode in rootNode.ChildNodes)
|
|
||||||
{
|
|
||||||
xmlList.Add(aPrimNode.OuterXml);
|
|
||||||
}
|
|
||||||
|
|
||||||
x.Stop();
|
|
||||||
TimeToDownload += x.ElapsedMilliseconds;
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload);
|
|
||||||
|
|
||||||
return xmlList;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(Scene scene, string dir)
|
|
||||||
{
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
if (m_repodir == null)
|
|
||||||
m_repodir = dir;
|
|
||||||
}
|
|
||||||
lock (m_scenes)
|
|
||||||
m_scenes.Add(scene.RegionInfo.RegionID, scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID regionid)
|
|
||||||
{
|
|
||||||
SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>();
|
|
||||||
|
|
||||||
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
||||||
string[] directories = Directory.GetDirectories(scenedir);
|
|
||||||
|
|
||||||
FileStream fs = null;
|
|
||||||
StreamReader sr = null;
|
|
||||||
String logMessage = "";
|
|
||||||
String logLocation = "";
|
|
||||||
foreach (string revisionDir in directories)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logLocation = revisionDir + Slash.DirectorySeparatorChar + "log";
|
|
||||||
fs = new FileStream(logLocation, FileMode.Open);
|
|
||||||
sr = new StreamReader(fs);
|
|
||||||
logMessage = sr.ReadToEnd();
|
|
||||||
sr.Close();
|
|
||||||
fs.Close();
|
|
||||||
revisionDict.Add(revisionDir, logMessage);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return revisionDict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NumOfRegionRev(UUID regionid)
|
|
||||||
{
|
|
||||||
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
||||||
m_log.Info("[FSDB]: Reading scene dir: " + scenedir);
|
|
||||||
string[] directories = Directory.GetDirectories(scenedir);
|
|
||||||
return directories.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run once and only once.
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
SetupSerialiser();
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: Creating repository in " + m_repodir + ".");
|
|
||||||
CreateDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveRegion(UUID regionid, string regionName, string logMessage)
|
|
||||||
{
|
|
||||||
m_log.Info("[FSDB]: ...............................");
|
|
||||||
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir);
|
|
||||||
if (!Directory.Exists(scenedir))
|
|
||||||
Directory.CreateDirectory(scenedir);
|
|
||||||
|
|
||||||
int newRevisionNum = GetMostRecentRevision(regionid)+1;
|
|
||||||
string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar;
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir);
|
|
||||||
if (!Directory.Exists(revisiondir))
|
|
||||||
Directory.CreateDirectory(revisiondir);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Stopwatch x = new Stopwatch();
|
|
||||||
x.Start();
|
|
||||||
if (m_scenes.ContainsKey(regionid))
|
|
||||||
{
|
|
||||||
m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir);
|
|
||||||
}
|
|
||||||
x.Stop();
|
|
||||||
TimeToSave += x.ElapsedMilliseconds;
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds);
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Finish by writing log message.
|
|
||||||
FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite);
|
|
||||||
StreamWriter sw = new StreamWriter(file);
|
|
||||||
sw.Write(logMessage);
|
|
||||||
sw.Close();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// GitDatabase.cs
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Slash = System.IO.Path;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
|
||||||
using OpenSim.Region.CoreModules.World.Terrain;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Just a stub :-(
|
|
||||||
/// </summary>
|
|
||||||
public class GitDatabase : IContentDatabase
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public GitDatabase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public SceneObjectGroup GetMostRecentObjectRevision(UUID id)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetMostRecentRevision(UUID regionid)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneObjectGroup GetObjectRevision(UUID id, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetObjectsFromRegion(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectHeightMap(UUID regionid)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectHeightMap(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectXML(UUID regionid)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectXML(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool InRepository(UUID id)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(Scene scene, String dir)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(UUID id)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NumOfObjectRev(UUID id)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NumOfRegionRev(UUID regionid)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveObject(SceneObjectGroup entity)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveRegion(UUID regionid, string regionName, string logMessage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// IContentDatabase.cs
|
|
||||||
// User: bongiojp
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public interface IContentDatabase
|
|
||||||
{
|
|
||||||
#region Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the most recent revision number of a region.
|
|
||||||
/// </summary>
|
|
||||||
int GetMostRecentRevision(UUID regionid);
|
|
||||||
|
|
||||||
string GetRegionObjectHeightMap(UUID regionid);
|
|
||||||
|
|
||||||
string GetRegionObjectHeightMap(UUID regionid, int revision);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region.
|
|
||||||
/// </summary>
|
|
||||||
System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid);
|
|
||||||
|
|
||||||
System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database.
|
|
||||||
/// Initialise should be called one for each region to be contained in the database. The directory should be the full path
|
|
||||||
/// to the repository and will only be defined once, regardless of how many times the method is called.
|
|
||||||
/// </summary>
|
|
||||||
void Initialise(Scene scene, String dir);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of the revision numbers and corresponding log messages for a given region.
|
|
||||||
/// </summary>
|
|
||||||
System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the total number of revisions saved for a specific region.
|
|
||||||
/// </summary>
|
|
||||||
int NumOfRegionRev(UUID regionid);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should be called once after Initialise has been called.
|
|
||||||
/// </summary>
|
|
||||||
void PostInitialise();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the Region terrain map and objects within the region as xml to the database.
|
|
||||||
/// </summary>
|
|
||||||
void SaveRegion(UUID regionid, string regionName, string logMessage);
|
|
||||||
|
|
||||||
#endregion Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,270 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class MetaEntity
|
|
||||||
{
|
|
||||||
#region Constants
|
|
||||||
|
|
||||||
public const float INVISIBLE = .95f;
|
|
||||||
|
|
||||||
// Settings for transparency of metaentity
|
|
||||||
public const float NONE = 0f;
|
|
||||||
public const float TRANSLUCENT = .5f;
|
|
||||||
|
|
||||||
#endregion Constants
|
|
||||||
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
//private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity.
|
|
||||||
protected uint m_metaLocalid;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public MetaEntity()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes a new meta entity by copying the given scene object group.
|
|
||||||
/// The physics boolean is just a stub right now.
|
|
||||||
/// </summary>
|
|
||||||
public MetaEntity(SceneObjectGroup orig, bool physics)
|
|
||||||
{
|
|
||||||
m_Entity = orig.Copy(false);
|
|
||||||
Initialize(physics);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Takes an XML description of a scene object group and converts it to a meta entity.
|
|
||||||
/// </summary>
|
|
||||||
public MetaEntity(string objectXML, Scene scene, bool physics)
|
|
||||||
{
|
|
||||||
m_Entity = SceneObjectSerializer.FromXml2Format(objectXML);
|
|
||||||
m_Entity.SetScene(scene);
|
|
||||||
Initialize(physics);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public SceneObjectPart[] Parts
|
|
||||||
{
|
|
||||||
get { return m_Entity.Parts; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint LocalId
|
|
||||||
{
|
|
||||||
get { return m_Entity.LocalId; }
|
|
||||||
set { m_Entity.LocalId = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneObjectGroup ObjectGroup
|
|
||||||
{
|
|
||||||
get { return m_Entity; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int PrimCount
|
|
||||||
{
|
|
||||||
get { return m_Entity.PrimCount; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneObjectPart RootPart
|
|
||||||
{
|
|
||||||
get { return m_Entity.RootPart; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Scene Scene
|
|
||||||
{
|
|
||||||
get { return m_Entity.Scene; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID UUID
|
|
||||||
{
|
|
||||||
get { return m_Entity.UUID; }
|
|
||||||
set { m_Entity.UUID = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Protected Methods
|
|
||||||
|
|
||||||
// The metaentity objectgroup must have unique localids as well as unique uuids.
|
|
||||||
// localids are used by the client to refer to parts.
|
|
||||||
// uuids are sent to the client and back to the server to identify parts on the server side.
|
|
||||||
/// <summary>
|
|
||||||
/// Changes localids and uuids of m_Entity.
|
|
||||||
/// </summary>
|
|
||||||
protected void Initialize(bool physics)
|
|
||||||
{
|
|
||||||
//make new uuids
|
|
||||||
Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
|
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_Entity.Parts)
|
|
||||||
{
|
|
||||||
part.ResetIDs(part.LinkNum);
|
|
||||||
parts.Add(part.UUID, part);
|
|
||||||
}
|
|
||||||
|
|
||||||
//finalize
|
|
||||||
m_Entity.RootPart.PhysActor = null;
|
|
||||||
foreach (SceneObjectPart part in parts.Values)
|
|
||||||
m_Entity.AddPart(part);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Protected Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hides the metaentity from a single client.
|
|
||||||
/// </summary>
|
|
||||||
public virtual void Hide(IClientAPI client)
|
|
||||||
{
|
|
||||||
//This deletes the group without removing from any databases.
|
|
||||||
//This is important because we are not IN any database.
|
|
||||||
//m_Entity.FakeDeleteGroup();
|
|
||||||
foreach (SceneObjectPart part in m_Entity.Parts)
|
|
||||||
client.SendKillObject(m_Entity.RegionHandle, new List<uint>() { part.LocalId });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server.
|
|
||||||
/// </summary>
|
|
||||||
public virtual void HideFromAll()
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in m_Entity.Parts)
|
|
||||||
{
|
|
||||||
m_Entity.Scene.ForEachClient(
|
|
||||||
delegate(IClientAPI controller)
|
|
||||||
{ controller.SendKillObject(m_Entity.RegionHandle, new List<uint>() { part.LocalId }); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullUpdate(IClientAPI client)
|
|
||||||
{
|
|
||||||
// Not sure what clientFlags should be but 0 seems to work
|
|
||||||
SendFullUpdate(client, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullUpdate(IClientAPI client, uint clientFlags)
|
|
||||||
{
|
|
||||||
m_Entity.SendFullUpdateToClient(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullUpdateToAll()
|
|
||||||
{
|
|
||||||
m_Entity.Scene.ForEachClient(
|
|
||||||
delegate(IClientAPI controller)
|
|
||||||
{ m_Entity.SendFullUpdateToClient(controller); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes a single SceneObjectPart see through.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="part">
|
|
||||||
/// A <see cref="SceneObjectPart"/>
|
|
||||||
/// The part to make see through
|
|
||||||
/// </param>
|
|
||||||
/// <param name="transparencyAmount">
|
|
||||||
/// A <see cref="System.Single"/>
|
|
||||||
/// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible.
|
|
||||||
/// </param>
|
|
||||||
public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount)
|
|
||||||
{
|
|
||||||
Primitive.TextureEntry tex = null;
|
|
||||||
Color4 texcolor;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tex = part.Shape.Textures;
|
|
||||||
texcolor = new Color4();
|
|
||||||
}
|
|
||||||
catch(Exception)
|
|
||||||
{
|
|
||||||
//m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint i = 0; i < tex.FaceTextures.Length; i++)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (tex.FaceTextures[i] != null)
|
|
||||||
{
|
|
||||||
texcolor = tex.FaceTextures[i].RGBA;
|
|
||||||
texcolor.A = transparencyAmount;
|
|
||||||
tex.FaceTextures[i].RGBA = texcolor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
//m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
texcolor = tex.DefaultTexture.RGBA;
|
|
||||||
texcolor.A = transparencyAmount;
|
|
||||||
tex.DefaultTexture.RGBA = texcolor;
|
|
||||||
part.Shape.TextureEntry = tex.GetBytes();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
//m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class PointMetaEntity : MetaEntity
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public PointMetaEntity(Scene scene, Vector3 groupPos, float transparency)
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
CreatePointEntity(scene, UUID.Random(), groupPos);
|
|
||||||
SetPartTransparency(m_Entity.RootPart, transparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PointMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency)
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
CreatePointEntity(scene, uuid, groupPos);
|
|
||||||
SetPartTransparency(m_Entity.RootPart, transparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos)
|
|
||||||
{
|
|
||||||
SceneObjectPart y = new SceneObjectPart();
|
|
||||||
|
|
||||||
//Initialize part
|
|
||||||
y.Name = "Very Small Point";
|
|
||||||
y.RegionHandle = scene.RegionInfo.RegionHandle;
|
|
||||||
y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
|
|
||||||
y.OwnerID = UUID.Zero;
|
|
||||||
y.CreatorID = UUID.Zero;
|
|
||||||
y.LastOwnerID = UUID.Zero;
|
|
||||||
y.UUID = uuid;
|
|
||||||
|
|
||||||
y.Shape = PrimitiveBaseShape.CreateBox();
|
|
||||||
y.Scale = new Vector3(0.01f,0.01f,0.01f);
|
|
||||||
y.LastOwnerID = UUID.Zero;
|
|
||||||
y.GroupPosition = groupPos;
|
|
||||||
y.OffsetPosition = Vector3.Zero;
|
|
||||||
y.RotationOffset = Quaternion.Identity;
|
|
||||||
y.Velocity = Vector3.Zero;
|
|
||||||
y.AngularVelocity = Vector3.Zero;
|
|
||||||
y.Acceleration = Vector3.Zero;
|
|
||||||
|
|
||||||
y.Flags = 0;
|
|
||||||
y.TrimPermissions();
|
|
||||||
|
|
||||||
//Initialize group and add part as root part
|
|
||||||
SceneObjectGroup x = new SceneObjectGroup(y);
|
|
||||||
x.SetScene(scene);
|
|
||||||
x.RegionHandle = scene.RegionInfo.RegionHandle;
|
|
||||||
x.SetScene(scene);
|
|
||||||
|
|
||||||
m_Entity = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
This module is meant to be built alone and not added to the Opensim code base. References are made to required dlls through a
|
|
||||||
reference file, ContentManagement.mdp. Originally, for development, this project was contained in the Opensim/Region/Modules/
|
|
||||||
directory.
|
|
||||||
|
|
||||||
To compile: nant
|
|
||||||
To use: Copy ContentManagement.dll into the bin directory of your Opensim build. You should find many other dlls in the same directory.
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------------------------------------------
|
|
||||||
To build the libgit.so file:
|
|
||||||
|
|
||||||
#Download GIT git repository
|
|
||||||
$ git clone git://git2.kernel.org/pub/OpenSim/Region/Environment/Modules/ContentManagementSystem/scm/git/git.git
|
|
||||||
$ cd git
|
|
||||||
|
|
||||||
#Compile GIT
|
|
||||||
#Note that we are adding two extra flags to pass to gcc while compiling (-c and -fPIC)
|
|
||||||
$ autoconf
|
|
||||||
$ ./configure
|
|
||||||
$ CFLAGS="-g -O2 -Wall -c -fPIC" make
|
|
||||||
|
|
||||||
#Copy necessary object files (and some not so necessary) to their own directory for shared object file creation
|
|
||||||
$ mkdir ../libgit-objects
|
|
||||||
$ cp builtin*.o ../libgit-objects
|
|
||||||
$ cp xdiff/*.o ../libgit-objects
|
|
||||||
$ cp libgit.a ../libgit-objects
|
|
||||||
|
|
||||||
#Remove the main symbol from any object files (like git.o)
|
|
||||||
$ cd ../libgit-objects
|
|
||||||
$ strip -N main *.o
|
|
||||||
|
|
||||||
#Uncompress the plumbing objects from archive created by git
|
|
||||||
$ ar x libgit.a
|
|
||||||
|
|
||||||
#Create shared object file from all objects (including the zlib library)
|
|
||||||
$ ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o
|
|
||||||
|
|
||||||
|
|
||||||
#You can also just copy the following commands into a file and run as a script inside the git directory
|
|
||||||
|
|
||||||
make clean
|
|
||||||
autoconf
|
|
||||||
./configure
|
|
||||||
CFLAGS="-g -O2 -Wall -c -fPIC" make
|
|
||||||
mkdir libgit-objects
|
|
||||||
cp builtin*.o libgit-objects
|
|
||||||
cp xdiff/*.o libgit-objects
|
|
||||||
cp libgit.a libgit-objects
|
|
||||||
cd libgit-objects
|
|
||||||
strip -N main *.o
|
|
||||||
ar x libgit.a
|
|
||||||
ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o
|
|
|
@ -1,216 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// SceneObjectGroupDiff.cs
|
|
||||||
// User: bongiojp
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
#region Enumerations
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum Diff
|
|
||||||
{
|
|
||||||
NONE = 0,
|
|
||||||
FACECOLOR = 1,
|
|
||||||
SHAPE = 1<<1,
|
|
||||||
MATERIAL = 1<<2,
|
|
||||||
TEXTURE = 1<<3,
|
|
||||||
SCALE = 1<<4,
|
|
||||||
POSITION = 1<<5,
|
|
||||||
OFFSETPOSITION = 1<<6,
|
|
||||||
ROTATIONOFFSET = 1<<7,
|
|
||||||
ROTATIONALVELOCITY = 1<<8,
|
|
||||||
ACCELERATION = 1<<9,
|
|
||||||
ANGULARVELOCITY = 1<<10,
|
|
||||||
VELOCITY = 1<<11,
|
|
||||||
OBJECTOWNER = 1<<12,
|
|
||||||
PERMISSIONS = 1<<13,
|
|
||||||
DESCRIPTION = 1<<14,
|
|
||||||
NAME = 1<<15,
|
|
||||||
SCRIPT = 1<<16,
|
|
||||||
CLICKACTION = 1<<17,
|
|
||||||
PARTICLESYSTEM = 1<<18,
|
|
||||||
GLOW = 1<<19,
|
|
||||||
SALEPRICE = 1<<20,
|
|
||||||
SITNAME = 1<<21,
|
|
||||||
SITTARGETORIENTATION = 1<<22,
|
|
||||||
SITTARGETPOSITION = 1<<23,
|
|
||||||
TEXT = 1<<24,
|
|
||||||
TOUCHNAME = 1<<25
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Enumerations
|
|
||||||
|
|
||||||
public static class Difference
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
static float TimeToDiff = 0;
|
|
||||||
// private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
private static bool AreQuaternionsEquivalent(Quaternion first, Quaternion second)
|
|
||||||
{
|
|
||||||
Vector3 firstVector = llRot2Euler(first);
|
|
||||||
Vector3 secondVector = llRot2Euler(second);
|
|
||||||
return AreVectorsEquivalent(firstVector, secondVector);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool AreVectorsEquivalent(Vector3 first, Vector3 second)
|
|
||||||
{
|
|
||||||
if (TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2)
|
|
||||||
&& TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2)
|
|
||||||
&& TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2)
|
|
||||||
)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
|
|
||||||
private static double NormalizeAngle(double angle)
|
|
||||||
{
|
|
||||||
angle = angle % (Math.PI * 2);
|
|
||||||
if (angle < 0) angle = angle + Math.PI * 2;
|
|
||||||
return angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int TruncateSignificant(float num, int digits)
|
|
||||||
{
|
|
||||||
return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits));
|
|
||||||
// return (int) ((num * (10*digits))/10*digits);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
|
|
||||||
// Also changed the original function from LSL_Types to LL types
|
|
||||||
private static Vector3 llRot2Euler(Quaternion r)
|
|
||||||
{
|
|
||||||
Quaternion t = new Quaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W);
|
|
||||||
double m = (t.X + t.Y + t.Z + t.W);
|
|
||||||
if (m == 0) return new Vector3();
|
|
||||||
double n = 2 * (r.Y * r.W + r.X * r.Z);
|
|
||||||
double p = m * m - n * n;
|
|
||||||
if (p > 0)
|
|
||||||
return new Vector3((float)NormalizeAngle(Math.Atan2(2.0 * (r.X * r.W - r.Y * r.Z), (-t.X - t.Y + t.Z + t.W))),
|
|
||||||
(float)NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))),
|
|
||||||
(float)NormalizeAngle(Math.Atan2(2.0 * (r.Z * r.W - r.X * r.Y), (t.X - t.Y - t.Z + t.W))));
|
|
||||||
else if (n > 0)
|
|
||||||
return new Vector3(0.0f, (float)(Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
|
|
||||||
else
|
|
||||||
return new Vector3(0.0f, (float)(-Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts
|
|
||||||
/// and returns a Diff bitmask which details what the differences are.
|
|
||||||
/// </summary>
|
|
||||||
public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second)
|
|
||||||
{
|
|
||||||
Stopwatch x = new Stopwatch();
|
|
||||||
x.Start();
|
|
||||||
|
|
||||||
Diff result = 0;
|
|
||||||
|
|
||||||
// VECTOR COMPARISONS
|
|
||||||
if (!AreVectorsEquivalent(first.Acceleration, second.Acceleration))
|
|
||||||
result |= Diff.ACCELERATION;
|
|
||||||
if (!AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition))
|
|
||||||
result |= Diff.POSITION;
|
|
||||||
if (!AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity))
|
|
||||||
result |= Diff.ANGULARVELOCITY;
|
|
||||||
if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition))
|
|
||||||
result |= Diff.OFFSETPOSITION;
|
|
||||||
if (!AreVectorsEquivalent(first.Scale, second.Scale))
|
|
||||||
result |= Diff.SCALE;
|
|
||||||
if (!AreVectorsEquivalent(first.Velocity, second.Velocity))
|
|
||||||
result |= Diff.VELOCITY;
|
|
||||||
|
|
||||||
|
|
||||||
// QUATERNION COMPARISONS
|
|
||||||
if (!AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset))
|
|
||||||
result |= Diff.ROTATIONOFFSET;
|
|
||||||
|
|
||||||
|
|
||||||
// MISC COMPARISONS (UUID, Byte)
|
|
||||||
if (first.ClickAction != second.ClickAction)
|
|
||||||
result |= Diff.CLICKACTION;
|
|
||||||
if (first.OwnerID != second.OwnerID)
|
|
||||||
result |= Diff.OBJECTOWNER;
|
|
||||||
|
|
||||||
|
|
||||||
// STRING COMPARISONS
|
|
||||||
if (first.Description != second.Description)
|
|
||||||
result |= Diff.DESCRIPTION;
|
|
||||||
if (first.Material != second.Material)
|
|
||||||
result |= Diff.MATERIAL;
|
|
||||||
if (first.Name != second.Name)
|
|
||||||
result |= Diff.NAME;
|
|
||||||
if (first.SitName != second.SitName)
|
|
||||||
result |= Diff.SITNAME;
|
|
||||||
if (first.Text != second.Text)
|
|
||||||
result |= Diff.TEXT;
|
|
||||||
if (first.TouchName != second.TouchName)
|
|
||||||
result |= Diff.TOUCHNAME;
|
|
||||||
|
|
||||||
x.Stop();
|
|
||||||
TimeToDiff += x.ElapsedMilliseconds;
|
|
||||||
//m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,10 +28,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Net;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
@ -50,6 +54,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
||||||
private bool m_lastOarLoadedOk;
|
private bool m_lastOarLoadedOk;
|
||||||
private int m_channelNotify = -1000;
|
private int m_channelNotify = -1000;
|
||||||
private bool m_enabled = false;
|
private bool m_enabled = false;
|
||||||
|
private bool m_disable_logins = false;
|
||||||
|
private string m_uri = string.Empty;
|
||||||
|
|
||||||
Scene m_scene = null;
|
Scene m_scene = null;
|
||||||
|
|
||||||
|
@ -68,10 +74,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
||||||
if (m_config != null)
|
if (m_config != null)
|
||||||
{
|
{
|
||||||
m_enabled = m_config.GetBoolean("enabled", false);
|
m_enabled = m_config.GetBoolean("enabled", false);
|
||||||
|
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify);
|
m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify);
|
||||||
}
|
m_disable_logins = m_config.GetBoolean("login_disable", false);
|
||||||
|
m_uri = m_config.GetString("alert_uri",string.Empty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!m_enabled)
|
// if (!m_enabled)
|
||||||
|
@ -91,8 +100,21 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
||||||
|
|
||||||
m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
|
m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
|
||||||
m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
|
m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
|
||||||
|
m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
|
||||||
|
|
||||||
m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName);
|
m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
if(m_disable_logins == true)
|
||||||
|
{
|
||||||
|
scene.LoginLock = true;
|
||||||
|
scene.LoginsDisabled = true;
|
||||||
|
m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
if(m_uri != string.Empty)
|
||||||
|
{
|
||||||
|
RRAlert("disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -150,7 +172,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
||||||
|
|
||||||
m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}",
|
m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}",
|
||||||
m_scene.RegionInfo.RegionName, c.Message, m_channelNotify);
|
m_scene.RegionInfo.RegionName, c.Message, m_channelNotify);
|
||||||
m_scene.EventManager.TriggerOnChatBroadcast(this, c);
|
|
||||||
|
m_scene.EventManager.TriggerOnChatBroadcast(this, c);
|
||||||
|
m_scene.EventManager.TriggerLoginsEnabled(m_scene.RegionInfo.RegionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,5 +189,69 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
||||||
m_lastOarLoadedOk = false;
|
m_lastOarLoadedOk = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnLoginsEnabled(string regionName)
|
||||||
|
{
|
||||||
|
if (m_disable_logins == true)
|
||||||
|
{
|
||||||
|
if (m_scene.StartDisabled == false)
|
||||||
|
{
|
||||||
|
m_scene.LoginsDisabled = false;
|
||||||
|
m_scene.LoginLock = false;
|
||||||
|
m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName);
|
||||||
|
if ( m_uri != string.Empty )
|
||||||
|
{
|
||||||
|
RRAlert("enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RRAlert(string status)
|
||||||
|
{
|
||||||
|
string request_method = "POST";
|
||||||
|
string content_type = "application/json";
|
||||||
|
OSDMap RRAlert = new OSDMap();
|
||||||
|
|
||||||
|
RRAlert["alert"] = "region_ready";
|
||||||
|
RRAlert["login"] = status;
|
||||||
|
RRAlert["region_name"] = m_scene.RegionInfo.RegionName;
|
||||||
|
RRAlert["region_id"] = m_scene.RegionInfo.RegionID;
|
||||||
|
|
||||||
|
string strBuffer = "";
|
||||||
|
byte[] buffer = new byte[1];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
strBuffer = OSDParser.SerializeJsonString(RRAlert);
|
||||||
|
Encoding str = Util.UTF8;
|
||||||
|
buffer = str.GetBytes(strBuffer);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[RegionReady]: Exception thrown on alert: {0}", e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRequest request = WebRequest.Create(m_uri);
|
||||||
|
request.Method = request_method;
|
||||||
|
request.ContentType = content_type;
|
||||||
|
|
||||||
|
Stream os = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
request.ContentLength = buffer.Length;
|
||||||
|
os = request.GetRequestStream();
|
||||||
|
os.Write(buffer, 0, strBuffer.Length);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[RegionReady]: Exception thrown sending alert: {0}", e.Message);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (os != null)
|
||||||
|
os.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -631,7 +631,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
|
public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,12 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
|
|
||||||
public abstract PrimitiveBaseShape Shape { set; }
|
public abstract PrimitiveBaseShape Shape { set; }
|
||||||
|
|
||||||
public abstract uint LocalID { set; }
|
uint m_baseLocalID;
|
||||||
|
public virtual uint LocalID
|
||||||
|
{
|
||||||
|
set { m_baseLocalID = value; }
|
||||||
|
get { return m_baseLocalID; }
|
||||||
|
}
|
||||||
|
|
||||||
public abstract bool Grabbed { set; }
|
public abstract bool Grabbed { set; }
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,13 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
|
|
||||||
public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying);
|
public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying);
|
||||||
|
|
||||||
|
public virtual PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying)
|
||||||
|
{
|
||||||
|
PhysicsActor ret = AddAvatar(avName, position, size, isFlying);
|
||||||
|
if (ret != null) ret.LocalID = localID;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void RemoveAvatar(PhysicsActor actor);
|
public abstract void RemoveAvatar(PhysicsActor actor);
|
||||||
|
|
||||||
public abstract void RemovePrim(PhysicsActor prim);
|
public abstract void RemovePrim(PhysicsActor prim);
|
||||||
|
@ -75,6 +82,14 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||||
Vector3 size, Quaternion rotation, bool isPhysical);
|
Vector3 size, Quaternion rotation, bool isPhysical);
|
||||||
|
|
||||||
|
public virtual PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||||
|
Vector3 size, Quaternion rotation, bool isPhysical)
|
||||||
|
{
|
||||||
|
PhysicsActor ret = AddPrimShape(primName, pbs, position, size, rotation, isPhysical);
|
||||||
|
if (ret != null) ret.LocalID = localID;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual float TimeDilation
|
public virtual float TimeDilation
|
||||||
{
|
{
|
||||||
get { return 1.0f; }
|
get { return 1.0f; }
|
||||||
|
|
|
@ -303,7 +303,11 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
if (meshOsd is OSDMap)
|
if (meshOsd is OSDMap)
|
||||||
{
|
{
|
||||||
OSDMap map = (OSDMap)meshOsd;
|
OSDMap map = (OSDMap)meshOsd;
|
||||||
OSDMap physicsParms = (OSDMap)map["physics_shape"];
|
OSDMap physicsParms = (OSDMap)map["physics_shape"]; // old asset format
|
||||||
|
|
||||||
|
if (physicsParms.Count == 0)
|
||||||
|
physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
|
||||||
|
|
||||||
int physOffset = physicsParms["offset"].AsInteger() + (int)start;
|
int physOffset = physicsParms["offset"].AsInteger() + (int)start;
|
||||||
int physSize = physicsParms["size"].AsInteger();
|
int physSize = physicsParms["size"].AsInteger();
|
||||||
|
|
||||||
|
|
|
@ -309,7 +309,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||||
// In attachments, the sensor cone always orients with the
|
// In attachments, the sensor cone always orients with the
|
||||||
// avatar rotation. This may include a nonzero elevation if
|
// avatar rotation. This may include a nonzero elevation if
|
||||||
// in mouselook.
|
// in mouselook.
|
||||||
|
|
||||||
ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
|
ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
|
||||||
fromRegionPos = avatar.AbsolutePosition;
|
fromRegionPos = avatar.AbsolutePosition;
|
||||||
q = avatar.Rotation;
|
q = avatar.Rotation;
|
||||||
|
@ -424,6 +423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||||
|
|
||||||
SceneObjectPart SensePoint = ts.host;
|
SceneObjectPart SensePoint = ts.host;
|
||||||
Vector3 fromRegionPos = SensePoint.AbsolutePosition;
|
Vector3 fromRegionPos = SensePoint.AbsolutePosition;
|
||||||
|
|
||||||
Quaternion q = SensePoint.RotationOffset;
|
Quaternion q = SensePoint.RotationOffset;
|
||||||
if (SensePoint.ParentGroup.RootPart.IsAttachment)
|
if (SensePoint.ParentGroup.RootPart.IsAttachment)
|
||||||
{
|
{
|
||||||
|
@ -435,6 +435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||||
fromRegionPos = avatar.AbsolutePosition;
|
fromRegionPos = avatar.AbsolutePosition;
|
||||||
q = avatar.Rotation;
|
q = avatar.Rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
|
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
|
||||||
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
|
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
|
||||||
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
|
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
|
||||||
|
|
|
@ -65,6 +65,10 @@ namespace OpenSim.Server.Base
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static T LoadPlugin<T>(string dllName, Object[] args) where T:class
|
public static T LoadPlugin<T>(string dllName, Object[] args) where T:class
|
||||||
{
|
{
|
||||||
|
// This is good to debug configuration problems
|
||||||
|
//if (dllName == string.Empty)
|
||||||
|
// Util.PrintCallStack();
|
||||||
|
|
||||||
string[] parts = dllName.Split(new char[] {':'});
|
string[] parts = dllName.Split(new char[] {':'});
|
||||||
|
|
||||||
dllName = parts[0];
|
dllName = parts[0];
|
||||||
|
@ -124,6 +128,13 @@ namespace OpenSim.Server.Base
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
catch (ReflectionTypeLoadException rtle)
|
||||||
|
{
|
||||||
|
m_log.Error(string.Format("Error loading plugin from {0}:\n{1}", dllName,
|
||||||
|
String.Join("\n", Array.ConvertAll(rtle.LoaderExceptions, e => e.ToString()))),
|
||||||
|
rtle);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(string.Format("Error loading plugin from {0}", dllName), e);
|
m_log.Error(string.Format("Error loading plugin from {0}", dllName), e);
|
||||||
|
|
|
@ -46,14 +46,14 @@ namespace OpenSim.Server.Handlers.Friends
|
||||||
if (serverConfig == null)
|
if (serverConfig == null)
|
||||||
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
|
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
|
||||||
|
|
||||||
string gridService = serverConfig.GetString("LocalServiceModule",
|
string theService = serverConfig.GetString("LocalServiceModule",
|
||||||
String.Empty);
|
String.Empty);
|
||||||
|
|
||||||
if (gridService == String.Empty)
|
if (theService == String.Empty)
|
||||||
throw new Exception("No LocalServiceModule in config file");
|
throw new Exception("No LocalServiceModule in config file");
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
Object[] args = new Object[] { config };
|
||||||
m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(gridService, args);
|
m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
|
||||||
|
|
||||||
server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService));
|
server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService));
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,12 +82,18 @@ namespace OpenSim.Server.Handlers.Friends
|
||||||
case "getfriends":
|
case "getfriends":
|
||||||
return GetFriends(request);
|
return GetFriends(request);
|
||||||
|
|
||||||
|
case "getfriends_string":
|
||||||
|
return GetFriendsString(request);
|
||||||
|
|
||||||
case "storefriend":
|
case "storefriend":
|
||||||
return StoreFriend(request);
|
return StoreFriend(request);
|
||||||
|
|
||||||
case "deletefriend":
|
case "deletefriend":
|
||||||
return DeleteFriend(request);
|
return DeleteFriend(request);
|
||||||
|
|
||||||
|
case "deletefriend_string":
|
||||||
|
return DeleteFriendString(request);
|
||||||
|
|
||||||
}
|
}
|
||||||
m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
|
m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +117,25 @@ namespace OpenSim.Server.Handlers.Friends
|
||||||
m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
|
m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
|
||||||
|
|
||||||
FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
|
FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
|
||||||
//m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count);
|
|
||||||
|
return PackageFriends(finfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] GetFriendsString(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
string principalID = string.Empty;
|
||||||
|
if (request.ContainsKey("PRINCIPALID"))
|
||||||
|
principalID = request["PRINCIPALID"].ToString();
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
|
||||||
|
|
||||||
|
FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
|
||||||
|
|
||||||
|
return PackageFriends(finfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] PackageFriends(FriendInfo[] finfos)
|
||||||
|
{
|
||||||
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||||
if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
|
if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
|
||||||
|
@ -136,9 +160,9 @@ namespace OpenSim.Server.Handlers.Friends
|
||||||
|
|
||||||
byte[] StoreFriend(Dictionary<string, object> request)
|
byte[] StoreFriend(Dictionary<string, object> request)
|
||||||
{
|
{
|
||||||
FriendInfo friend = new FriendInfo(request);
|
string principalID = string.Empty, friend = string.Empty; int flags = 0;
|
||||||
|
FromKeyValuePairs(request, out principalID, out friend, out flags);
|
||||||
bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.MyFlags);
|
bool success = m_FriendsService.StoreFriend(principalID, friend, flags);
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
return SuccessResult();
|
return SuccessResult();
|
||||||
|
@ -163,7 +187,25 @@ namespace OpenSim.Server.Handlers.Friends
|
||||||
else
|
else
|
||||||
return FailureResult();
|
return FailureResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] DeleteFriendString(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
string principalID = string.Empty;
|
||||||
|
if (request.ContainsKey("PRINCIPALID"))
|
||||||
|
principalID = request["PRINCIPALID"].ToString();
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to delete friend");
|
||||||
|
string friend = string.Empty;
|
||||||
|
if (request.ContainsKey("FRIEND"))
|
||||||
|
friend = request["FRIEND"].ToString();
|
||||||
|
|
||||||
|
bool success = m_FriendsService.Delete(principalID, friend);
|
||||||
|
if (success)
|
||||||
|
return SuccessResult();
|
||||||
|
else
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Misc
|
#region Misc
|
||||||
|
@ -233,6 +275,19 @@ namespace OpenSim.Server.Handlers.Friends
|
||||||
return ms.ToArray();
|
return ms.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FromKeyValuePairs(Dictionary<string, object> kvp, out string principalID, out string friend, out int flags)
|
||||||
|
{
|
||||||
|
principalID = string.Empty;
|
||||||
|
if (kvp.ContainsKey("PrincipalID") && kvp["PrincipalID"] != null)
|
||||||
|
principalID = kvp["PrincipalID"].ToString();
|
||||||
|
friend = string.Empty;
|
||||||
|
if (kvp.ContainsKey("Friend") && kvp["Friend"] != null)
|
||||||
|
friend = kvp["Friend"].ToString();
|
||||||
|
flags = 0;
|
||||||
|
if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null)
|
||||||
|
Int32.TryParse(kvp["MyFlags"].ToString(), out flags);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* 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 Nini.Config;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
|
||||||
|
namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
|
{
|
||||||
|
public class HGFriendsServerConnector : ServiceConnector
|
||||||
|
{
|
||||||
|
private IFriendsService m_FriendsService;
|
||||||
|
private IUserAgentService m_UserAgentService;
|
||||||
|
private string m_ConfigName = "HGFriendsService";
|
||||||
|
|
||||||
|
public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
|
base(config, server, configName)
|
||||||
|
{
|
||||||
|
if (configName != string.Empty)
|
||||||
|
m_ConfigName = configName;
|
||||||
|
|
||||||
|
IConfig serverConfig = config.Configs[m_ConfigName];
|
||||||
|
if (serverConfig == null)
|
||||||
|
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
|
||||||
|
|
||||||
|
string theService = serverConfig.GetString("LocalServiceModule",
|
||||||
|
String.Empty);
|
||||||
|
|
||||||
|
if (theService == String.Empty)
|
||||||
|
throw new Exception("No LocalServiceModule in config file");
|
||||||
|
|
||||||
|
Object[] args = new Object[] { config };
|
||||||
|
m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
|
||||||
|
|
||||||
|
theService = serverConfig.GetString("UserAgentService", string.Empty);
|
||||||
|
if (theService == String.Empty)
|
||||||
|
throw new Exception("No UserAgentService in " + m_ConfigName);
|
||||||
|
|
||||||
|
m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(theService, args);
|
||||||
|
|
||||||
|
server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,320 @@
|
||||||
|
/*
|
||||||
|
* 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 Nini.Config;
|
||||||
|
using log4net;
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
|
{
|
||||||
|
public class HGFriendsServerPostHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IFriendsService m_FriendsService;
|
||||||
|
private IUserAgentService m_UserAgentService;
|
||||||
|
|
||||||
|
public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) :
|
||||||
|
base("POST", "/hgfriends")
|
||||||
|
{
|
||||||
|
m_FriendsService = service;
|
||||||
|
m_UserAgentService = uservice;
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream requestData,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
StreamReader sr = new StreamReader(requestData);
|
||||||
|
string body = sr.ReadToEnd();
|
||||||
|
sr.Close();
|
||||||
|
body = body.Trim();
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Dictionary<string, object> request =
|
||||||
|
ServerUtils.ParseQueryString(body);
|
||||||
|
|
||||||
|
if (!request.ContainsKey("METHOD"))
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
string method = request["METHOD"].ToString();
|
||||||
|
|
||||||
|
switch (method)
|
||||||
|
{
|
||||||
|
case "getfriendperms":
|
||||||
|
return GetFriendPerms(request);
|
||||||
|
|
||||||
|
case "newfriendship":
|
||||||
|
return NewFriendship(request);
|
||||||
|
|
||||||
|
case "deletefriendship":
|
||||||
|
return DeleteFriendship(request);
|
||||||
|
}
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Method-specific handlers
|
||||||
|
|
||||||
|
byte[] GetFriendPerms(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
if (!VerifyServiceKey(request))
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
UUID principalID = UUID.Zero;
|
||||||
|
if (request.ContainsKey("PRINCIPALID"))
|
||||||
|
UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friend perms");
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID friendID = UUID.Zero;
|
||||||
|
if (request.ContainsKey("FRIENDID"))
|
||||||
|
UUID.TryParse(request["FRIENDID"].ToString(), out friendID);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[HGFRIENDS HANDLER]: no friendID in request to get friend perms");
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
string perms = "0";
|
||||||
|
FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID);
|
||||||
|
foreach (FriendInfo finfo in friendsInfo)
|
||||||
|
{
|
||||||
|
if (finfo.Friend.StartsWith(friendID.ToString()))
|
||||||
|
return SuccessResult(finfo.TheirFlags.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return FailureResult("Friend not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] NewFriendship(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
if (!VerifyServiceKey(request))
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
// OK, can proceed
|
||||||
|
FriendInfo friend = new FriendInfo(request);
|
||||||
|
UUID friendID;
|
||||||
|
string tmp = string.Empty;
|
||||||
|
if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend);
|
||||||
|
|
||||||
|
// If the friendship already exists, return fail
|
||||||
|
FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
|
||||||
|
foreach (FriendInfo finfo in finfos)
|
||||||
|
if (finfo.Friend.StartsWith(friendID.ToString()))
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
// the user needs to confirm when he gets home
|
||||||
|
bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
return SuccessResult();
|
||||||
|
else
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] DeleteFriendship(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
FriendInfo friend = new FriendInfo(request);
|
||||||
|
string secret = string.Empty;
|
||||||
|
if (request.ContainsKey("SECRET"))
|
||||||
|
secret = request["SECRET"].ToString();
|
||||||
|
|
||||||
|
if (secret == string.Empty)
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
|
||||||
|
foreach (FriendInfo finfo in finfos)
|
||||||
|
{
|
||||||
|
// We check the secret here
|
||||||
|
if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
|
||||||
|
m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
|
||||||
|
m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
|
||||||
|
|
||||||
|
return SuccessResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Misc
|
||||||
|
|
||||||
|
private bool VerifyServiceKey(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string serviceKey = request["KEY"].ToString();
|
||||||
|
string sessionStr = request["SESSIONID"].ToString();
|
||||||
|
UUID sessionID;
|
||||||
|
UUID.TryParse(sessionStr, out sessionID);
|
||||||
|
|
||||||
|
if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: Verification ok");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] SuccessResult()
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||||
|
"", "");
|
||||||
|
|
||||||
|
doc.AppendChild(xmlnode);
|
||||||
|
|
||||||
|
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
|
||||||
|
"");
|
||||||
|
|
||||||
|
doc.AppendChild(rootElement);
|
||||||
|
|
||||||
|
XmlElement result = doc.CreateElement("", "Result", "");
|
||||||
|
result.AppendChild(doc.CreateTextNode("Success"));
|
||||||
|
|
||||||
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] SuccessResult(string value)
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||||
|
"", "");
|
||||||
|
|
||||||
|
doc.AppendChild(xmlnode);
|
||||||
|
|
||||||
|
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
|
||||||
|
"");
|
||||||
|
|
||||||
|
doc.AppendChild(rootElement);
|
||||||
|
|
||||||
|
XmlElement result = doc.CreateElement("", "Result", "");
|
||||||
|
result.AppendChild(doc.CreateTextNode("Success"));
|
||||||
|
|
||||||
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
|
XmlElement message = doc.CreateElement("", "Value", "");
|
||||||
|
message.AppendChild(doc.CreateTextNode(value));
|
||||||
|
|
||||||
|
rootElement.AppendChild(message);
|
||||||
|
|
||||||
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private byte[] FailureResult()
|
||||||
|
{
|
||||||
|
return FailureResult(String.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] FailureResult(string msg)
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||||
|
"", "");
|
||||||
|
|
||||||
|
doc.AppendChild(xmlnode);
|
||||||
|
|
||||||
|
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
|
||||||
|
"");
|
||||||
|
|
||||||
|
doc.AppendChild(rootElement);
|
||||||
|
|
||||||
|
XmlElement result = doc.CreateElement("", "Result", "");
|
||||||
|
result.AppendChild(doc.CreateTextNode("Failure"));
|
||||||
|
|
||||||
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
|
XmlElement message = doc.CreateElement("", "Message", "");
|
||||||
|
message.AppendChild(doc.CreateTextNode(msg));
|
||||||
|
|
||||||
|
rootElement.AppendChild(message);
|
||||||
|
|
||||||
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] DocToBytes(XmlDocument doc)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||||
|
xw.Formatting = Formatting.Indented;
|
||||||
|
doc.WriteTo(xw);
|
||||||
|
xw.Flush();
|
||||||
|
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
|
||||||
|
using log4net;
|
||||||
|
using Nwc.XmlRpc;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
|
{
|
||||||
|
public class InstantMessageServerConnector : ServiceConnector
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(
|
||||||
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IInstantMessage m_IMService;
|
||||||
|
|
||||||
|
public InstantMessageServerConnector(IConfigSource config, IHttpServer server) :
|
||||||
|
this(config, server, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstantMessageServerConnector(IConfigSource config, IHttpServer server, IInstantMessageSimConnector simConnector) :
|
||||||
|
base(config, server, String.Empty)
|
||||||
|
{
|
||||||
|
IConfig gridConfig = config.Configs["HGInstantMessageService"];
|
||||||
|
if (gridConfig != null)
|
||||||
|
{
|
||||||
|
string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
|
||||||
|
|
||||||
|
Object[] args = new Object[] { config, simConnector };
|
||||||
|
m_IMService = ServerUtils.LoadPlugin<IInstantMessage>(serviceDll, args);
|
||||||
|
}
|
||||||
|
if (m_IMService == null)
|
||||||
|
throw new Exception("InstantMessage server connector cannot proceed because of missing service");
|
||||||
|
|
||||||
|
server.AddXmlRPCHandler("grid_instant_message", ProcessInstantMessage, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public IInstantMessage GetService()
|
||||||
|
{
|
||||||
|
return m_IMService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual XmlRpcResponse ProcessInstantMessage(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||||
|
{
|
||||||
|
bool successful = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// various rational defaults
|
||||||
|
UUID fromAgentID = UUID.Zero;
|
||||||
|
UUID toAgentID = UUID.Zero;
|
||||||
|
UUID imSessionID = UUID.Zero;
|
||||||
|
uint timestamp = 0;
|
||||||
|
string fromAgentName = "";
|
||||||
|
string message = "";
|
||||||
|
byte dialog = (byte)0;
|
||||||
|
bool fromGroup = false;
|
||||||
|
byte offline = (byte)0;
|
||||||
|
uint ParentEstateID = 0;
|
||||||
|
Vector3 Position = Vector3.Zero;
|
||||||
|
UUID RegionID = UUID.Zero;
|
||||||
|
byte[] binaryBucket = new byte[0];
|
||||||
|
|
||||||
|
float pos_x = 0;
|
||||||
|
float pos_y = 0;
|
||||||
|
float pos_z = 0;
|
||||||
|
//m_log.Info("Processing IM");
|
||||||
|
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
|
// Check if it's got all the data
|
||||||
|
if (requestData.ContainsKey("from_agent_id")
|
||||||
|
&& requestData.ContainsKey("to_agent_id") && requestData.ContainsKey("im_session_id")
|
||||||
|
&& requestData.ContainsKey("timestamp") && requestData.ContainsKey("from_agent_name")
|
||||||
|
&& requestData.ContainsKey("message") && requestData.ContainsKey("dialog")
|
||||||
|
&& requestData.ContainsKey("from_group")
|
||||||
|
&& requestData.ContainsKey("offline") && requestData.ContainsKey("parent_estate_id")
|
||||||
|
&& requestData.ContainsKey("position_x") && requestData.ContainsKey("position_y")
|
||||||
|
&& requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
|
||||||
|
&& requestData.ContainsKey("binary_bucket"))
|
||||||
|
{
|
||||||
|
// Do the easy way of validating the UUIDs
|
||||||
|
UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
|
||||||
|
UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
|
||||||
|
UUID.TryParse((string)requestData["im_session_id"], out imSessionID);
|
||||||
|
UUID.TryParse((string)requestData["region_id"], out RegionID);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
timestamp = (uint)Convert.ToInt32((string)requestData["timestamp"]);
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (OverflowException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fromAgentName = (string)requestData["from_agent_name"];
|
||||||
|
message = (string)requestData["message"];
|
||||||
|
if (message == null)
|
||||||
|
message = string.Empty;
|
||||||
|
|
||||||
|
// Bytes don't transfer well over XMLRPC, so, we Base64 Encode them.
|
||||||
|
string requestData1 = (string)requestData["dialog"];
|
||||||
|
if (string.IsNullOrEmpty(requestData1))
|
||||||
|
{
|
||||||
|
dialog = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] dialogdata = Convert.FromBase64String(requestData1);
|
||||||
|
dialog = dialogdata[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((string)requestData["from_group"] == "TRUE")
|
||||||
|
fromGroup = true;
|
||||||
|
|
||||||
|
string requestData2 = (string)requestData["offline"];
|
||||||
|
if (String.IsNullOrEmpty(requestData2))
|
||||||
|
{
|
||||||
|
offline = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] offlinedata = Convert.FromBase64String(requestData2);
|
||||||
|
offline = offlinedata[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ParentEstateID = (uint)Convert.ToInt32((string)requestData["parent_estate_id"]);
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch (OverflowException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float.TryParse((string)requestData["position_x"], out pos_x);
|
||||||
|
float.TryParse((string)requestData["position_y"], out pos_y);
|
||||||
|
float.TryParse((string)requestData["position_z"], out pos_z);
|
||||||
|
|
||||||
|
Position = new Vector3(pos_x, pos_y, pos_z);
|
||||||
|
|
||||||
|
string requestData3 = (string)requestData["binary_bucket"];
|
||||||
|
if (string.IsNullOrEmpty(requestData3))
|
||||||
|
{
|
||||||
|
binaryBucket = new byte[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
binaryBucket = Convert.FromBase64String(requestData3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a New GridInstantMessageObject the the data
|
||||||
|
GridInstantMessage gim = new GridInstantMessage();
|
||||||
|
gim.fromAgentID = fromAgentID.Guid;
|
||||||
|
gim.fromAgentName = fromAgentName;
|
||||||
|
gim.fromGroup = fromGroup;
|
||||||
|
gim.imSessionID = imSessionID.Guid;
|
||||||
|
gim.RegionID = RegionID.Guid;
|
||||||
|
gim.timestamp = timestamp;
|
||||||
|
gim.toAgentID = toAgentID.Guid;
|
||||||
|
gim.message = message;
|
||||||
|
gim.dialog = dialog;
|
||||||
|
gim.offline = offline;
|
||||||
|
gim.ParentEstateID = ParentEstateID;
|
||||||
|
gim.Position = Position;
|
||||||
|
gim.binaryBucket = binaryBucket;
|
||||||
|
|
||||||
|
successful = m_IMService.IncomingInstantMessage(gim);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error("[INSTANT MESSAGE]: Caught unexpected exception:", e);
|
||||||
|
successful = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send response back to region calling if it was successful
|
||||||
|
// calling region uses this to know when to look up a user's location again.
|
||||||
|
XmlRpcResponse resp = new XmlRpcResponse();
|
||||||
|
Hashtable respdata = new Hashtable();
|
||||||
|
if (successful)
|
||||||
|
respdata["success"] = "TRUE";
|
||||||
|
else
|
||||||
|
respdata["success"] = "FALSE";
|
||||||
|
resp.Value = respdata;
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,15 +52,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private IUserAgentService m_HomeUsersService;
|
private IUserAgentService m_HomeUsersService;
|
||||||
|
private string[] m_AuthorizedCallers;
|
||||||
|
|
||||||
|
private bool m_VerifyCallers = false;
|
||||||
|
|
||||||
public UserAgentServerConnector(IConfigSource config, IHttpServer server) :
|
public UserAgentServerConnector(IConfigSource config, IHttpServer server) :
|
||||||
|
this(config, server, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAgentServerConnector(IConfigSource config, IHttpServer server, IFriendsSimConnector friendsConnector) :
|
||||||
base(config, server, String.Empty)
|
base(config, server, String.Empty)
|
||||||
{
|
{
|
||||||
IConfig gridConfig = config.Configs["UserAgentService"];
|
IConfig gridConfig = config.Configs["UserAgentService"];
|
||||||
if (gridConfig != null)
|
if (gridConfig != null)
|
||||||
{
|
{
|
||||||
string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
|
string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
|
||||||
Object[] args = new Object[] { config };
|
|
||||||
|
Object[] args = new Object[] { config, friendsConnector };
|
||||||
m_HomeUsersService = ServerUtils.LoadPlugin<IUserAgentService>(serviceDll, args);
|
m_HomeUsersService = ServerUtils.LoadPlugin<IUserAgentService>(serviceDll, args);
|
||||||
}
|
}
|
||||||
if (m_HomeUsersService == null)
|
if (m_HomeUsersService == null)
|
||||||
|
@ -69,12 +78,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1");
|
string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1");
|
||||||
bool proxy = gridConfig.GetBoolean("HasProxy", false);
|
bool proxy = gridConfig.GetBoolean("HasProxy", false);
|
||||||
|
|
||||||
|
m_VerifyCallers = gridConfig.GetBoolean("VerifyCallers", false);
|
||||||
|
string csv = gridConfig.GetString("AuthorizedCallers", "127.0.0.1");
|
||||||
|
csv = csv.Replace(" ", "");
|
||||||
|
m_AuthorizedCallers = csv.Split(',');
|
||||||
|
|
||||||
server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false);
|
server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false);
|
||||||
server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false);
|
server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false);
|
||||||
server.AddXmlRPCHandler("verify_agent", VerifyAgent, false);
|
server.AddXmlRPCHandler("verify_agent", VerifyAgent, false);
|
||||||
server.AddXmlRPCHandler("verify_client", VerifyClient, false);
|
server.AddXmlRPCHandler("verify_client", VerifyClient, false);
|
||||||
server.AddXmlRPCHandler("logout_agent", LogoutAgent, false);
|
server.AddXmlRPCHandler("logout_agent", LogoutAgent, false);
|
||||||
|
|
||||||
|
server.AddXmlRPCHandler("status_notification", StatusNotification, false);
|
||||||
|
server.AddXmlRPCHandler("get_online_friends", GetOnlineFriends, false);
|
||||||
|
server.AddXmlRPCHandler("get_server_urls", GetServerURLs, false);
|
||||||
|
|
||||||
|
server.AddXmlRPCHandler("locate_user", LocateUser, false);
|
||||||
|
server.AddXmlRPCHandler("get_uui", GetUUI, false);
|
||||||
|
|
||||||
server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler);
|
server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,5 +215,201 @@ namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public XmlRpcResponse StatusNotification(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||||
|
{
|
||||||
|
Hashtable hash = new Hashtable();
|
||||||
|
hash["result"] = "false";
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
|
//string host = (string)requestData["host"];
|
||||||
|
//string portstr = (string)requestData["port"];
|
||||||
|
if (requestData.ContainsKey("userID") && requestData.ContainsKey("online"))
|
||||||
|
{
|
||||||
|
string userID_str = (string)requestData["userID"];
|
||||||
|
UUID userID = UUID.Zero;
|
||||||
|
UUID.TryParse(userID_str, out userID);
|
||||||
|
List<string> ids = new List<string>();
|
||||||
|
foreach (object key in requestData.Keys)
|
||||||
|
{
|
||||||
|
if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null)
|
||||||
|
ids.Add(requestData[key].ToString());
|
||||||
|
}
|
||||||
|
bool online = false;
|
||||||
|
bool.TryParse(requestData["online"].ToString(), out online);
|
||||||
|
|
||||||
|
// let's spawn a thread for this, because it may take a long time...
|
||||||
|
List<UUID> friendsOnline = m_HomeUsersService.StatusNotification(ids, userID, online);
|
||||||
|
if (friendsOnline.Count > 0)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
foreach (UUID id in friendsOnline)
|
||||||
|
{
|
||||||
|
hash["friend_" + i.ToString()] = id.ToString();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hash["result"] = "No Friends Online";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
response.Value = hash;
|
||||||
|
return response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlRpcResponse GetOnlineFriends(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||||
|
{
|
||||||
|
Hashtable hash = new Hashtable();
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
|
//string host = (string)requestData["host"];
|
||||||
|
//string portstr = (string)requestData["port"];
|
||||||
|
if (requestData.ContainsKey("userID"))
|
||||||
|
{
|
||||||
|
string userID_str = (string)requestData["userID"];
|
||||||
|
UUID userID = UUID.Zero;
|
||||||
|
UUID.TryParse(userID_str, out userID);
|
||||||
|
List<string> ids = new List<string>();
|
||||||
|
foreach (object key in requestData.Keys)
|
||||||
|
{
|
||||||
|
if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null)
|
||||||
|
ids.Add(requestData[key].ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
//List<UUID> online = m_HomeUsersService.GetOnlineFriends(userID, ids);
|
||||||
|
//if (online.Count > 0)
|
||||||
|
//{
|
||||||
|
// int i = 0;
|
||||||
|
// foreach (UUID id in online)
|
||||||
|
// {
|
||||||
|
// hash["friend_" + i.ToString()] = id.ToString();
|
||||||
|
// i++;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
// hash["result"] = "No Friends Online";
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
response.Value = hash;
|
||||||
|
return response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlRpcResponse GetServerURLs(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||||
|
{
|
||||||
|
Hashtable hash = new Hashtable();
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
|
//string host = (string)requestData["host"];
|
||||||
|
//string portstr = (string)requestData["port"];
|
||||||
|
if (requestData.ContainsKey("userID"))
|
||||||
|
{
|
||||||
|
string userID_str = (string)requestData["userID"];
|
||||||
|
UUID userID = UUID.Zero;
|
||||||
|
UUID.TryParse(userID_str, out userID);
|
||||||
|
|
||||||
|
Dictionary<string, object> serverURLs = m_HomeUsersService.GetServerURLs(userID);
|
||||||
|
if (serverURLs.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, object> kvp in serverURLs)
|
||||||
|
hash["SRV_" + kvp.Key] = kvp.Value.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hash["result"] = "No Service URLs";
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
response.Value = hash;
|
||||||
|
return response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Locates the user.
|
||||||
|
/// This is a sensitive operation, only authorized IP addresses can perform it.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="remoteClient"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public XmlRpcResponse LocateUser(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||||
|
{
|
||||||
|
Hashtable hash = new Hashtable();
|
||||||
|
|
||||||
|
bool authorized = true;
|
||||||
|
if (m_VerifyCallers)
|
||||||
|
{
|
||||||
|
authorized = false;
|
||||||
|
foreach (string s in m_AuthorizedCallers)
|
||||||
|
if (s == remoteClient.Address.ToString())
|
||||||
|
{
|
||||||
|
authorized = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authorized)
|
||||||
|
{
|
||||||
|
Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
|
//string host = (string)requestData["host"];
|
||||||
|
//string portstr = (string)requestData["port"];
|
||||||
|
if (requestData.ContainsKey("userID"))
|
||||||
|
{
|
||||||
|
string userID_str = (string)requestData["userID"];
|
||||||
|
UUID userID = UUID.Zero;
|
||||||
|
UUID.TryParse(userID_str, out userID);
|
||||||
|
|
||||||
|
string url = m_HomeUsersService.LocateUser(userID);
|
||||||
|
if (url != string.Empty)
|
||||||
|
hash["URL"] = url;
|
||||||
|
else
|
||||||
|
hash["result"] = "Unable to locate user";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
response.Value = hash;
|
||||||
|
return response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Locates the user.
|
||||||
|
/// This is a sensitive operation, only authorized IP addresses can perform it.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="remoteClient"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public XmlRpcResponse GetUUI(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||||
|
{
|
||||||
|
Hashtable hash = new Hashtable();
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
|
//string host = (string)requestData["host"];
|
||||||
|
//string portstr = (string)requestData["port"];
|
||||||
|
if (requestData.ContainsKey("userID") && requestData.ContainsKey("targetUserID"))
|
||||||
|
{
|
||||||
|
string userID_str = (string)requestData["userID"];
|
||||||
|
UUID userID = UUID.Zero;
|
||||||
|
UUID.TryParse(userID_str, out userID);
|
||||||
|
|
||||||
|
string tuserID_str = (string)requestData["targetUserID"];
|
||||||
|
UUID targetUserID = UUID.Zero;
|
||||||
|
UUID.TryParse(tuserID_str, out targetUserID);
|
||||||
|
string uui = m_HomeUsersService.GetUUI(userID, targetUserID);
|
||||||
|
if (uui != string.Empty)
|
||||||
|
hash["UUI"] = uui;
|
||||||
|
else
|
||||||
|
hash["result"] = "User unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
response.Value = hash;
|
||||||
|
return response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
* 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.Reflection;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
using Nini.Config;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
|
||||||
|
namespace OpenSim.Server.Handlers.MapImage
|
||||||
|
{
|
||||||
|
public class MapAddServiceConnector : ServiceConnector
|
||||||
|
{
|
||||||
|
private IMapImageService m_MapService;
|
||||||
|
private string m_ConfigName = "MapImageService";
|
||||||
|
|
||||||
|
public MapAddServiceConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
|
base(config, server, configName)
|
||||||
|
{
|
||||||
|
IConfig serverConfig = config.Configs[m_ConfigName];
|
||||||
|
if (serverConfig == null)
|
||||||
|
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
|
||||||
|
|
||||||
|
string gridService = serverConfig.GetString("LocalServiceModule",
|
||||||
|
String.Empty);
|
||||||
|
|
||||||
|
if (gridService == String.Empty)
|
||||||
|
throw new Exception("No LocalServiceModule in config file");
|
||||||
|
|
||||||
|
Object[] args = new Object[] { config };
|
||||||
|
m_MapService = ServerUtils.LoadPlugin<IMapImageService>(gridService, args);
|
||||||
|
|
||||||
|
server.AddStreamHandler(new MapServerPostHandler(m_MapService));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MapServerPostHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private IMapImageService m_MapService;
|
||||||
|
|
||||||
|
public MapServerPostHandler(IMapImageService service) :
|
||||||
|
base("POST", "/map")
|
||||||
|
{
|
||||||
|
m_MapService = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream requestData, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path);
|
||||||
|
StreamReader sr = new StreamReader(requestData);
|
||||||
|
string body = sr.ReadToEnd();
|
||||||
|
sr.Close();
|
||||||
|
body = body.Trim();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Dictionary<string, object> request = ServerUtils.ParseQueryString(body);
|
||||||
|
|
||||||
|
if (!request.ContainsKey("X") || !request.ContainsKey("Y") || !request.ContainsKey("DATA"))
|
||||||
|
{
|
||||||
|
httpResponse.StatusCode = (int)OSHttpStatusCode.ClientErrorBadRequest;
|
||||||
|
return FailureResult("Bad request.");
|
||||||
|
}
|
||||||
|
int x = 0, y = 0;
|
||||||
|
Int32.TryParse(request["X"].ToString(), out x);
|
||||||
|
Int32.TryParse(request["Y"].ToString(), out y);
|
||||||
|
string type = "image/jpeg";
|
||||||
|
if (request.ContainsKey("TYPE"))
|
||||||
|
type = request["TYPE"].ToString();
|
||||||
|
byte[] data = Convert.FromBase64String(request["DATA"].ToString());
|
||||||
|
|
||||||
|
string reason = string.Empty;
|
||||||
|
bool result = m_MapService.AddMapTile(x, y, data, out reason);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
return SuccessResult();
|
||||||
|
else
|
||||||
|
return FailureResult(reason);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[MAP SERVICE IMAGE HANDLER]: Exception {0} {1}", e.Message, e.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FailureResult("Unexpected server error");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] SuccessResult()
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||||
|
"", "");
|
||||||
|
|
||||||
|
doc.AppendChild(xmlnode);
|
||||||
|
|
||||||
|
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
|
||||||
|
"");
|
||||||
|
|
||||||
|
doc.AppendChild(rootElement);
|
||||||
|
|
||||||
|
XmlElement result = doc.CreateElement("", "Result", "");
|
||||||
|
result.AppendChild(doc.CreateTextNode("Success"));
|
||||||
|
|
||||||
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] FailureResult(string msg)
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||||
|
"", "");
|
||||||
|
|
||||||
|
doc.AppendChild(xmlnode);
|
||||||
|
|
||||||
|
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
|
||||||
|
"");
|
||||||
|
|
||||||
|
doc.AppendChild(rootElement);
|
||||||
|
|
||||||
|
XmlElement result = doc.CreateElement("", "Result", "");
|
||||||
|
result.AppendChild(doc.CreateTextNode("Failure"));
|
||||||
|
|
||||||
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
|
XmlElement message = doc.CreateElement("", "Message", "");
|
||||||
|
message.AppendChild(doc.CreateTextNode(msg));
|
||||||
|
|
||||||
|
rootElement.AppendChild(message);
|
||||||
|
|
||||||
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] DocToBytes(XmlDocument doc)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||||
|
xw.Formatting = Formatting.Indented;
|
||||||
|
doc.WriteTo(xw);
|
||||||
|
xw.Flush();
|
||||||
|
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue