Merge branch 'master' into careminster-presence-refactor

avinationmerge
Melanie 2011-06-09 02:05:04 +01:00
commit 326c46ba70
119 changed files with 6471 additions and 4318 deletions

View File

@ -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);
}
}

View File

@ -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);
@ -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);
}
}
@ -315,7 +320,7 @@ namespace OpenSim.Data.MSSQL
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)

View File

@ -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())

View File

@ -168,6 +168,7 @@ namespace OpenSim.Data.MSSQL
protected T[] DoQuery(SqlCommand cmd)
{
List<T> result = new List<T>();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader == null)
@ -175,8 +176,6 @@ namespace OpenSim.Data.MSSQL
CheckColumnNames(reader);
List<T> result = new List<T>();
while (reader.Read())
{
T row = new T();
@ -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;
}
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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))
{

View File

@ -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>
@ -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.

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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'

View File

@ -1003,7 +1003,7 @@ CREATE TABLE "regionwindlight" (
PRIMARY KEY ("region_id")
)
COMMIT TRANSACTION
COMMIT
:VERSION 26

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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; });

View File

@ -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();

View File

@ -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;

View File

@ -345,6 +345,7 @@ namespace OpenSim.Framework
}
}
}
}

View File

@ -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; }

View File

@ -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(' ');

View File

@ -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);

View File

@ -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
}
}

View File

@ -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");

View File

@ -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;

View File

@ -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,17 +8364,26 @@ 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
// 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;

View File

@ -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(

View File

@ -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,31 +241,35 @@ 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)
Util.FireAndForget(delegate { FetchFriendslist(client); });
}
/// 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(client.AgentId, out friendsData))
if (m_Friends.TryGetValue(agentID, out friendsData))
{
friendsData.Refcount++;
return false;
}
else
{
friendsData = new UserFriendData();
friendsData.PrincipalID = client.AgentId;
friendsData.Friends = FriendsService.GetFriends(client.AgentId);
friendsData.PrincipalID = agentID;
friendsData.Friends = GetFriendsFromService(client);
friendsData.Refcount = 1;
m_Friends[client.AgentId] = friendsData;
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,6 +405,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
if (friendList.Count > 0)
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)
@ -358,9 +421,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
return online;
}
/// <summary>
/// Find the client for a ID
/// </summary>
@ -415,18 +475,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
Util.FireAndForget(
delegate
{
foreach (FriendInfo fi in friendList)
{
//m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
// Notify about this user status
StatusNotify(fi, agentID, online);
}
StatusNotify(friendList, agentID, online);
}
);
}
}
private void StatusNotify(FriendInfo friend, UUID userID, bool online)
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{
foreach (FriendInfo friend in friendList)
{
UUID friendID;
if (UUID.TryParse(friend.Friend, out friendID))
@ -462,6 +521,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
}
}
}
private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
{
@ -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;
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
}
}

View File

@ -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);
}
}
}
}

View File

@ -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
}
}

View File

@ -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
@ -181,29 +182,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <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>
/// </remarks>
///
/// <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>
/// <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 });
@ -227,7 +262,7 @@ 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
@ -239,12 +274,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
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>

View File

@ -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)
{

View File

@ -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);
}
}
}
}
}
}
}

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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)
{
@ -555,11 +559,34 @@ 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);
}

View File

@ -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

View File

@ -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;

View File

@ -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>

View File

@ -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;
}
}
}

View File

@ -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;
@ -66,17 +67,35 @@ namespace OpenSim.Region.CoreModules.Hypergrid
minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize);
foreach (GridRegion r in regions)
{
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
FillInMap(mapBlocks, minX, minY, maxX, maxY);
//
remoteClient.SendMapBlock(mapBlocks, 0);
}

View File

@ -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" />

View File

@ -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);
}

View File

@ -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);
}
}
}
}

View File

@ -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);

View File

@ -582,15 +582,20 @@ namespace OpenSim.Region.CoreModules.World.Permissions
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;
@ -599,8 +604,10 @@ 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))
@ -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;
@ -705,6 +711,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
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);
if ((parcel != null) && (parcel.LandData.OwnerID == currentUser))

View File

@ -208,7 +208,18 @@ 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.
// 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.
if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY >= 4096)
{
ScenePresence avatarPresence = null;
m_scene.TryGetScenePresence(agentID, out avatarPresence);
@ -254,6 +265,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
cachedTime = Util.UnixTimeSinceEpoch();
}
}
}
LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
return mapResponse.ToString();

View File

@ -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)
{
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}
}
}
}
}
}

View File

@ -408,8 +408,21 @@ namespace OpenSim.Region.Framework.Scenes
InventoryItemBase item = new InventoryItemBase(itemId, senderId);
item = InventoryService.GetItem(item);
if ((item != null) && (item.Owner == senderId))
if (item == null)
{
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);
@ -588,13 +601,6 @@ namespace OpenSim.Region.Framework.Scenes
return itemCopy;
}
else
{
m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId);
return null;
}
}
/// <summary>
/// Give an entire inventory folder from one user to another. The entire contents (including all descendent
@ -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>

View File

@ -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);
// 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)

View File

@ -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();
}

View File

@ -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));
}
}
}

View File

@ -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)
{
}

View File

@ -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,6 +1232,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID);
GroupMembershipData[] membershipArray;
// 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);
if (isGod)
{
membershipArray = membershipData.ToArray();
}
else
{
if (requestingClient.AgentId != dataForAgentID)
{
Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership)
@ -1244,6 +1256,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
{
membershipArray = membershipData.ToArray();
}
}
if (m_debugEnabled)
{
@ -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);

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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,9 +74,12 @@ 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);
}
}
@ -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.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();
}
}
}
}

View File

@ -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)
{
}

View File

@ -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);

View File

@ -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);

View File

@ -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));
}

View File

@ -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();
@ -164,6 +188,24 @@ namespace OpenSim.Server.Handlers.Friends
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
}
}

View File

@ -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));
}
}
}

View File

@ -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
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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
{
@ -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;
}
}
}

View File

@ -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
}
}

View File

@ -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)
{

View File

@ -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;
}
}
}

View File

@ -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
{

View File

@ -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())
{
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 true;
return success;
}
}
m_log.WarnFormat(

View File

@ -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";

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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);
}

View File

@ -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
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

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -341,6 +341,9 @@ namespace OpenSim.Services.InventoryService
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);

View File

@ -627,7 +627,19 @@ namespace OpenSim.Services.LLLoginService
if (finfo.TheirFlags == -1)
continue;
LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(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);

View File

@ -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,10 +554,20 @@ namespace OpenSim.Services.LLLoginService
}
else
{
m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions.", startLocation);
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];
}
else
@ -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,33 +823,43 @@ 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] + "/";
}
}
// New style: service keys start with SRV_; override the previous
string[] keys = m_LoginServerConfig.GetKeys();
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);
}
}

View File

@ -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");
}
}
}

View File

@ -117,17 +117,20 @@ namespace OpenSim.Tests.Common
// }
public static UserAccount CreateUserWithInventory(Scene scene)
{
return CreateUserWithInventory(scene, 99);
}
public static UserAccount CreateUserWithInventory(Scene scene, int uuidTail)
{
return CreateUserWithInventory(
scene, "Bill", "Bailey", UUID.Parse("00000000-0000-0000-0000-000000000099"), "troll");
scene, "Bill", "Bailey", new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail)), "troll");
}
public static UserAccount CreateUserWithInventory(
Scene scene, string firstName, string lastName, UUID userId, string pw)
{
UserAccount ua
= new UserAccount(userId)
{ FirstName = firstName, LastName = lastName };
UserAccount ua = new UserAccount(userId) { FirstName = firstName, LastName = lastName };
CreateUserWithInventory(scene, ua, pw);
return ua;
}

Some files were not shown because too many files have changed in this diff Show More