Merge branch 'master' into careminster-presence-refactor
commit
326c46ba70
|
@ -34,7 +34,7 @@ namespace OpenSim.Data
|
|||
{
|
||||
public class FriendsData
|
||||
{
|
||||
public UUID PrincipalID;
|
||||
public string PrincipalID;
|
||||
public string Friend;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ namespace OpenSim.Data
|
|||
{
|
||||
bool Store(FriendsData data);
|
||||
bool Delete(UUID ownerID, string friend);
|
||||
bool Delete(string ownerID, string friend);
|
||||
FriendsData[] GetFriends(UUID principalID);
|
||||
FriendsData[] GetFriends(string principalID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace OpenSim.Data.MSSQL
|
|||
{
|
||||
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 string m_connectionString;
|
||||
|
@ -72,7 +72,12 @@ namespace OpenSim.Data.MSSQL
|
|||
}
|
||||
|
||||
//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
|
||||
Type t = typeof(EstateSettings);
|
||||
|
@ -112,19 +117,19 @@ namespace OpenSim.Data.MSSQL
|
|||
{
|
||||
FieldInfo f = _FieldMap[name];
|
||||
object v = reader[name];
|
||||
if (f.FieldType == typeof(bool) )
|
||||
if (f.FieldType == typeof(bool))
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if (f.FieldType == typeof(string))
|
||||
else if (f.FieldType == typeof(string))
|
||||
{
|
||||
f.SetValue(es, v.ToString());
|
||||
}
|
||||
else if (f.FieldType == typeof(UInt32))
|
||||
else if (f.FieldType == typeof(UInt32))
|
||||
{
|
||||
f.SetValue(es, Convert.ToUInt32(v));
|
||||
}
|
||||
|
@ -186,7 +191,7 @@ namespace OpenSim.Data.MSSQL
|
|||
}
|
||||
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();
|
||||
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.ExecuteNonQuery();
|
||||
|
||||
//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);
|
||||
foreach (EstateBan b in es.EstateBans)
|
||||
{
|
||||
|
@ -350,43 +355,195 @@ namespace OpenSim.Data.MSSQL
|
|||
|
||||
public EstateSettings LoadEstateSettings(int estateID)
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new EstateSettings();
|
||||
EstateSettings es = 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()
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new List<EstateSettings>();
|
||||
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
|
||||
|
||||
List<int> allEstateIds = GetEstatesAll();
|
||||
|
||||
foreach (int estateId in allEstateIds)
|
||||
allEstateSettings.Add(LoadEstateSettings(estateId));
|
||||
|
||||
return allEstateSettings;
|
||||
}
|
||||
|
||||
public List<int> GetEstates(string search)
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new List<int>();
|
||||
List<int> result = 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()
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new List<int>();
|
||||
List<int> result = 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
public List<UUID> GetRegions(int estateID)
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new List<UUID>();
|
||||
List<UUID> result = 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)
|
||||
|
|
|
@ -51,6 +51,11 @@ namespace OpenSim.Data.MSSQL
|
|||
}
|
||||
|
||||
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 (SqlCommand cmd = new SqlCommand())
|
||||
|
@ -67,6 +72,11 @@ namespace OpenSim.Data.MSSQL
|
|||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(string principalID)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
|
|
|
@ -168,14 +168,13 @@ namespace OpenSim.Data.MSSQL
|
|||
|
||||
protected T[] DoQuery(SqlCommand cmd)
|
||||
{
|
||||
List<T> result = new List<T>();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader == null)
|
||||
return new T[0];
|
||||
|
||||
CheckColumnNames(reader);
|
||||
|
||||
List<T> result = new List<T>();
|
||||
CheckColumnNames(reader);
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
|
@ -262,6 +261,15 @@ namespace OpenSim.Data.MSSQL
|
|||
{
|
||||
names.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))
|
||||
{
|
||||
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 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.CommandText = query;
|
||||
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.Common;
|
||||
using System.Reflection;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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";
|
||||
if (scopeID != UUID.Zero)
|
||||
sql += " and ScopeID = @scopeID";
|
||||
sql += " order by regionName";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
|
|
|
@ -55,6 +55,10 @@ namespace OpenSim.Data.MSSQL
|
|||
/// </summary>
|
||||
private MSSQLManager _Database;
|
||||
private string m_connectionString;
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MSSQLSimulationData()
|
||||
{
|
||||
|
@ -74,9 +78,28 @@ namespace OpenSim.Data.MSSQL
|
|||
m_connectionString = 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
|
||||
_Database.CheckMigration(_migrationStore);
|
||||
// Clean dropped attachments
|
||||
//
|
||||
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>
|
||||
|
@ -214,7 +237,7 @@ namespace OpenSim.Data.MSSQL
|
|||
{
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID));
|
||||
|
||||
|
||||
List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
|
||||
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
|
@ -241,6 +264,14 @@ namespace OpenSim.Data.MSSQL
|
|||
/// <param name="regionUUID"></param>
|
||||
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);
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
|
@ -700,16 +731,470 @@ VALUES
|
|||
}
|
||||
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
//Return default LL windlight settings
|
||||
return new RegionLightShareData();
|
||||
RegionLightShareData nWP = new RegionLightShareData();
|
||||
nWP.OnSave += StoreRegionWindlightSettings;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
//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>
|
||||
/// Loads the settings of a region.
|
||||
|
@ -1136,7 +1621,7 @@ VALUES
|
|||
if (Convert.ToInt16(primRow["PassTouches"]) != 0)
|
||||
prim.PassTouches = true;
|
||||
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
|
||||
|
||||
|
||||
if (!(primRow["MediaURL"] is System.DBNull))
|
||||
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"]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return baseShape;
|
||||
}
|
||||
|
@ -1576,15 +2061,15 @@ VALUES
|
|||
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
||||
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
|
||||
{
|
||||
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
|
||||
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
|
|
|
@ -66,11 +66,18 @@ namespace OpenSim.Data.MSSQL
|
|||
|
||||
public bool StoreFolder(XInventoryFolder folder)
|
||||
{
|
||||
if (folder.folderName.Length > 64)
|
||||
folder.folderName = folder.folderName.Substring(0, 64);
|
||||
return m_Folders.Store(folder);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -78,7 +85,6 @@ namespace OpenSim.Data.MSSQL
|
|||
{
|
||||
return m_Folders.Delete(field, val);
|
||||
}
|
||||
|
||||
public bool DeleteFolders(string[] fields, string[] vals)
|
||||
{
|
||||
return m_Folders.Delete(fields, vals);
|
||||
|
@ -88,12 +94,10 @@ namespace OpenSim.Data.MSSQL
|
|||
{
|
||||
return m_Items.Delete(field, val);
|
||||
}
|
||||
|
||||
public bool DeleteItems(string[] fields, string[] vals)
|
||||
{
|
||||
return m_Items.Delete(fields, vals);
|
||||
}
|
||||
|
||||
public bool MoveItem(string id, string 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
|
||||
|
||||
: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
|
||||
|
||||
: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")
|
||||
)
|
||||
|
||||
COMMIT TRANSACTION
|
||||
COMMIT
|
||||
|
||||
:VERSION 26
|
||||
|
||||
|
|
|
@ -43,6 +43,11 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
|
||||
public bool Delete(UUID principalID, string friend)
|
||||
{
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
|
@ -64,5 +69,14 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
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;
|
||||
|
||||
:VERSION 3 # -------------------------
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE `Friends` DROP PRIMARY KEY;
|
||||
ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36));
|
||||
ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
COMMIT;
|
||||
|
|
|
@ -42,6 +42,11 @@ namespace OpenSim.Data.Null
|
|||
{
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to implement the Get [] semantics, but it cuts corners.
|
||||
/// 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="values"></param>
|
||||
/// <returns></returns>
|
||||
public FriendsData[] GetFriends(UUID userID)
|
||||
public FriendsData[] GetFriends(string userID)
|
||||
{
|
||||
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
|
||||
{
|
||||
return fdata.PrincipalID == userID;
|
||||
return fdata.PrincipalID == userID.ToString();
|
||||
});
|
||||
|
||||
if (lst != null)
|
||||
|
@ -72,9 +77,14 @@ namespace OpenSim.Data.Null
|
|||
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)
|
||||
{
|
||||
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();
|
||||
|
||||
|
@ -58,6 +63,11 @@ namespace OpenSim.Data.SQLite
|
|||
}
|
||||
|
||||
public bool Delete(UUID principalID, string friend)
|
||||
{
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
SqliteCommand cmd = new SqliteCommand();
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ namespace OpenSim.Data.SQLite
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -345,6 +345,7 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -223,6 +223,12 @@ namespace OpenSim.Framework
|
|||
set { m_metadata.Temporary = value; }
|
||||
}
|
||||
|
||||
public string CreatorID
|
||||
{
|
||||
get { return m_metadata.CreatorID; }
|
||||
set { m_metadata.CreatorID = value; }
|
||||
}
|
||||
|
||||
public AssetFlags Flags
|
||||
{
|
||||
get { return m_metadata.Flags; }
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace OpenSim.Framework
|
|||
public Vector3 Position;
|
||||
public ulong RegionHandle;
|
||||
public UUID RegionID;
|
||||
public string Gatekeeper = string.Empty;
|
||||
public int Version;
|
||||
|
||||
public AssetLandmark(AssetBase a)
|
||||
|
@ -51,6 +52,8 @@ namespace OpenSim.Framework
|
|||
string[] parts = temp.Split('\n');
|
||||
int.TryParse(parts[0].Substring(17, 1), out Version);
|
||||
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").
|
||||
// Parse each scalar separately to take into account the system's culture setting.
|
||||
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);
|
||||
|
||||
public delegate void TeleportLandmarkRequest(
|
||||
IClientAPI remoteClient, UUID regionID, Vector3 position);
|
||||
IClientAPI remoteClient, AssetLandmark lm);
|
||||
|
||||
public delegate void DisconnectUser();
|
||||
|
||||
|
@ -1165,7 +1165,19 @@ namespace OpenSim.Framework
|
|||
void SendAgentAlertMessage(string message, bool modal);
|
||||
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);
|
||||
|
||||
bool AddMoney(int debit);
|
||||
|
|
|
@ -1706,5 +1706,68 @@ namespace OpenSim.Framework
|
|||
return (T)Enum.Parse(typeof(T), value); ;
|
||||
}
|
||||
#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("True", true);
|
||||
configSource.Alias.AddAlias("False", false);
|
||||
configSource.Alias.AddAlias("Yes", true);
|
||||
configSource.Alias.AddAlias("No", false);
|
||||
|
||||
configSource.AddSwitch("Startup", "background");
|
||||
configSource.AddSwitch("Startup", "inifile");
|
||||
|
@ -239,6 +241,8 @@ namespace OpenSim
|
|||
configSource.AddSwitch("Startup", "physics");
|
||||
configSource.AddSwitch("Startup", "gui");
|
||||
configSource.AddSwitch("Startup", "console");
|
||||
configSource.AddSwitch("Startup", "save_crashes");
|
||||
configSource.AddSwitch("Startup", "crash_dir");
|
||||
|
||||
configSource.AddConfig("StandAlone");
|
||||
configSource.AddConfig("Network");
|
||||
|
|
|
@ -918,7 +918,7 @@ namespace OpenSim
|
|||
|
||||
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<string> estateNames = new List<string>();
|
||||
|
@ -929,7 +929,7 @@ namespace OpenSim
|
|||
{
|
||||
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))
|
||||
break;
|
||||
|
|
|
@ -1476,6 +1476,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
money.MoneyData.TransactionSuccess = success;
|
||||
money.MoneyData.Description = description;
|
||||
money.MoneyData.MoneyBalance = balance;
|
||||
money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE");
|
||||
OutPacket(money, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
|
@ -2231,7 +2232,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
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);
|
||||
dialog.Data.ObjectID = objectID;
|
||||
|
@ -2249,6 +2252,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
|
||||
}
|
||||
dialog.Buttons = buttons;
|
||||
|
||||
dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
|
||||
dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
|
||||
dialog.OwnerData[0].OwnerID = ownerID;
|
||||
|
||||
OutPacket(dialog, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
|
@ -2320,8 +2328,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
|
||||
viewertime.TimeInfo.SunDirection = Position;
|
||||
viewertime.TimeInfo.SunAngVelocity = Velocity;
|
||||
|
@ -8358,16 +8364,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
AssetLandmark lm;
|
||||
if (lmid != UUID.Zero)
|
||||
{
|
||||
|
||||
//AssetBase lma = m_assetCache.GetAsset(lmid, false);
|
||||
AssetBase lma = m_assetService.Get(lmid.ToString());
|
||||
|
||||
if (lma == null)
|
||||
{
|
||||
// Failed to find landmark
|
||||
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
||||
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
||||
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
||||
OutPacket(tpCancel, ThrottleOutPacketType.Task);
|
||||
|
||||
// Let's try to search in the user's home asset server
|
||||
lma = FindAssetInUserAssetServer(lmid.ToString());
|
||||
|
||||
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
|
||||
|
@ -8398,13 +8413,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest;
|
||||
if (handlerTeleportLandmarkRequest != null)
|
||||
{
|
||||
handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position);
|
||||
handlerTeleportLandmarkRequest(this, lm);
|
||||
}
|
||||
else
|
||||
{
|
||||
//no event handler so cancel request
|
||||
|
||||
|
||||
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
||||
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
||||
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
||||
|
@ -8414,6 +8427,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
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)
|
||||
{
|
||||
TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
|
||||
|
|
|
@ -124,7 +124,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
|||
|
||||
ScenePresence sp = m_scene.GetScenePresence(avatarID);
|
||||
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(
|
||||
|
|
|
@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
{
|
||||
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
||||
{
|
||||
protected bool m_Enabled = false;
|
||||
|
||||
protected class UserFriendData
|
||||
{
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
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"];
|
||||
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");
|
||||
throw new Exception("Connector load error");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
scene.RegisterModuleInterface<IFriendsModule>(this);
|
||||
|
||||
|
@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
|
||||
public string Name
|
||||
public virtual string Name
|
||||
{
|
||||
get { return "FriendsModule"; }
|
||||
}
|
||||
|
@ -194,13 +219,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
get { return null; }
|
||||
}
|
||||
|
||||
public uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||
#endregion
|
||||
|
||||
public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(principalID);
|
||||
foreach (FriendInfo fi in friends)
|
||||
FriendInfo finfo = GetFriend(friends, friendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
if (fi.Friend == friendID.ToString())
|
||||
return (uint)fi.TheirFlags;
|
||||
return (uint)finfo.TheirFlags;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -214,30 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
client.OnTerminateFriendship += OnTerminateFriendship;
|
||||
client.OnGrantUserRights += OnGrantUserRights;
|
||||
|
||||
// Asynchronously fetch the friends list or increment the refcount for the existing
|
||||
// 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;
|
||||
Util.FireAndForget(delegate { FetchFriendslist(client); });
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -263,14 +294,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
private void OnMakeRootAgent(ScenePresence sp)
|
||||
{
|
||||
UUID agentID = sp.ControllingClient.AgentId;
|
||||
UpdateFriendsCache(agentID);
|
||||
RefetchFriends(sp.ControllingClient);
|
||||
}
|
||||
|
||||
private void OnClientLogin(IClientAPI client)
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
|
||||
//m_log.DebugFormat("[XXX]: OnClientLogin!");
|
||||
// Inform the friends that this user is online
|
||||
StatusChange(agentID, true);
|
||||
|
||||
|
@ -279,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
m_NeedsListOfFriends.Add(agentID);
|
||||
}
|
||||
|
||||
public void SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||
public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
|
||||
|
@ -287,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
lock (m_NeedsListOfFriends)
|
||||
{
|
||||
if (!m_NeedsListOfFriends.Remove(agentID))
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the friends online
|
||||
|
@ -313,10 +344,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
foreach (string fid in outstanding)
|
||||
{
|
||||
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;
|
||||
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
|
||||
}
|
||||
|
||||
PresenceInfo presence = null;
|
||||
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
|
||||
|
@ -326,13 +359,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
im.offline = 0;
|
||||
|
||||
im.fromAgentID = fromAgentID.Guid;
|
||||
im.fromAgentName = account.FirstName + " " + account.LastName;
|
||||
im.fromAgentName = firstname + " " + lastname;
|
||||
im.offline = (byte)((presence == null) ? 1 : 0);
|
||||
im.imSessionID = im.fromAgentID;
|
||||
im.message = FriendshipMessage(fid);
|
||||
|
||||
// Finally
|
||||
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)
|
||||
|
@ -348,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
}
|
||||
|
||||
if (friendList.Count > 0)
|
||||
{
|
||||
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||
foreach (PresenceInfo pi in presence)
|
||||
{
|
||||
UUID presenceID;
|
||||
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||
online.Add(presenceID);
|
||||
}
|
||||
}
|
||||
GetOnlineFriends(userID, friendList, 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>
|
||||
/// Find the client for a ID
|
||||
/// </summary>
|
||||
|
@ -415,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
Util.FireAndForget(
|
||||
delegate
|
||||
{
|
||||
foreach (FriendInfo fi in friendList)
|
||||
{
|
||||
//m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
|
||||
// Notify about this user status
|
||||
StatusNotify(fi, agentID, online);
|
||||
}
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
|
||||
// Notify about this user status
|
||||
StatusNotify(friendList, agentID, online);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void StatusNotify(FriendInfo friend, UUID userID, bool online)
|
||||
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||
{
|
||||
UUID friendID;
|
||||
if (UUID.TryParse(friend.Friend, out friendID))
|
||||
foreach (FriendInfo friend in friendList)
|
||||
{
|
||||
// Try local
|
||||
if (LocalStatusNotification(userID, friendID, online))
|
||||
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)
|
||||
UUID friendID;
|
||||
if (UUID.TryParse(friend.Friend, out friendID))
|
||||
{
|
||||
PresenceInfo friendSession = null;
|
||||
foreach (PresenceInfo pinfo in friendSessions)
|
||||
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
|
||||
{
|
||||
friendSession = pinfo;
|
||||
break;
|
||||
}
|
||||
// Try local
|
||||
if (LocalStatusNotification(userID, friendID, online))
|
||||
return;
|
||||
|
||||
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);
|
||||
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
|
||||
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
|
||||
}
|
||||
}
|
||||
PresenceInfo friendSession = null;
|
||||
foreach (PresenceInfo pinfo in friendSessions)
|
||||
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
|
||||
{
|
||||
friendSession = pinfo;
|
||||
break;
|
||||
}
|
||||
|
||||
// Friend is not online. Ignore.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
|
||||
if (friendSession != null)
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
|
||||
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.
|
||||
// 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
|
||||
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)
|
||||
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
|
||||
im.imSessionID = im.fromAgentID;
|
||||
im.fromAgentName = GetFriendshipRequesterName(agentID);
|
||||
|
||||
// Try the local sim
|
||||
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
|
||||
im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
||||
|
||||
// Try the local sim
|
||||
if (LocalFriendshipOffered(friendID, im))
|
||||
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.
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
|
||||
|
||||
FriendsService.StoreFriend(agentID, friendID.ToString(), 1);
|
||||
FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
|
||||
|
||||
StoreFriendships(agentID, friendID);
|
||||
|
||||
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||
if (ccm != null)
|
||||
|
@ -523,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
}
|
||||
|
||||
// Update the local cache
|
||||
UpdateFriendsCache(agentID);
|
||||
RefetchFriends(client);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
|
@ -554,8 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
{
|
||||
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
|
||||
|
||||
FriendsService.Delete(agentID, friendID.ToString());
|
||||
FriendsService.Delete(friendID, agentID.ToString());
|
||||
DeleteFriendship(agentID, friendID);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
|
@ -582,11 +644,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
|
||||
{
|
||||
FriendsService.Delete(agentID, exfriendID.ToString());
|
||||
FriendsService.Delete(exfriendID, agentID.ToString());
|
||||
if (!DeleteFriendship(agentID, exfriendID))
|
||||
client.SendAlertMessage("Unable to terminate friendship on this sim.");
|
||||
|
||||
// Update local cache
|
||||
UpdateFriendsCache(agentID);
|
||||
RefetchFriends(client);
|
||||
|
||||
client.SendTerminateFriend(exfriendID);
|
||||
|
||||
|
@ -612,23 +674,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
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);
|
||||
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())
|
||||
friend = fi;
|
||||
return;
|
||||
}
|
||||
|
||||
// Let's find the friend in this user's friend list
|
||||
FriendInfo friend = GetFriend(friends, target);
|
||||
|
||||
if (friend != null) // Found it
|
||||
{
|
||||
// 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
|
||||
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
|
||||
|
@ -693,7 +769,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
|
||||
// Update the local cache
|
||||
UpdateFriendsCache(friendID);
|
||||
RefetchFriends(friendClient);
|
||||
|
||||
// we're done
|
||||
return true;
|
||||
|
@ -726,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
// the friend in this sim as root agent
|
||||
friendClient.SendTerminateFriend(exfriendID);
|
||||
// update local cache
|
||||
UpdateFriendsCache(exfriendID);
|
||||
RefetchFriends(friendClient);
|
||||
// we're done
|
||||
return true;
|
||||
}
|
||||
|
@ -756,15 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
}
|
||||
|
||||
// Update local cache
|
||||
lock (m_Friends)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(friendID);
|
||||
foreach (FriendInfo finfo in friends)
|
||||
{
|
||||
if (finfo.Friend == userID.ToString())
|
||||
finfo.TheirFlags = rights;
|
||||
}
|
||||
}
|
||||
UpdateLocalCache(userID, friendID, rights);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -775,10 +843,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
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);
|
||||
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
|
||||
if (online)
|
||||
friendClient.SendAgentOnline(new UUID[] { userID });
|
||||
|
@ -793,7 +861,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
|||
|
||||
#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;
|
||||
|
||||
|
@ -806,14 +880,63 @@ namespace OpenSim.Region.CoreModules.Avatar.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)
|
||||
{
|
||||
UserFriendData 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,628 @@
|
|||
/*
|
||||
* 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 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);
|
||||
// need to debug this here
|
||||
if (online)
|
||||
{
|
||||
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, url + ";" + first + " " + last);
|
||||
|
||||
try // our best
|
||||
{
|
||||
string[] parts = userMan.GetUserName(agentID).Split();
|
||||
first = parts[0];
|
||||
last = parts[1];
|
||||
}
|
||||
catch { }
|
||||
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>
|
||||
/// 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
|
||||
///
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// </remarks>
|
||||
///
|
||||
/// <param name="inventoryService">
|
||||
/// Inventory service to query
|
||||
|
@ -178,32 +179,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
|
||||
return FindItemByPath(inventoryService, rootFolder, path);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
|
||||
///
|
||||
/// This method does not handle paths that contain multiple delimitors
|
||||
/// </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.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="inventoryService">
|
||||
/// Inventory service to query
|
||||
/// </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>
|
||||
/// </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>null if the item is not found</returns>
|
||||
public static InventoryItemBase FindItemByPath(
|
||||
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
|
||||
path = path.TrimStart(new char[] { PATH_DELIMITER });
|
||||
|
||||
|
@ -215,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
if (components.Length == 1)
|
||||
{
|
||||
// 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);
|
||||
|
||||
List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
|
||||
|
||||
|
||||
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
|
||||
|
||||
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);
|
||||
|
||||
if (item.Name == components[0])
|
||||
return item;
|
||||
foundItems.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
|
||||
|
||||
|
||||
InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
|
||||
|
||||
foreach (InventoryFolderBase folder in contents.Folders)
|
||||
{
|
||||
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 null;
|
||||
return foundItems;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -154,7 +154,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -246,10 +249,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
|
||||
// The path may point to an item instead
|
||||
if (inventoryFolder == null)
|
||||
{
|
||||
inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
|
||||
//inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
|
||||
}
|
||||
|
||||
if (null == inventoryFolder && null == inventoryItem)
|
||||
{
|
||||
|
|
|
@ -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 IMessageTransferModule m_TransferModule = null;
|
||||
private bool m_Enabled = true;
|
||||
private bool m_Enabled = false;
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
if (config.Configs["Messaging"] != null)
|
||||
{
|
||||
if (config.Configs["Messaging"].GetString(
|
||||
"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)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
if (m_TransferModule == null)
|
||||
{
|
||||
m_TransferModule =
|
||||
|
@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
|||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
lock (m_scenes)
|
||||
{
|
||||
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 Scene m_aScene;
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
protected List<UUID> m_agentsInTransit;
|
||||
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
|
||||
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
|
||||
|
@ -96,13 +97,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
if (m_aScene == null)
|
||||
m_aScene = scene;
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
scene.RegisterModuleInterface<IEntityTransferModule>(this);
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
|
||||
protected virtual void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnTeleportHomeRequest += TeleportHomeFired;
|
||||
client.OnTeleportHomeRequest += TriggerTeleportHome;
|
||||
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
|
@ -118,6 +121,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
return;
|
||||
if (scene == m_aScene)
|
||||
m_aScene = null;
|
||||
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
|
||||
public virtual void RegionLoaded(Scene scene)
|
||||
|
@ -127,7 +132,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#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)
|
||||
{
|
||||
|
@ -557,9 +561,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
#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
|
||||
|
||||
public void TeleportHomeFired(UUID id, IClientAPI client)
|
||||
public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
|
||||
{
|
||||
TeleportHome(id, client);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
protected override void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnTeleportHomeRequest += TeleportHomeFired;
|
||||
client.OnTeleportHomeRequest += TriggerTeleportHome;
|
||||
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
|
||||
client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
|
||||
}
|
||||
|
||||
|
@ -178,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
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);
|
||||
}
|
||||
|
@ -233,6 +234,58 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
|
||||
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
|
||||
|
||||
#region IUserAgentVerificationModule
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
|
||||
private string m_ProfileServerURI;
|
||||
private bool m_OutboundPermission;
|
||||
private string m_ThisGatekeeper;
|
||||
|
||||
// private bool m_Initialized = false;
|
||||
|
||||
|
@ -85,6 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
{
|
||||
m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
|
||||
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
|
||||
m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
|
||||
}
|
||||
else
|
||||
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)
|
||||
{
|
||||
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); });
|
||||
}
|
||||
|
@ -119,6 +121,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
#endregion
|
||||
|
||||
#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
|
||||
///
|
||||
|
@ -180,10 +200,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
|
||||
{
|
||||
string userAssetServer = string.Empty;
|
||||
if (IsForeignUser(sender, out userAssetServer))
|
||||
if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -203,9 +223,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -30,6 +30,7 @@ using System.Collections.Generic;
|
|||
using System.Net;
|
||||
using System.Xml;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using OpenSim.Framework;
|
||||
|
@ -128,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
|
||||
protected virtual void OnNewClient(IClientAPI client)
|
||||
{
|
||||
|
||||
client.OnCreateNewInventoryItem += CreateNewInventoryItem;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
|
@ -156,6 +157,87 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
|
||||
#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>
|
||||
/// Capability originating call to update the asset of an item in an agent's inventory
|
||||
/// </summary>
|
||||
|
|
|
@ -30,11 +30,13 @@ using System.IO;
|
|||
using System.Reflection;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
|
||||
using OpenSim.Region.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
|
@ -47,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
public UUID Id;
|
||||
public string FirstName;
|
||||
public string LastName;
|
||||
public string ProfileURL;
|
||||
public string HomeURL;
|
||||
public Dictionary<string, object> ServerURLs;
|
||||
}
|
||||
|
||||
public class UserManagementModule : ISharedRegionModule, IUserManagement
|
||||
|
@ -78,6 +81,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
// }
|
||||
// }
|
||||
//}
|
||||
MainConsole.Instance.Commands.AddCommand("grid", true,
|
||||
"show user-names",
|
||||
"show user-names",
|
||||
"Show the bindings between user UUIDs and user names",
|
||||
String.Empty,
|
||||
HandleShowUsers);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
|
@ -101,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
scene.RegisterModuleInterface<IUserManagement>(this);
|
||||
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
|
||||
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
|
@ -109,18 +121,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
m_Scenes.Remove(scene);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
public void RegionLoaded(Scene s)
|
||||
{
|
||||
}
|
||||
|
||||
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()
|
||||
|
@ -134,6 +140,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
#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)
|
||||
{
|
||||
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
|
||||
|
@ -150,6 +164,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
string[] names = GetUserNames(uuid);
|
||||
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]);
|
||||
}
|
||||
|
||||
|
@ -210,6 +225,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
|
||||
public string GetUserName(UUID uuid)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
|
||||
string[] names = GetUserNames(uuid);
|
||||
if (names.Length == 2)
|
||||
{
|
||||
|
@ -222,6 +238,60 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
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)
|
||||
{
|
||||
if (m_UserCache.ContainsKey(id))
|
||||
|
@ -247,13 +317,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
string[] parts = creatorData.Split(';');
|
||||
if (parts.Length >= 1)
|
||||
{
|
||||
user.ProfileURL = parts[0];
|
||||
user.HomeURL = parts[0];
|
||||
try
|
||||
{
|
||||
Uri uri = new Uri(parts[0]);
|
||||
user.LastName = "@" + uri.Authority;
|
||||
}
|
||||
catch
|
||||
catch (UriFormatException)
|
||||
{
|
||||
m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
|
||||
user.LastName = "@unknown";
|
||||
|
@ -272,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
lock (m_UserCache)
|
||||
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)
|
||||
|
@ -311,5 +381,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
//}
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
|
@ -67,9 +68,26 @@ namespace OpenSim.Region.CoreModules.Hypergrid
|
|||
|
||||
foreach (GridRegion r in regions)
|
||||
{
|
||||
MapBlockData block = new MapBlockData();
|
||||
MapBlockFromGridRegion(block, r);
|
||||
mapBlocks.Add(block);
|
||||
uint x = 0, y = 0;
|
||||
long handle = 0;
|
||||
if (r.RegionSecret != null && r.RegionSecret != string.Empty)
|
||||
{
|
||||
if (long.TryParse(r.RegionSecret, out handle))
|
||||
{
|
||||
Utils.LongToUInts((ulong)handle, out x, out y);
|
||||
x = x / Constants.RegionSize;
|
||||
y = y / Constants.RegionSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (handle == 0 ||
|
||||
// Check the distance from the current region
|
||||
(handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096))
|
||||
{
|
||||
MapBlockData block = new MapBlockData();
|
||||
MapBlockFromGridRegion(block, r);
|
||||
mapBlocks.Add(block);
|
||||
}
|
||||
}
|
||||
|
||||
// Different from super
|
||||
|
@ -77,6 +95,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
|
|||
//
|
||||
|
||||
remoteClient.SendMapBlock(mapBlocks, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
|
||||
<RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
|
||||
<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="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
|
||||
<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>();
|
||||
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 HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
|
||||
}
|
||||
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
|||
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -230,6 +230,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
/// <param name="asset"></param>
|
||||
public void AssetRequestCallback(string id, object sender, AssetBase asset)
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
|
||||
try
|
||||
{
|
||||
lock (this)
|
||||
|
@ -289,6 +291,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
|||
/// </summary>
|
||||
protected void PerformAssetsRequestCallback(object o)
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
|
||||
try
|
||||
{
|
||||
m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);
|
||||
|
|
|
@ -548,18 +548,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
|
||||
// libomv will moan about PrimFlags.ObjectYouOfficer being
|
||||
// deprecated
|
||||
#pragma warning disable 0612
|
||||
#pragma warning disable 0612
|
||||
objflags &= (uint)
|
||||
~(PrimFlags.ObjectCopy | // Tells client you can copy 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.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.ObjectAnyOwner | // Tells client that someone owns 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.ObjectModify | // tells client you can modify the object
|
||||
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.ObjectYouOwner | // Tells client that you're the owner of the object
|
||||
PrimFlags.ObjectAnyOwner | // Tells client that someone owns 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
|
||||
);
|
||||
#pragma warning restore 0612
|
||||
#pragma warning restore 0612
|
||||
|
||||
// Creating the three ObjectFlags options for this method to choose from.
|
||||
// Customize the OwnerMask
|
||||
|
@ -576,22 +576,27 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
|
||||
if (m_bypassPermissions)
|
||||
return objectOwnerMask;
|
||||
|
||||
|
||||
// Object owners should be able to edit their own content
|
||||
if (user == objectOwner)
|
||||
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
|
||||
if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
|
||||
{
|
||||
return objectOwnerMask;
|
||||
}
|
||||
|
||||
// Admin should be able to edit anything in the sim (including admin objects)
|
||||
if (IsAdministrator(user))
|
||||
{
|
||||
return objectOwnerMask;
|
||||
|
||||
}
|
||||
|
||||
// Users should be able to edit what is over their land.
|
||||
Vector3 taskPos = task.AbsolutePosition;
|
||||
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
|
||||
if (!IsAdministrator(objectOwner))
|
||||
{
|
||||
return objectOwnerMask;
|
||||
}
|
||||
}
|
||||
|
||||
// Group permissions
|
||||
if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
|
||||
return objectGroupMask | objectEveryoneMask;
|
||||
|
||||
|
||||
return objectEveryoneMask;
|
||||
}
|
||||
|
||||
|
@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
//
|
||||
// Nobody but the object owner can set permissions on an object
|
||||
//
|
||||
|
||||
if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
|
||||
{
|
||||
return false;
|
||||
|
@ -704,6 +710,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
// Return immediately, so that the administrator can shares group objects
|
||||
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.
|
||||
ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);
|
||||
|
|
|
@ -208,52 +208,65 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
|||
//m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
|
||||
// path, param, agentID.ToString());
|
||||
|
||||
// this is here because CAPS map requests work even beyond the 10,000 limit.
|
||||
ScenePresence avatarPresence = null;
|
||||
// There is a major hack going on in this method. The viewer doesn't request
|
||||
// map blocks (RequestMapBlocks) above 4096. 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 4096 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 (avatarPresence != null)
|
||||
if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY >= 4096)
|
||||
{
|
||||
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()))
|
||||
{
|
||||
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);
|
||||
bool lookup = false;
|
||||
|
||||
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();
|
||||
mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
|
||||
return mapResponse.ToString();
|
||||
|
|
|
@ -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);
|
||||
|
||||
void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
|
||||
Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq);
|
||||
|
||||
bool Cross(ScenePresence agent, bool isFlying);
|
||||
|
||||
void AgentArrivedAtDestination(UUID agent);
|
||||
|
|
|
@ -34,6 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
public interface IFriendsModule
|
||||
{
|
||||
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
|
||||
{
|
||||
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 firstName, string lastName, string profileURL);
|
||||
}
|
||||
|
|
|
@ -393,6 +393,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public delegate void RegionUp(GridRegion region);
|
||||
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 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);
|
||||
item = InventoryService.GetItem(item);
|
||||
|
||||
if ((item != null) && (item.Owner == senderId))
|
||||
if (item == 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId);
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient);
|
||||
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>
|
||||
|
@ -781,7 +787,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="asset"></param>
|
||||
/// <param name="invType"></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)
|
||||
{
|
||||
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>
|
||||
/// Link an inventory item to an existing item.
|
||||
/// </summary>
|
||||
|
|
|
@ -95,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public bool m_strictAccessControl = true;
|
||||
public bool m_seeIntoBannedRegion = false;
|
||||
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 StartDisabled = false;
|
||||
public bool LoadingPrims;
|
||||
public IXfer XferManager;
|
||||
|
||||
|
@ -1399,10 +1402,26 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
IConfig startupConfig = m_config.Configs["Startup"];
|
||||
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);
|
||||
LoginsDisabled = false;
|
||||
// For RegionReady lockouts
|
||||
if( LoginLock == false)
|
||||
{
|
||||
LoginsDisabled = false;
|
||||
}
|
||||
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartDisabled = true;
|
||||
LoginsDisabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
|
@ -1765,6 +1784,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
|
||||
LoadingPrims = false;
|
||||
EventManager.TriggerPrimsLoaded(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1930,6 +1950,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
sceneObject.SetGroup(groupID, null);
|
||||
}
|
||||
|
||||
IUserManagement uman = RequestModuleInterface<IUserManagement>();
|
||||
if (uman != null)
|
||||
sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
|
||||
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
|
||||
return sceneObject;
|
||||
|
@ -2658,6 +2682,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (TryGetScenePresence(client.AgentId, out presence))
|
||||
{
|
||||
m_LastLogin = Util.EnvironmentTickCount();
|
||||
|
||||
// Cache the user's name
|
||||
CacheUserName(aCircuit);
|
||||
|
||||
EventManager.TriggerOnNewClient(client);
|
||||
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)
|
||||
{
|
||||
vialogin = false;
|
||||
|
@ -2813,7 +2863,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
|
||||
{
|
||||
client.OnCreateNewInventoryItem += CreateNewInventoryItem;
|
||||
|
||||
client.OnLinkInventoryItem += HandleLinkInventoryItem;
|
||||
client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
|
||||
client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
|
||||
|
@ -2837,7 +2887,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
|
||||
{
|
||||
client.OnTeleportLocationRequest += RequestTeleportLocation;
|
||||
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
|
||||
}
|
||||
|
||||
public virtual void SubscribeToClientScriptEvents(IClientAPI client)
|
||||
|
@ -2941,7 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
|
||||
{
|
||||
client.OnCreateNewInventoryItem -= CreateNewInventoryItem;
|
||||
|
||||
client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
|
||||
client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
|
||||
client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
|
||||
|
@ -2963,7 +3012,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
|
||||
{
|
||||
client.OnTeleportLocationRequest -= RequestTeleportLocation;
|
||||
client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
|
||||
//client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
|
||||
//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)
|
||||
{
|
||||
if (m_teleportModule != null)
|
||||
|
|
|
@ -121,7 +121,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serialize a scene object to the original xml format
|
||||
/// </summary>
|
||||
|
@ -572,7 +571,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
|
||||
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)
|
||||
|
@ -1479,7 +1484,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
}
|
||||
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)
|
||||
reader.Read();
|
||||
}
|
||||
|
@ -1531,8 +1538,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
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();
|
||||
|
||||
reader.ReadStartElement(name, String.Empty); // Shape
|
||||
|
@ -1551,7 +1567,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
}
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
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>
|
||||
/// 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>
|
||||
/// <param name="dataForAgentID"></param>
|
||||
/// <returns></returns>
|
||||
|
@ -1231,20 +1232,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
|||
List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID);
|
||||
GroupMembershipData[] membershipArray;
|
||||
|
||||
if (requestingClient.AgentId != dataForAgentID)
|
||||
{
|
||||
Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership)
|
||||
{
|
||||
return membership.ListInProfile;
|
||||
};
|
||||
// cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for
|
||||
// those with a GodLike aspect.
|
||||
Scene cScene = (Scene)requestingClient.Scene;
|
||||
bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId);
|
||||
|
||||
membershipArray = membershipData.FindAll(showInProfile).ToArray();
|
||||
}
|
||||
else
|
||||
if (isGod)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
|
|
@ -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.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
@ -50,6 +54,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
|||
private bool m_lastOarLoadedOk;
|
||||
private int m_channelNotify = -1000;
|
||||
private bool m_enabled = false;
|
||||
private bool m_disable_logins = false;
|
||||
private string m_uri = string.Empty;
|
||||
|
||||
Scene m_scene = null;
|
||||
|
||||
|
@ -68,10 +74,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
|||
if (m_config != null)
|
||||
{
|
||||
m_enabled = m_config.GetBoolean("enabled", false);
|
||||
|
||||
if (m_enabled)
|
||||
{
|
||||
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)
|
||||
|
@ -91,8 +100,21 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
|||
|
||||
m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
|
||||
m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
|
||||
m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
|
||||
|
||||
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)
|
||||
|
@ -150,7 +172,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
|||
|
||||
m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}",
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -309,7 +309,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
|||
// In attachments, the sensor cone always orients with the
|
||||
// avatar rotation. This may include a nonzero elevation if
|
||||
// in mouselook.
|
||||
|
||||
ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
|
||||
fromRegionPos = avatar.AbsolutePosition;
|
||||
q = avatar.Rotation;
|
||||
|
@ -424,6 +423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
|||
|
||||
SceneObjectPart SensePoint = ts.host;
|
||||
Vector3 fromRegionPos = SensePoint.AbsolutePosition;
|
||||
|
||||
Quaternion q = SensePoint.RotationOffset;
|
||||
if (SensePoint.ParentGroup.RootPart.IsAttachment)
|
||||
{
|
||||
|
@ -435,6 +435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
|||
fromRegionPos = avatar.AbsolutePosition;
|
||||
q = avatar.Rotation;
|
||||
}
|
||||
|
||||
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);
|
||||
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
|
||||
|
|
|
@ -65,6 +65,10 @@ namespace OpenSim.Server.Base
|
|||
/// <returns></returns>
|
||||
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[] {':'});
|
||||
|
||||
dllName = parts[0];
|
||||
|
@ -124,6 +128,13 @@ namespace OpenSim.Server.Base
|
|||
|
||||
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)
|
||||
{
|
||||
m_log.Error(string.Format("Error loading plugin from {0}", dllName), e);
|
||||
|
|
|
@ -46,14 +46,14 @@ namespace OpenSim.Server.Handlers.Friends
|
|||
if (serverConfig == null)
|
||||
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);
|
||||
|
||||
if (gridService == String.Empty)
|
||||
if (theService == String.Empty)
|
||||
throw new Exception("No LocalServiceModule in config file");
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -82,12 +82,18 @@ namespace OpenSim.Server.Handlers.Friends
|
|||
case "getfriends":
|
||||
return GetFriends(request);
|
||||
|
||||
case "getfriends_string":
|
||||
return GetFriendsString(request);
|
||||
|
||||
case "storefriend":
|
||||
return StoreFriend(request);
|
||||
|
||||
case "deletefriend":
|
||||
return DeleteFriend(request);
|
||||
|
||||
case "deletefriend_string":
|
||||
return DeleteFriendString(request);
|
||||
|
||||
}
|
||||
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");
|
||||
|
||||
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>();
|
||||
if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
|
||||
|
@ -136,9 +160,9 @@ namespace OpenSim.Server.Handlers.Friends
|
|||
|
||||
byte[] StoreFriend(Dictionary<string, object> request)
|
||||
{
|
||||
FriendInfo friend = new FriendInfo(request);
|
||||
|
||||
bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.MyFlags);
|
||||
string principalID = string.Empty, friend = string.Empty; int flags = 0;
|
||||
FromKeyValuePairs(request, out principalID, out friend, out flags);
|
||||
bool success = m_FriendsService.StoreFriend(principalID, friend, flags);
|
||||
|
||||
if (success)
|
||||
return SuccessResult();
|
||||
|
@ -163,7 +187,25 @@ namespace OpenSim.Server.Handlers.Friends
|
|||
else
|
||||
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
|
||||
|
||||
#region Misc
|
||||
|
@ -233,6 +275,19 @@ namespace OpenSim.Server.Handlers.Friends
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
private IUserAgentService m_HomeUsersService;
|
||||
private string[] m_AuthorizedCallers;
|
||||
|
||||
private bool m_VerifyCallers = false;
|
||||
|
||||
public UserAgentServerConnector(IConfigSource config, IHttpServer server) :
|
||||
this(config, server, null)
|
||||
{
|
||||
}
|
||||
|
||||
public UserAgentServerConnector(IConfigSource config, IHttpServer server, IFriendsSimConnector friendsConnector) :
|
||||
base(config, server, String.Empty)
|
||||
{
|
||||
IConfig gridConfig = config.Configs["UserAgentService"];
|
||||
if (gridConfig != null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (m_HomeUsersService == null)
|
||||
|
@ -69,12 +78,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
|
|||
string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1");
|
||||
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("get_home_region", GetHomeRegion, false);
|
||||
server.AddXmlRPCHandler("verify_agent", VerifyAgent, false);
|
||||
server.AddXmlRPCHandler("verify_client", VerifyClient, 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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
|||
using OpenSim.Server.Base;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Services.Connectors
|
||||
namespace OpenSim.Services.Connectors.Friends
|
||||
{
|
||||
public class FriendsServicesConnector : IFriendsService
|
||||
{
|
||||
|
@ -84,7 +84,7 @@ namespace OpenSim.Services.Connectors
|
|||
|
||||
|
||||
#region IFriendsService
|
||||
|
||||
|
||||
public FriendInfo[] GetFriends(UUID PrincipalID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
|
@ -92,6 +92,21 @@ namespace OpenSim.Services.Connectors
|
|||
sendData["PRINCIPALID"] = PrincipalID.ToString();
|
||||
sendData["METHOD"] = "getfriends";
|
||||
|
||||
return GetFriends(sendData, PrincipalID.ToString());
|
||||
}
|
||||
|
||||
public FriendInfo[] GetFriends(string PrincipalID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
|
||||
sendData["PRINCIPALID"] = PrincipalID;
|
||||
sendData["METHOD"] = "getfriends_string";
|
||||
|
||||
return GetFriends(sendData, PrincipalID);
|
||||
}
|
||||
|
||||
protected FriendInfo[] GetFriends(Dictionary<string, object> sendData, string PrincipalID)
|
||||
{
|
||||
string reqString = ServerUtils.BuildQueryString(sendData);
|
||||
|
||||
try
|
||||
|
@ -144,14 +159,10 @@ namespace OpenSim.Services.Connectors
|
|||
|
||||
}
|
||||
|
||||
public bool StoreFriend(UUID PrincipalID, string Friend, int flags)
|
||||
public bool StoreFriend(string PrincipalID, string Friend, int flags)
|
||||
{
|
||||
FriendInfo finfo = new FriendInfo();
|
||||
finfo.PrincipalID = PrincipalID;
|
||||
finfo.Friend = Friend;
|
||||
finfo.MyFlags = flags;
|
||||
|
||||
Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
|
||||
Dictionary<string, object> sendData = ToKeyValuePairs(PrincipalID, Friend, flags);
|
||||
|
||||
sendData["METHOD"] = "storefriend";
|
||||
|
||||
|
@ -189,6 +200,16 @@ namespace OpenSim.Services.Connectors
|
|||
|
||||
}
|
||||
|
||||
public bool Delete(string PrincipalID, string Friend)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["PRINCIPALID"] = PrincipalID.ToString();
|
||||
sendData["FRIEND"] = Friend;
|
||||
sendData["METHOD"] = "deletefriend_string";
|
||||
|
||||
return Delete(sendData, PrincipalID, Friend);
|
||||
}
|
||||
|
||||
public bool Delete(UUID PrincipalID, string Friend)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
|
@ -196,6 +217,11 @@ namespace OpenSim.Services.Connectors
|
|||
sendData["FRIEND"] = Friend;
|
||||
sendData["METHOD"] = "deletefriend";
|
||||
|
||||
return Delete(sendData, PrincipalID.ToString(), Friend);
|
||||
}
|
||||
|
||||
public bool Delete(Dictionary<string, object> sendData, string PrincipalID, string Friend)
|
||||
{
|
||||
string reply = string.Empty;
|
||||
try
|
||||
{
|
||||
|
@ -230,5 +256,16 @@ namespace OpenSim.Services.Connectors
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Dictionary<string, object> ToKeyValuePairs(string principalID, string friend, int flags)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
result["PrincipalID"] = principalID;
|
||||
result["Friend"] = friend;
|
||||
result["MyFlags"] = flags;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* 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 log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.Friends;
|
||||
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Services.Connectors.Hypergrid
|
||||
{
|
||||
public class HGFriendsServicesConnector
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_ServerURI = String.Empty;
|
||||
private string m_ServiceKey = String.Empty;
|
||||
private UUID m_SessionID;
|
||||
|
||||
public HGFriendsServicesConnector()
|
||||
{
|
||||
}
|
||||
|
||||
public HGFriendsServicesConnector(string serverURI)
|
||||
{
|
||||
m_ServerURI = serverURI.TrimEnd('/');
|
||||
}
|
||||
|
||||
public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey)
|
||||
{
|
||||
m_ServerURI = serverURI.TrimEnd('/');
|
||||
m_ServiceKey = serviceKey;
|
||||
m_SessionID = sessionID;
|
||||
}
|
||||
|
||||
#region IFriendsService
|
||||
|
||||
public uint GetFriendPerms(UUID PrincipalID, UUID friendID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
|
||||
sendData["PRINCIPALID"] = PrincipalID.ToString();
|
||||
sendData["FRIENDID"] = friendID.ToString();
|
||||
sendData["METHOD"] = "getfriendperms";
|
||||
sendData["KEY"] = m_ServiceKey;
|
||||
sendData["SESSIONID"] = m_SessionID.ToString();
|
||||
|
||||
string reqString = ServerUtils.BuildQueryString(sendData);
|
||||
|
||||
try
|
||||
{
|
||||
string reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "/hgfriends",
|
||||
reqString);
|
||||
if (reply != string.Empty)
|
||||
{
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
|
||||
|
||||
if ((replyData != null) && replyData.ContainsKey("Value") && (replyData["Value"] != null))
|
||||
{
|
||||
uint perms = 0;
|
||||
uint.TryParse(replyData["Value"].ToString(), out perms);
|
||||
return perms;
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriendPerms {0} received null response",
|
||||
PrincipalID);
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
public bool NewFriendship(UUID PrincipalID, string Friend)
|
||||
{
|
||||
FriendInfo finfo = new FriendInfo();
|
||||
finfo.PrincipalID = PrincipalID;
|
||||
finfo.Friend = Friend;
|
||||
|
||||
Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
|
||||
|
||||
sendData["METHOD"] = "newfriendship";
|
||||
sendData["KEY"] = m_ServiceKey;
|
||||
sendData["SESSIONID"] = m_SessionID.ToString();
|
||||
|
||||
string reply = string.Empty;
|
||||
try
|
||||
{
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "/hgfriends",
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply != string.Empty)
|
||||
{
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
|
||||
|
||||
if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
|
||||
{
|
||||
bool success = false;
|
||||
Boolean.TryParse(replyData["Result"].ToString(), out success);
|
||||
return success;
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend {0} {1} received null response",
|
||||
PrincipalID, Friend);
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend received null reply");
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public bool DeleteFriendship(UUID PrincipalID, UUID Friend, string secret)
|
||||
{
|
||||
FriendInfo finfo = new FriendInfo();
|
||||
finfo.PrincipalID = PrincipalID;
|
||||
finfo.Friend = Friend.ToString();
|
||||
|
||||
Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
|
||||
|
||||
sendData["METHOD"] = "deletefriendship";
|
||||
sendData["SECRET"] = secret;
|
||||
|
||||
string reply = string.Empty;
|
||||
try
|
||||
{
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "/hgfriends",
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply != string.Empty)
|
||||
{
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
|
||||
|
||||
if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
|
||||
{
|
||||
bool success = false;
|
||||
Boolean.TryParse(replyData["Result"].ToString(), out success);
|
||||
return success;
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Delete {0} {1} received null response",
|
||||
PrincipalID, Friend);
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: DeleteFriend received null reply");
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -400,6 +400,329 @@ namespace OpenSim.Services.Connectors.Hypergrid
|
|||
GetBoolResponse(request, out reason);
|
||||
}
|
||||
|
||||
public List<UUID> StatusNotification(List<string> friends, UUID userID, bool online)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
hash["userID"] = userID.ToString();
|
||||
hash["online"] = online.ToString();
|
||||
int i = 0;
|
||||
foreach (string s in friends)
|
||||
{
|
||||
hash["friend_" + i.ToString()] = s;
|
||||
i++;
|
||||
}
|
||||
|
||||
IList paramList = new ArrayList();
|
||||
paramList.Add(hash);
|
||||
|
||||
XmlRpcRequest request = new XmlRpcRequest("status_notification", paramList);
|
||||
string reason = string.Empty;
|
||||
|
||||
// Send and get reply
|
||||
List<UUID> friendsOnline = new List<UUID>();
|
||||
XmlRpcResponse response = null;
|
||||
try
|
||||
{
|
||||
response = request.Send(m_ServerURL, 10000);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
|
||||
reason = "Exception: " + e.Message;
|
||||
return friendsOnline;
|
||||
}
|
||||
|
||||
if (response.IsFault)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
|
||||
reason = "XMLRPC Fault";
|
||||
return friendsOnline;
|
||||
}
|
||||
|
||||
hash = (Hashtable)response.Value;
|
||||
//foreach (Object o in hash)
|
||||
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
|
||||
try
|
||||
{
|
||||
if (hash == null)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
|
||||
reason = "Internal error 1";
|
||||
return friendsOnline;
|
||||
}
|
||||
|
||||
// Here is the actual response
|
||||
foreach (object key in hash.Keys)
|
||||
{
|
||||
if (key is string && ((string)key).StartsWith("friend_") && hash[key] != null)
|
||||
{
|
||||
UUID uuid;
|
||||
if (UUID.TryParse(hash[key].ToString(), out uuid))
|
||||
friendsOnline.Add(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
|
||||
reason = "Exception: " + e.Message;
|
||||
}
|
||||
|
||||
return friendsOnline;
|
||||
}
|
||||
|
||||
public List<UUID> GetOnlineFriends(UUID userID, List<string> friends)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
hash["userID"] = userID.ToString();
|
||||
int i = 0;
|
||||
foreach (string s in friends)
|
||||
{
|
||||
hash["friend_" + i.ToString()] = s;
|
||||
i++;
|
||||
}
|
||||
|
||||
IList paramList = new ArrayList();
|
||||
paramList.Add(hash);
|
||||
|
||||
XmlRpcRequest request = new XmlRpcRequest("get_online_friends", paramList);
|
||||
string reason = string.Empty;
|
||||
|
||||
// Send and get reply
|
||||
List<UUID> online = new List<UUID>();
|
||||
XmlRpcResponse response = null;
|
||||
try
|
||||
{
|
||||
response = request.Send(m_ServerURL, 10000);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
|
||||
reason = "Exception: " + e.Message;
|
||||
return online;
|
||||
}
|
||||
|
||||
if (response.IsFault)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
|
||||
reason = "XMLRPC Fault";
|
||||
return online;
|
||||
}
|
||||
|
||||
hash = (Hashtable)response.Value;
|
||||
//foreach (Object o in hash)
|
||||
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
|
||||
try
|
||||
{
|
||||
if (hash == null)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
|
||||
reason = "Internal error 1";
|
||||
return online;
|
||||
}
|
||||
|
||||
// Here is the actual response
|
||||
foreach (object key in hash.Keys)
|
||||
{
|
||||
if (key is string && ((string)key).StartsWith("friend_") && hash[key] != null)
|
||||
{
|
||||
UUID uuid;
|
||||
if (UUID.TryParse(hash[key].ToString(), out uuid))
|
||||
online.Add(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
|
||||
reason = "Exception: " + e.Message;
|
||||
}
|
||||
|
||||
return online;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> GetServerURLs(UUID userID)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
hash["userID"] = userID.ToString();
|
||||
|
||||
IList paramList = new ArrayList();
|
||||
paramList.Add(hash);
|
||||
|
||||
XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList);
|
||||
string reason = string.Empty;
|
||||
|
||||
// Send and get reply
|
||||
Dictionary<string, object> serverURLs = new Dictionary<string,object>();
|
||||
XmlRpcResponse response = null;
|
||||
try
|
||||
{
|
||||
response = request.Send(m_ServerURL, 10000);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
|
||||
reason = "Exception: " + e.Message;
|
||||
return serverURLs;
|
||||
}
|
||||
|
||||
if (response.IsFault)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
|
||||
reason = "XMLRPC Fault";
|
||||
return serverURLs;
|
||||
}
|
||||
|
||||
hash = (Hashtable)response.Value;
|
||||
//foreach (Object o in hash)
|
||||
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
|
||||
try
|
||||
{
|
||||
if (hash == null)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
|
||||
reason = "Internal error 1";
|
||||
return serverURLs;
|
||||
}
|
||||
|
||||
// Here is the actual response
|
||||
foreach (object key in hash.Keys)
|
||||
{
|
||||
if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null)
|
||||
{
|
||||
string serverType = key.ToString().Substring(4); // remove "SRV_"
|
||||
serverURLs.Add(serverType, hash[key].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
|
||||
reason = "Exception: " + e.Message;
|
||||
}
|
||||
|
||||
return serverURLs;
|
||||
}
|
||||
|
||||
public string LocateUser(UUID userID)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
hash["userID"] = userID.ToString();
|
||||
|
||||
IList paramList = new ArrayList();
|
||||
paramList.Add(hash);
|
||||
|
||||
XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList);
|
||||
string reason = string.Empty;
|
||||
|
||||
// Send and get reply
|
||||
string url = string.Empty;
|
||||
XmlRpcResponse response = null;
|
||||
try
|
||||
{
|
||||
response = request.Send(m_ServerURL, 10000);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
|
||||
reason = "Exception: " + e.Message;
|
||||
return url;
|
||||
}
|
||||
|
||||
if (response.IsFault)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
|
||||
reason = "XMLRPC Fault";
|
||||
return url;
|
||||
}
|
||||
|
||||
hash = (Hashtable)response.Value;
|
||||
//foreach (Object o in hash)
|
||||
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
|
||||
try
|
||||
{
|
||||
if (hash == null)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
|
||||
reason = "Internal error 1";
|
||||
return url;
|
||||
}
|
||||
|
||||
// Here's the actual response
|
||||
if (hash.ContainsKey("URL"))
|
||||
url = hash["URL"].ToString();
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
|
||||
reason = "Exception: " + e.Message;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public string GetUUI(UUID userID, UUID targetUserID)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
hash["userID"] = userID.ToString();
|
||||
hash["targetUserID"] = targetUserID.ToString();
|
||||
|
||||
IList paramList = new ArrayList();
|
||||
paramList.Add(hash);
|
||||
|
||||
XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList);
|
||||
string reason = string.Empty;
|
||||
|
||||
// Send and get reply
|
||||
string uui = string.Empty;
|
||||
XmlRpcResponse response = null;
|
||||
try
|
||||
{
|
||||
response = request.Send(m_ServerURL, 10000);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
|
||||
reason = "Exception: " + e.Message;
|
||||
return uui;
|
||||
}
|
||||
|
||||
if (response.IsFault)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
|
||||
reason = "XMLRPC Fault";
|
||||
return uui;
|
||||
}
|
||||
|
||||
hash = (Hashtable)response.Value;
|
||||
//foreach (Object o in hash)
|
||||
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
|
||||
try
|
||||
{
|
||||
if (hash == null)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
|
||||
reason = "Internal error 1";
|
||||
return uui;
|
||||
}
|
||||
|
||||
// Here's the actual response
|
||||
if (hash.ContainsKey("UUI"))
|
||||
uui = hash["UUI"].ToString();
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
|
||||
reason = "Exception: " + e.Message;
|
||||
}
|
||||
|
||||
return uui;
|
||||
}
|
||||
|
||||
private bool GetBoolResponse(XmlRpcRequest request, out string reason)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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 OpenMetaverse;
|
||||
using Nwc.XmlRpc;
|
||||
using log4net;
|
||||
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Services.Connectors.InstantMessage
|
||||
{
|
||||
public class InstantMessageServiceConnector
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// This actually does the XMLRPC Request
|
||||
/// </summary>
|
||||
/// <param name="url">URL we pull the data out of to send the request to</param>
|
||||
/// <param name="im">The Instant Message </param>
|
||||
/// <returns>Bool if the message was successfully delivered at the other side.</returns>
|
||||
public static bool SendInstantMessage(string url, GridInstantMessage im)
|
||||
{
|
||||
Hashtable xmlrpcdata = ConvertGridInstantMessageToXMLRPC(im);
|
||||
xmlrpcdata["region_handle"] = 0;
|
||||
|
||||
ArrayList SendParams = new ArrayList();
|
||||
SendParams.Add(xmlrpcdata);
|
||||
XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams);
|
||||
try
|
||||
{
|
||||
|
||||
XmlRpcResponse GridResp = GridReq.Send(url, 10000);
|
||||
|
||||
Hashtable responseData = (Hashtable)GridResp.Value;
|
||||
|
||||
if (responseData.ContainsKey("success"))
|
||||
{
|
||||
if ((string)responseData["success"] == "TRUE")
|
||||
{
|
||||
//m_log.DebugFormat("[XXX] Success");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//m_log.DebugFormat("[XXX] Fail");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[GRID INSTANT MESSAGE]: No response from {0}", url);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0} the host didn't respond " + e.ToString(), url);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes a GridInstantMessage and converts it into a Hashtable for XMLRPC
|
||||
/// </summary>
|
||||
/// <param name="msg">The GridInstantMessage object</param>
|
||||
/// <returns>Hashtable containing the XMLRPC request</returns>
|
||||
protected static Hashtable ConvertGridInstantMessageToXMLRPC(GridInstantMessage msg)
|
||||
{
|
||||
Hashtable gim = new Hashtable();
|
||||
gim["from_agent_id"] = msg.fromAgentID.ToString();
|
||||
// Kept for compatibility
|
||||
gim["from_agent_session"] = UUID.Zero.ToString();
|
||||
gim["to_agent_id"] = msg.toAgentID.ToString();
|
||||
gim["im_session_id"] = msg.imSessionID.ToString();
|
||||
gim["timestamp"] = msg.timestamp.ToString();
|
||||
gim["from_agent_name"] = msg.fromAgentName;
|
||||
gim["message"] = msg.message;
|
||||
byte[] dialogdata = new byte[1]; dialogdata[0] = msg.dialog;
|
||||
gim["dialog"] = Convert.ToBase64String(dialogdata, Base64FormattingOptions.None);
|
||||
|
||||
if (msg.fromGroup)
|
||||
gim["from_group"] = "TRUE";
|
||||
else
|
||||
gim["from_group"] = "FALSE";
|
||||
byte[] offlinedata = new byte[1]; offlinedata[0] = msg.offline;
|
||||
gim["offline"] = Convert.ToBase64String(offlinedata, Base64FormattingOptions.None);
|
||||
gim["parent_estate_id"] = msg.ParentEstateID.ToString();
|
||||
gim["position_x"] = msg.Position.X.ToString();
|
||||
gim["position_y"] = msg.Position.Y.ToString();
|
||||
gim["position_z"] = msg.Position.Z.ToString();
|
||||
gim["region_id"] = msg.RegionID.ToString();
|
||||
gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None);
|
||||
|
||||
return gim;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -77,6 +77,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
#region IFriendsService
|
||||
|
||||
public FriendInfo[] GetFriends(UUID principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
public FriendInfo[] GetFriends(string principalID)
|
||||
{
|
||||
if (String.IsNullOrEmpty(m_serverUrl))
|
||||
return new FriendInfo[0];
|
||||
|
@ -95,7 +100,14 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
UUID friendID = friendEntry["Key"].AsUUID();
|
||||
|
||||
FriendInfo friend = new FriendInfo();
|
||||
friend.PrincipalID = principalID;
|
||||
if (!UUID.TryParse(principalID, out friend.PrincipalID))
|
||||
{
|
||||
string tmp = string.Empty;
|
||||
if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp, out tmp))
|
||||
// bad record. ignore this entry
|
||||
continue;
|
||||
}
|
||||
|
||||
friend.Friend = friendID.ToString();
|
||||
friend.MyFlags = friendEntry["Value"].AsInteger();
|
||||
friend.TheirFlags = -1;
|
||||
|
@ -127,7 +139,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
return array;
|
||||
}
|
||||
|
||||
public bool StoreFriend(UUID principalID, string friend, int flags)
|
||||
public bool StoreFriend(string principalID, string friend, int flags)
|
||||
{
|
||||
if (String.IsNullOrEmpty(m_serverUrl))
|
||||
return true;
|
||||
|
@ -151,6 +163,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
}
|
||||
|
||||
public bool Delete(UUID principalID, string friend)
|
||||
{
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
if (String.IsNullOrEmpty(m_serverUrl))
|
||||
return true;
|
||||
|
@ -174,7 +191,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
|
||||
#endregion IFriendsService
|
||||
|
||||
private OSDArray GetFriended(UUID ownerID)
|
||||
private OSDArray GetFriended(string ownerID)
|
||||
{
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
|
@ -195,7 +212,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
}
|
||||
}
|
||||
|
||||
private OSDArray GetFriendedBy(UUID ownerID)
|
||||
private OSDArray GetFriendedBy(string ownerID)
|
||||
{
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
|
|
|
@ -103,16 +103,31 @@ namespace OpenSim.Services.Connectors.Simulation
|
|||
args["teleport_flags"] = OSD.FromString(flags.ToString());
|
||||
|
||||
OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000);
|
||||
if (result["Success"].AsBoolean())
|
||||
return true;
|
||||
|
||||
bool success = result["success"].AsBoolean();
|
||||
if (success && result.ContainsKey("_Result"))
|
||||
{
|
||||
OSDMap data = (OSDMap)result["_Result"];
|
||||
|
||||
reason = data["reason"].AsString();
|
||||
success = data["success"].AsBoolean();
|
||||
return success;
|
||||
}
|
||||
|
||||
// Try the old version, uncompressed
|
||||
result = WebUtil.PostToService(uri, args, 30000);
|
||||
|
||||
if (result["Success"].AsBoolean())
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName);
|
||||
return true;
|
||||
if (result.ContainsKey("_Result"))
|
||||
{
|
||||
OSDMap data = (OSDMap)result["_Result"];
|
||||
|
||||
reason = data["reason"].AsString();
|
||||
success = data["success"].AsBoolean();
|
||||
m_log.WarnFormat(
|
||||
"[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
m_log.WarnFormat(
|
||||
|
|
|
@ -54,10 +54,10 @@ namespace OpenSim.Services.FreeswitchService
|
|||
|
||||
Hashtable response = new Hashtable();
|
||||
|
||||
foreach (DictionaryEntry item in request)
|
||||
{
|
||||
// m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value);
|
||||
}
|
||||
// foreach (DictionaryEntry item in request)
|
||||
// {
|
||||
//// m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value);
|
||||
// }
|
||||
|
||||
string requestcontext = (string) request["Hunt-Context"];
|
||||
response["content_type"] = "text/xml";
|
||||
|
|
|
@ -43,17 +43,16 @@ namespace OpenSim.Services.Friends
|
|||
{
|
||||
}
|
||||
|
||||
public FriendInfo[] GetFriends(UUID PrincipalID)
|
||||
public virtual FriendInfo[] GetFriends(UUID PrincipalID)
|
||||
{
|
||||
FriendsData[] data = m_Database.GetFriends(PrincipalID);
|
||||
|
||||
List<FriendInfo> info = new List<FriendInfo>();
|
||||
|
||||
foreach (FriendsData d in data)
|
||||
{
|
||||
FriendInfo i = new FriendInfo();
|
||||
|
||||
i.PrincipalID = d.PrincipalID;
|
||||
i.PrincipalID = new UUID(d.PrincipalID);
|
||||
i.Friend = d.Friend;
|
||||
i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
|
||||
i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
|
||||
|
@ -64,7 +63,33 @@ namespace OpenSim.Services.Friends
|
|||
return info.ToArray();
|
||||
}
|
||||
|
||||
public bool StoreFriend(UUID PrincipalID, string Friend, int flags)
|
||||
public virtual FriendInfo[] GetFriends(string PrincipalID)
|
||||
{
|
||||
FriendsData[] data = m_Database.GetFriends(PrincipalID);
|
||||
List<FriendInfo> info = new List<FriendInfo>();
|
||||
|
||||
foreach (FriendsData d in data)
|
||||
{
|
||||
FriendInfo i = new FriendInfo();
|
||||
|
||||
if (!UUID.TryParse(d.PrincipalID, out i.PrincipalID))
|
||||
{
|
||||
string tmp = string.Empty;
|
||||
if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp, out tmp))
|
||||
// bad record. ignore this entry
|
||||
continue;
|
||||
}
|
||||
i.Friend = d.Friend;
|
||||
i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
|
||||
i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
|
||||
|
||||
info.Add(i);
|
||||
}
|
||||
|
||||
return info.ToArray();
|
||||
}
|
||||
|
||||
public virtual bool StoreFriend(string PrincipalID, string Friend, int flags)
|
||||
{
|
||||
FriendsData d = new FriendsData();
|
||||
|
||||
|
@ -76,7 +101,12 @@ namespace OpenSim.Services.Friends
|
|||
return m_Database.Store(d);
|
||||
}
|
||||
|
||||
public bool Delete(UUID PrincipalID, string Friend)
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
return m_Database.Delete(principalID, friend);
|
||||
}
|
||||
|
||||
public virtual bool Delete(UUID PrincipalID, string Friend)
|
||||
{
|
||||
return m_Database.Delete(PrincipalID, Friend);
|
||||
}
|
||||
|
|
|
@ -327,10 +327,13 @@ namespace OpenSim.Services.GridService
|
|||
else
|
||||
regInfo.RegionName = externalName;
|
||||
|
||||
m_log.Debug("[HYPERGRID LINKER]: naming linked region " + regInfo.RegionName);
|
||||
m_log.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString());
|
||||
|
||||
// Get the map image
|
||||
regInfo.TerrainImage = m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory);
|
||||
regInfo.TerrainImage = GetMapImage(regionID, imageURL);
|
||||
|
||||
// Store the origin's coordinates somewhere
|
||||
regInfo.RegionSecret = handle.ToString();
|
||||
|
||||
AddHyperlinkRegion(regInfo, handle);
|
||||
m_log.Info("[HYPERGRID LINKER]: Successfully linked to region_uuid " + regInfo.RegionID);
|
||||
|
@ -427,6 +430,10 @@ namespace OpenSim.Services.GridService
|
|||
m_Database.Delete(regionID);
|
||||
}
|
||||
|
||||
public UUID GetMapImage(UUID regionID, string imageURL)
|
||||
{
|
||||
return m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
* 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.Net;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Services.Connectors.Friends;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.InstantMessage;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
using OpenSim.Server.Base;
|
||||
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Services.HypergridService
|
||||
{
|
||||
/// <summary>
|
||||
/// Inter-grid IM
|
||||
/// </summary>
|
||||
public class HGInstantMessageService : IInstantMessage
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours
|
||||
|
||||
static bool m_Initialized = false;
|
||||
|
||||
protected static IGridService m_GridService;
|
||||
protected static IPresenceService m_PresenceService;
|
||||
protected static IUserAgentService m_UserAgentService;
|
||||
|
||||
protected static IInstantMessageSimConnector m_IMSimConnector;
|
||||
|
||||
protected static Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
|
||||
private static ExpiringCache<UUID, GridRegion> m_RegionCache;
|
||||
|
||||
private static string m_RestURL;
|
||||
private static bool m_ForwardOfflineGroupMessages;
|
||||
private static bool m_InGatekeeper;
|
||||
|
||||
public HGInstantMessageService(IConfigSource config)
|
||||
: this(config, null)
|
||||
{
|
||||
}
|
||||
|
||||
public HGInstantMessageService(IConfigSource config, IInstantMessageSimConnector imConnector)
|
||||
{
|
||||
if (imConnector != null)
|
||||
m_IMSimConnector = imConnector;
|
||||
|
||||
if (!m_Initialized)
|
||||
{
|
||||
m_Initialized = true;
|
||||
|
||||
IConfig serverConfig = config.Configs["HGInstantMessageService"];
|
||||
if (serverConfig == null)
|
||||
throw new Exception(String.Format("No section HGInstantMessageService in config file"));
|
||||
|
||||
string gridService = serverConfig.GetString("GridService", String.Empty);
|
||||
string presenceService = serverConfig.GetString("PresenceService", String.Empty);
|
||||
string userAgentService = serverConfig.GetString("UserAgentService", String.Empty);
|
||||
m_InGatekeeper = serverConfig.GetBoolean("InGatekeeper", false);
|
||||
m_log.DebugFormat("[HG IM SERVICE]: Starting... InRobust? {0}", m_InGatekeeper);
|
||||
|
||||
|
||||
if (gridService == string.Empty || presenceService == string.Empty)
|
||||
throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function."));
|
||||
|
||||
Object[] args = new Object[] { config };
|
||||
m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
|
||||
m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
|
||||
m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(userAgentService, args);
|
||||
|
||||
m_RegionCache = new ExpiringCache<UUID, GridRegion>();
|
||||
|
||||
IConfig cnf = config.Configs["Messaging"];
|
||||
if (cnf == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_RestURL = cnf.GetString("OfflineMessageURL", string.Empty);
|
||||
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public bool IncomingInstantMessage(GridInstantMessage im)
|
||||
{
|
||||
m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID);
|
||||
UUID toAgentID = new UUID(im.toAgentID);
|
||||
|
||||
bool success = false;
|
||||
if (m_IMSimConnector != null)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX] SendIMToRegion local im connector");
|
||||
success = m_IMSimConnector.SendInstantMessage(im);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = TrySendInstantMessage(im, "", true, false);
|
||||
}
|
||||
|
||||
if (!success && m_InGatekeeper) // we do this only in the Gatekeeper IM service
|
||||
UndeliveredMessage(im);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner)
|
||||
{
|
||||
m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url);
|
||||
if (url != string.Empty)
|
||||
return TrySendInstantMessage(im, url, true, foreigner);
|
||||
else
|
||||
{
|
||||
PresenceInfo upd = new PresenceInfo();
|
||||
upd.RegionID = UUID.Zero;
|
||||
return TrySendInstantMessage(im, upd, true, foreigner);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected bool TrySendInstantMessage(GridInstantMessage im, object previousLocation, bool firstTime, bool foreigner)
|
||||
{
|
||||
UUID toAgentID = new UUID(im.toAgentID);
|
||||
|
||||
PresenceInfo upd = null;
|
||||
string url = string.Empty;
|
||||
|
||||
bool lookupAgent = false;
|
||||
|
||||
lock (m_UserLocationMap)
|
||||
{
|
||||
if (m_UserLocationMap.ContainsKey(toAgentID))
|
||||
{
|
||||
object o = m_UserLocationMap[toAgentID];
|
||||
if (o is PresenceInfo)
|
||||
upd = (PresenceInfo)o;
|
||||
else if (o is string)
|
||||
url = (string)o;
|
||||
|
||||
// We need to compare the current location with the previous
|
||||
// or the recursive loop will never end because it will never try to lookup the agent again
|
||||
if (!firstTime)
|
||||
{
|
||||
lookupAgent = true;
|
||||
upd = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lookupAgent = true;
|
||||
}
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX] Neeed lookup ? {0}", (lookupAgent ? "yes" : "no"));
|
||||
|
||||
// Are we needing to look-up an agent?
|
||||
if (lookupAgent)
|
||||
{
|
||||
// Non-cached user agent lookup.
|
||||
PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { toAgentID.ToString() });
|
||||
if (presences != null && presences.Length > 0)
|
||||
{
|
||||
foreach (PresenceInfo p in presences)
|
||||
{
|
||||
if (p.RegionID != UUID.Zero)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: Found presence in {0}", p.RegionID);
|
||||
upd = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (upd == null && !foreigner)
|
||||
{
|
||||
// Let's check with the UAS if the user is elsewhere
|
||||
m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service");
|
||||
url = m_UserAgentService.LocateUser(toAgentID);
|
||||
}
|
||||
|
||||
// check if we've tried this before..
|
||||
// This is one way to end the recursive loop
|
||||
//
|
||||
if (!firstTime && ((previousLocation is PresenceInfo && upd != null && upd.RegionID == ((PresenceInfo)previousLocation).RegionID) ||
|
||||
(previousLocation is string && upd == null && previousLocation.Equals(url))))
|
||||
{
|
||||
// m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
|
||||
m_log.DebugFormat("[HG IM SERVICE]: Fail 2 {0} {1}", previousLocation, url);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (upd != null)
|
||||
{
|
||||
// ok, the user is around somewhere. Let's send back the reply with "success"
|
||||
// even though the IM may still fail. Just don't keep the caller waiting for
|
||||
// the entire time we're trying to deliver the IM
|
||||
return SendIMToRegion(upd, im, toAgentID, foreigner);
|
||||
}
|
||||
else if (url != string.Empty)
|
||||
{
|
||||
// ok, the user is around somewhere. Let's send back the reply with "success"
|
||||
// even though the IM may still fail. Just don't keep the caller waiting for
|
||||
// the entire time we're trying to deliver the IM
|
||||
return ForwardIMToGrid(url, im, toAgentID, foreigner);
|
||||
}
|
||||
else if (firstTime && previousLocation is string && (string)previousLocation != string.Empty)
|
||||
{
|
||||
return ForwardIMToGrid((string)previousLocation, im, toAgentID, foreigner);
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[HG IM SERVICE]: Unable to locate user {0}", toAgentID);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SendIMToRegion(PresenceInfo upd, GridInstantMessage im, UUID toAgentID, bool foreigner)
|
||||
{
|
||||
bool imresult = false;
|
||||
GridRegion reginfo = null;
|
||||
if (!m_RegionCache.TryGetValue(upd.RegionID, out reginfo))
|
||||
{
|
||||
reginfo = m_GridService.GetRegionByUUID(UUID.Zero /*!!!*/, upd.RegionID);
|
||||
if (reginfo != null)
|
||||
m_RegionCache.AddOrUpdate(upd.RegionID, reginfo, CACHE_EXPIRATION_SECONDS);
|
||||
}
|
||||
|
||||
if (reginfo != null)
|
||||
{
|
||||
imresult = InstantMessageServiceConnector.SendInstantMessage(reginfo.ServerURI, im);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[HG IM SERVICE]: Failed to deliver message to {0}", reginfo.ServerURI);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (imresult)
|
||||
{
|
||||
// IM delivery successful, so store the Agent's location in our local cache.
|
||||
lock (m_UserLocationMap)
|
||||
{
|
||||
if (m_UserLocationMap.ContainsKey(toAgentID))
|
||||
{
|
||||
m_UserLocationMap[toAgentID] = upd;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_UserLocationMap.Add(toAgentID, upd);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// try again, but lookup user this time.
|
||||
// Warning, this must call the Async version
|
||||
// of this method or we'll be making thousands of threads
|
||||
// The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
|
||||
// The version that spawns the thread is SendGridInstantMessageViaXMLRPC
|
||||
|
||||
// This is recursive!!!!!
|
||||
return TrySendInstantMessage(im, upd, false, foreigner);
|
||||
}
|
||||
}
|
||||
|
||||
bool ForwardIMToGrid(string url, GridInstantMessage im, UUID toAgentID, bool foreigner)
|
||||
{
|
||||
if (InstantMessageServiceConnector.SendInstantMessage(url, im))
|
||||
{
|
||||
// IM delivery successful, so store the Agent's location in our local cache.
|
||||
lock (m_UserLocationMap)
|
||||
{
|
||||
if (m_UserLocationMap.ContainsKey(toAgentID))
|
||||
{
|
||||
m_UserLocationMap[toAgentID] = url;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_UserLocationMap.Add(toAgentID, url);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// try again, but lookup user this time.
|
||||
|
||||
// This is recursive!!!!!
|
||||
return TrySendInstantMessage(im, url, false, foreigner);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private bool UndeliveredMessage(GridInstantMessage im)
|
||||
{
|
||||
if (m_RestURL != string.Empty && (im.offline != 0)
|
||||
&& (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
|
||||
{
|
||||
m_log.DebugFormat("[HG IM SERVICE]: Message saved");
|
||||
return SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
|
||||
"POST", m_RestURL + "/SaveMessage/", im);
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -134,6 +134,7 @@ namespace OpenSim.Services.HypergridService
|
|||
|
||||
public override InventoryFolderBase GetRootFolder(UUID principalID)
|
||||
{
|
||||
//m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID);
|
||||
// Warp! Root folder for travelers
|
||||
XInventoryFolder[] folders = m_Database.GetFolders(
|
||||
new string[] { "agentID", "folderName"},
|
||||
|
@ -171,6 +172,7 @@ namespace OpenSim.Services.HypergridService
|
|||
|
||||
public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
|
||||
{
|
||||
//m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type);
|
||||
return GetRootFolder(principalID);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,12 @@ using System.Net;
|
|||
using System.Reflection;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Services.Connectors.Friends;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
using OpenSim.Server.Base;
|
||||
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
|
@ -63,19 +65,35 @@ namespace OpenSim.Services.HypergridService
|
|||
protected static IGridService m_GridService;
|
||||
protected static GatekeeperServiceConnector m_GatekeeperConnector;
|
||||
protected static IGatekeeperService m_GatekeeperService;
|
||||
protected static IFriendsService m_FriendsService;
|
||||
protected static IPresenceService m_PresenceService;
|
||||
protected static IUserAccountService m_UserAccountService;
|
||||
protected static IFriendsSimConnector m_FriendsLocalSimConnector; // standalone, points to HGFriendsModule
|
||||
protected static FriendsSimConnector m_FriendsSimConnector; // grid
|
||||
|
||||
protected static string m_GridName;
|
||||
|
||||
protected static bool m_BypassClientVerification;
|
||||
|
||||
public UserAgentService(IConfigSource config)
|
||||
public UserAgentService(IConfigSource config) : this(config, null)
|
||||
{
|
||||
}
|
||||
|
||||
public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector)
|
||||
{
|
||||
// Let's set this always, because we don't know the sequence
|
||||
// of instantiations
|
||||
if (friendsConnector != null)
|
||||
m_FriendsLocalSimConnector = friendsConnector;
|
||||
|
||||
if (!m_Initialized)
|
||||
{
|
||||
m_Initialized = true;
|
||||
|
||||
m_log.DebugFormat("[HOME USERS SECURITY]: Starting...");
|
||||
|
||||
|
||||
m_FriendsSimConnector = new FriendsSimConnector();
|
||||
|
||||
IConfig serverConfig = config.Configs["UserAgentService"];
|
||||
if (serverConfig == null)
|
||||
throw new Exception(String.Format("No section UserAgentService in config file"));
|
||||
|
@ -83,6 +101,9 @@ namespace OpenSim.Services.HypergridService
|
|||
string gridService = serverConfig.GetString("GridService", String.Empty);
|
||||
string gridUserService = serverConfig.GetString("GridUserService", String.Empty);
|
||||
string gatekeeperService = serverConfig.GetString("GatekeeperService", String.Empty);
|
||||
string friendsService = serverConfig.GetString("FriendsService", String.Empty);
|
||||
string presenceService = serverConfig.GetString("PresenceService", String.Empty);
|
||||
string userAccountService = serverConfig.GetString("UserAccountService", String.Empty);
|
||||
|
||||
m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false);
|
||||
|
||||
|
@ -94,6 +115,9 @@ namespace OpenSim.Services.HypergridService
|
|||
m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
|
||||
m_GatekeeperConnector = new GatekeeperServiceConnector();
|
||||
m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args);
|
||||
m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(friendsService, args);
|
||||
m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
|
||||
m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountService, args);
|
||||
|
||||
m_GridName = serverConfig.GetString("ExternalName", string.Empty);
|
||||
if (m_GridName == string.Empty)
|
||||
|
@ -155,12 +179,17 @@ namespace OpenSim.Services.HypergridService
|
|||
string myExternalIP = string.Empty;
|
||||
string gridName = gatekeeper.ServerURI;
|
||||
|
||||
m_log.DebugFormat("[USER AGENT SERVICE]: m_grid - {0}, gn - {1}", m_GridName, gridName);
|
||||
|
||||
m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}", m_GridName, gridName);
|
||||
|
||||
if (m_GridName == gridName)
|
||||
success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason);
|
||||
else
|
||||
{
|
||||
success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason);
|
||||
if (success)
|
||||
// Report them as nowhere
|
||||
m_PresenceService.ReportAgent(agentCircuit.SessionID, UUID.Zero);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
|
@ -168,8 +197,11 @@ namespace OpenSim.Services.HypergridService
|
|||
agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason);
|
||||
|
||||
// restore the old travel info
|
||||
lock (m_TravelingAgents)
|
||||
m_TravelingAgents[agentCircuit.SessionID] = old;
|
||||
if(reason != "Logins Disabled")
|
||||
{
|
||||
lock (m_TravelingAgents)
|
||||
m_TravelingAgents[agentCircuit.SessionID] = old;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -179,6 +211,7 @@ namespace OpenSim.Services.HypergridService
|
|||
if (clientIP != null)
|
||||
m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString();
|
||||
m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -289,6 +322,213 @@ namespace OpenSim.Services.HypergridService
|
|||
return false;
|
||||
}
|
||||
|
||||
public List<UUID> StatusNotification(List<string> friends, UUID foreignUserID, bool online)
|
||||
{
|
||||
if (m_FriendsService == null || m_PresenceService == null)
|
||||
{
|
||||
m_log.WarnFormat("[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing");
|
||||
return new List<UUID>();
|
||||
}
|
||||
|
||||
List<UUID> localFriendsOnline = new List<UUID>();
|
||||
|
||||
m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count);
|
||||
|
||||
// First, let's double check that the reported friends are, indeed, friends of that user
|
||||
// And let's check that the secret matches
|
||||
List<string> usersToBeNotified = new List<string>();
|
||||
foreach (string uui in friends)
|
||||
{
|
||||
UUID localUserID;
|
||||
string secret = string.Empty, tmp = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
|
||||
{
|
||||
FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
|
||||
foreach (FriendInfo finfo in friendInfos)
|
||||
{
|
||||
if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret))
|
||||
{
|
||||
// great!
|
||||
usersToBeNotified.Add(localUserID.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now, let's send the notifications
|
||||
m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: user has {0} local friends", usersToBeNotified.Count);
|
||||
|
||||
// First, let's send notifications to local users who are online in the home grid
|
||||
PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
|
||||
if (friendSessions != null && friendSessions.Length > 0)
|
||||
{
|
||||
PresenceInfo friendSession = null;
|
||||
foreach (PresenceInfo pinfo in friendSessions)
|
||||
if (pinfo.RegionID != UUID.Zero) // let's guard against traveling agents
|
||||
{
|
||||
friendSession = pinfo;
|
||||
break;
|
||||
}
|
||||
|
||||
if (friendSession != null)
|
||||
{
|
||||
ForwardStatusNotificationToSim(friendSession.RegionID, foreignUserID, friendSession.UserID, online);
|
||||
usersToBeNotified.Remove(friendSession.UserID.ToString());
|
||||
UUID id;
|
||||
if (UUID.TryParse(friendSession.UserID, out id))
|
||||
localFriendsOnline.Add(id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, let's notify the rest who may be online somewhere else
|
||||
foreach (string user in usersToBeNotified)
|
||||
{
|
||||
UUID id = new UUID(user);
|
||||
if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName)
|
||||
{
|
||||
string url = m_TravelingAgents[id].GridExternalName;
|
||||
// forward
|
||||
m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
|
||||
}
|
||||
}
|
||||
|
||||
// and finally, let's send the online friends
|
||||
if (online)
|
||||
{
|
||||
return localFriendsOnline;
|
||||
}
|
||||
else
|
||||
return new List<UUID>();
|
||||
}
|
||||
|
||||
protected void ForwardStatusNotificationToSim(UUID regionID, UUID foreignUserID, string user, bool online)
|
||||
{
|
||||
UUID userID;
|
||||
if (UUID.TryParse(user, out userID))
|
||||
{
|
||||
if (m_FriendsLocalSimConnector != null)
|
||||
{
|
||||
m_log.DebugFormat("[USER AGENT SERVICE]: Local Notify, user {0} is {1}", foreignUserID, (online ? "online" : "offline"));
|
||||
m_FriendsLocalSimConnector.StatusNotify(foreignUserID, userID, online);
|
||||
}
|
||||
else
|
||||
{
|
||||
GridRegion region = m_GridService.GetRegionByUUID(UUID.Zero /* !!! */, regionID);
|
||||
if (region != null)
|
||||
{
|
||||
m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, foreignUserID, (online ? "online" : "offline"));
|
||||
m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID, online);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<UUID> GetOnlineFriends(UUID foreignUserID, List<string> friends)
|
||||
{
|
||||
List<UUID> online = new List<UUID>();
|
||||
|
||||
if (m_FriendsService == null || m_PresenceService == null)
|
||||
{
|
||||
m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get online friends because friends or presence services are missing");
|
||||
return online;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[USER AGENT SERVICE]: Foreign user {0} wants to know status of {1} local friends", foreignUserID, friends.Count);
|
||||
|
||||
// First, let's double check that the reported friends are, indeed, friends of that user
|
||||
// And let's check that the secret matches and the rights
|
||||
List<string> usersToBeNotified = new List<string>();
|
||||
foreach (string uui in friends)
|
||||
{
|
||||
UUID localUserID;
|
||||
string secret = string.Empty, tmp = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
|
||||
{
|
||||
FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
|
||||
foreach (FriendInfo finfo in friendInfos)
|
||||
{
|
||||
if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret) &&
|
||||
(finfo.TheirFlags & (int)FriendRights.CanSeeOnline) != 0 && (finfo.TheirFlags != -1))
|
||||
{
|
||||
// great!
|
||||
usersToBeNotified.Add(localUserID.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now, let's find out their status
|
||||
m_log.DebugFormat("[USER AGENT SERVICE]: GetOnlineFriends: user has {0} local friends with status rights", usersToBeNotified.Count);
|
||||
|
||||
// First, let's send notifications to local users who are online in the home grid
|
||||
PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
|
||||
if (friendSessions != null && friendSessions.Length > 0)
|
||||
{
|
||||
foreach (PresenceInfo pi in friendSessions)
|
||||
{
|
||||
UUID presenceID;
|
||||
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||
online.Add(presenceID);
|
||||
}
|
||||
}
|
||||
|
||||
return online;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> GetServerURLs(UUID userID)
|
||||
{
|
||||
if (m_UserAccountService == null)
|
||||
{
|
||||
m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get server URLs because user account service is missing");
|
||||
return new Dictionary<string, object>();
|
||||
}
|
||||
UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID);
|
||||
if (account != null)
|
||||
return account.ServiceURLs;
|
||||
|
||||
return new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public string LocateUser(UUID userID)
|
||||
{
|
||||
foreach (TravelingAgentInfo t in m_TravelingAgents.Values)
|
||||
{
|
||||
if (t == null)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis");
|
||||
continue;
|
||||
}
|
||||
if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName))
|
||||
return t.GridExternalName;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public string GetUUI(UUID userID, UUID targetUserID)
|
||||
{
|
||||
// Let's see if it's a local user
|
||||
UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, targetUserID);
|
||||
if (account != null)
|
||||
return targetUserID.ToString() + ";" + m_GridName + ";" + account.FirstName + " " + account.LastName ;
|
||||
|
||||
// Let's try the list of friends
|
||||
FriendInfo[] friends = m_FriendsService.GetFriends(userID);
|
||||
if (friends != null && friends.Length > 0)
|
||||
{
|
||||
foreach (FriendInfo f in friends)
|
||||
if (f.Friend.StartsWith(targetUserID.ToString()))
|
||||
{
|
||||
// Let's remove the secret
|
||||
UUID id; string tmp = string.Empty, secret = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(f.Friend, out id, out tmp, out tmp, out tmp, out secret))
|
||||
return f.Friend.Replace(secret, "0");
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
class TravelingAgentInfo
|
||||
|
|
|
@ -74,7 +74,9 @@ namespace OpenSim.Services.Interfaces
|
|||
public interface IFriendsService
|
||||
{
|
||||
FriendInfo[] GetFriends(UUID PrincipalID);
|
||||
bool StoreFriend(UUID PrincipalID, string Friend, int flags);
|
||||
FriendInfo[] GetFriends(string PrincipalID);
|
||||
bool StoreFriend(string PrincipalID, string Friend, int flags);
|
||||
bool Delete(UUID PrincipalID, string Friend);
|
||||
bool Delete(string PrincipalID, string Friend);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,9 +54,34 @@ namespace OpenSim.Services.Interfaces
|
|||
bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
|
||||
void LogoutAgent(UUID userID, UUID sessionID);
|
||||
GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
|
||||
Dictionary<string, object> GetServerURLs(UUID userID);
|
||||
|
||||
string LocateUser(UUID userID);
|
||||
// Tries to get the universal user identifier for the targetUserId
|
||||
// on behalf of the userID
|
||||
string GetUUI(UUID userID, UUID targetUserID);
|
||||
|
||||
// Returns the local friends online
|
||||
List<UUID> StatusNotification(List<string> friends, UUID userID, bool online);
|
||||
//List<UUID> GetOnlineFriends(UUID userID, List<string> friends);
|
||||
|
||||
bool AgentIsComingHome(UUID sessionID, string thisGridExternalName);
|
||||
bool VerifyAgent(UUID sessionID, string token);
|
||||
bool VerifyClient(UUID sessionID, string reportedIP);
|
||||
}
|
||||
|
||||
public interface IInstantMessage
|
||||
{
|
||||
bool IncomingInstantMessage(GridInstantMessage im);
|
||||
bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner);
|
||||
}
|
||||
public interface IFriendsSimConnector
|
||||
{
|
||||
bool StatusNotify(UUID userID, UUID friendID, bool online);
|
||||
}
|
||||
|
||||
public interface IInstantMessageSimConnector
|
||||
{
|
||||
bool SendInstantMessage(GridInstantMessage im);
|
||||
}
|
||||
}
|
|
@ -340,6 +340,9 @@ namespace OpenSim.Services.InventoryService
|
|||
List<InventoryItemBase> itemsList = new List<InventoryItemBase>();
|
||||
|
||||
itemsList.AddRange(m_Database.getInventoryInFolder(folderID));
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY SERVICE]: Found {0} items in folder {1} for {2}", itemsList.Count, folderID, userID);
|
||||
|
||||
return itemsList;
|
||||
}
|
||||
|
@ -385,8 +388,9 @@ namespace OpenSim.Services.InventoryService
|
|||
// See IInventoryServices
|
||||
public virtual bool AddItem(InventoryItemBase item)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[INVENTORY SERVICE]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder);
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2} for {3}",
|
||||
// item.Name, item.ID, item.Folder, item.Owner);
|
||||
|
||||
m_Database.addInventoryItem(item);
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService
|
|||
{
|
||||
public class XInventoryService : ServiceBase, IInventoryService
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(
|
||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||
//private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(
|
||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected IXInventoryData m_Database;
|
||||
protected bool m_AllowDelete = true;
|
||||
|
@ -385,8 +385,8 @@ namespace OpenSim.Services.InventoryService
|
|||
|
||||
public virtual bool AddItem(InventoryItemBase item)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner);
|
||||
//m_log.DebugFormat(
|
||||
// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner);
|
||||
|
||||
return m_Database.StoreItem(ConvertFromOpenSim(item));
|
||||
}
|
||||
|
|
|
@ -627,7 +627,19 @@ namespace OpenSim.Services.LLLoginService
|
|||
if (finfo.TheirFlags == -1)
|
||||
continue;
|
||||
LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
|
||||
buddyitem.BuddyID = finfo.Friend;
|
||||
// finfo.Friend may not be a simple uuid
|
||||
UUID friendID = UUID.Zero;
|
||||
if (UUID.TryParse(finfo.Friend, out friendID))
|
||||
buddyitem.BuddyID = finfo.Friend;
|
||||
else
|
||||
{
|
||||
string tmp;
|
||||
if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
|
||||
buddyitem.BuddyID = friendID.ToString();
|
||||
else
|
||||
// junk entry
|
||||
continue;
|
||||
}
|
||||
buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
|
||||
buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
|
||||
buddylistreturn.AddNewBuddy(buddyitem);
|
||||
|
|
|
@ -523,6 +523,7 @@ namespace OpenSim.Services.LLLoginService
|
|||
// free uri form
|
||||
// e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
|
||||
where = "url";
|
||||
GridRegion region = null;
|
||||
Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
|
||||
Match uriMatch = reURI.Match(startLocation);
|
||||
if (uriMatch == null)
|
||||
|
@ -553,8 +554,18 @@ namespace OpenSim.Services.LLLoginService
|
|||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions.", startLocation);
|
||||
return null;
|
||||
m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region");
|
||||
region = FindAlternativeRegion(scopeID);
|
||||
if (region != null)
|
||||
{
|
||||
where = "safe";
|
||||
return region;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions and no alternative found.", startLocation);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return regions[0];
|
||||
|
@ -582,7 +593,8 @@ namespace OpenSim.Services.LLLoginService
|
|||
if (parts.Length > 1)
|
||||
UInt32.TryParse(parts[1], out port);
|
||||
|
||||
GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
|
||||
// GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
|
||||
region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
|
||||
return region;
|
||||
}
|
||||
}
|
||||
|
@ -811,16 +823,13 @@ namespace OpenSim.Services.LLLoginService
|
|||
// Old style: get the service keys from the DB
|
||||
foreach (KeyValuePair<string, object> kvp in account.ServiceURLs)
|
||||
{
|
||||
if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty))
|
||||
{
|
||||
aCircuit.ServiceURLs[kvp.Key] = m_LoginServerConfig.GetString(kvp.Key, string.Empty);
|
||||
}
|
||||
else
|
||||
if (kvp.Value != null)
|
||||
{
|
||||
aCircuit.ServiceURLs[kvp.Key] = kvp.Value;
|
||||
|
||||
if (!aCircuit.ServiceURLs[kvp.Key].ToString().EndsWith("/"))
|
||||
aCircuit.ServiceURLs[kvp.Key] = aCircuit.ServiceURLs[kvp.Key] + "/";
|
||||
}
|
||||
if (!aCircuit.ServiceURLs[kvp.Key].ToString().EndsWith("/"))
|
||||
aCircuit.ServiceURLs[kvp.Key] = aCircuit.ServiceURLs[kvp.Key] + "/";
|
||||
}
|
||||
|
||||
// New style: service keys start with SRV_; override the previous
|
||||
|
@ -828,16 +837,29 @@ namespace OpenSim.Services.LLLoginService
|
|||
|
||||
if (keys.Length > 0)
|
||||
{
|
||||
bool newUrls = false;
|
||||
IEnumerable<string> serviceKeys = keys.Where(value => value.StartsWith("SRV_"));
|
||||
foreach (string serviceKey in serviceKeys)
|
||||
{
|
||||
string keyName = serviceKey.Replace("SRV_", "");
|
||||
aCircuit.ServiceURLs[keyName] = m_LoginServerConfig.GetString(serviceKey, string.Empty);
|
||||
if (!aCircuit.ServiceURLs[keyName].ToString().EndsWith("/"))
|
||||
aCircuit.ServiceURLs[keyName] = aCircuit.ServiceURLs[keyName] + "/";
|
||||
string keyValue = m_LoginServerConfig.GetString(serviceKey, string.Empty);
|
||||
if (!keyValue.EndsWith("/"))
|
||||
keyValue = keyValue + "/";
|
||||
|
||||
if (!account.ServiceURLs.ContainsKey(keyName) || (account.ServiceURLs.ContainsKey(keyName) && account.ServiceURLs[keyName] != keyValue))
|
||||
{
|
||||
account.ServiceURLs[keyName] = keyValue;
|
||||
newUrls = true;
|
||||
}
|
||||
aCircuit.ServiceURLs[keyName] = keyValue;
|
||||
|
||||
m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]);
|
||||
}
|
||||
|
||||
// The grid operator decided to override the defaults in the
|
||||
// [LoginService] configuration. Let's store the correct ones.
|
||||
if (newUrls)
|
||||
m_UserAccountService.StoreUserAccount(account);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.Text;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using log4net.Appender;
|
||||
using log4net.Layout;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.InstantMessage;
|
||||
|
||||
namespace OpenSim.Tests.Clients.InstantMessage
|
||||
{
|
||||
public class IMClient
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
ConsoleAppender consoleAppender = new ConsoleAppender();
|
||||
consoleAppender.Layout =
|
||||
new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline");
|
||||
log4net.Config.BasicConfigurator.Configure(consoleAppender);
|
||||
|
||||
string serverURI = "http://127.0.0.1:8002";
|
||||
GridInstantMessage im = new GridInstantMessage();
|
||||
im.fromAgentID = new Guid();
|
||||
im.toAgentID = new Guid();
|
||||
im.message = "Hello";
|
||||
im.imSessionID = new Guid();
|
||||
|
||||
bool success = InstantMessageServiceConnector.SendInstantMessage(serverURI, im);
|
||||
|
||||
if (success)
|
||||
m_log.InfoFormat("[IM CLIENT]: Successfully IMed {0}", serverURI);
|
||||
else
|
||||
m_log.InfoFormat("[IM CLIENT]: failed to IM {0}", serverURI);
|
||||
|
||||
System.Console.WriteLine("\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue