Merge branch 'dev' of ssh://sceneapi@island.sciencesim.com/home/sceneapi/sceneapi into dev

dsg
Huaiyu (Kitty) Liu 2011-06-16 09:51:40 -07:00
commit 492d684911
202 changed files with 9301 additions and 4827 deletions

View File

@ -34,7 +34,7 @@ namespace OpenSim.Data
{ {
public class FriendsData public class FriendsData
{ {
public UUID PrincipalID; public string PrincipalID;
public string Friend; public string Friend;
public Dictionary<string, string> Data; public Dictionary<string, string> Data;
} }
@ -46,6 +46,8 @@ namespace OpenSim.Data
{ {
bool Store(FriendsData data); bool Store(FriendsData data);
bool Delete(UUID ownerID, string friend); bool Delete(UUID ownerID, string friend);
bool Delete(string ownerID, string friend);
FriendsData[] GetFriends(UUID principalID); FriendsData[] GetFriends(UUID principalID);
FriendsData[] GetFriends(string principalID);
} }
} }

View File

@ -74,9 +74,38 @@ namespace OpenSim.Data
bool StoreFolder(XInventoryFolder folder); bool StoreFolder(XInventoryFolder folder);
bool StoreItem(XInventoryItem item); bool StoreItem(XInventoryItem item);
/// <summary>
/// Delete folders where field == val
/// </summary>
/// <param name="field"></param>
/// <param name="val"></param>
/// <returns>true if the delete was successful, false if it was not</returns>
bool DeleteFolders(string field, string val); bool DeleteFolders(string field, string val);
/// <summary>
/// Delete folders where field1 == val1, field2 == val2...
/// </summary>
/// <param name="fields"></param>
/// <param name="vals"></param>
/// <returns>true if the delete was successful, false if it was not</returns>
bool DeleteFolders(string[] fields, string[] vals);
/// <summary>
/// Delete items where field == val
/// </summary>
/// <param name="field"></param>
/// <param name="val"></param>
/// <returns>true if the delete was successful, false if it was not</returns>
bool DeleteItems(string field, string val); bool DeleteItems(string field, string val);
/// <summary>
/// Delete items where field1 == val1, field2 == val2...
/// </summary>
/// <param name="fields"></param>
/// <param name="vals"></param>
/// <returns>true if the delete was successful, false if it was not</returns>
bool DeleteItems(string[] fields, string[] vals);
bool MoveItem(string id, string newParent); bool MoveItem(string id, string newParent);
XInventoryItem[] GetActiveGestures(UUID principalID); XInventoryItem[] GetActiveGestures(UUID principalID);
int GetAssetPermissions(UUID principalID, UUID assetID); int GetAssetPermissions(UUID principalID, UUID assetID);

View File

@ -41,7 +41,7 @@ namespace OpenSim.Data.MSSQL
{ {
private const string _migrationStore = "EstateStore"; private const string _migrationStore = "EstateStore";
private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private MSSQLManager _Database; private MSSQLManager _Database;
private string m_connectionString; private string m_connectionString;
@ -72,7 +72,12 @@ namespace OpenSim.Data.MSSQL
} }
//Migration settings //Migration settings
_Database.CheckMigration(_migrationStore); using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
Migration m = new Migration(conn, GetType().Assembly, "EstateStore");
m.Update();
}
//Interesting way to get parameters! Maybe implement that also with other types //Interesting way to get parameters! Maybe implement that also with other types
Type t = typeof(EstateSettings); Type t = typeof(EstateSettings);
@ -112,19 +117,19 @@ namespace OpenSim.Data.MSSQL
{ {
FieldInfo f = _FieldMap[name]; FieldInfo f = _FieldMap[name];
object v = reader[name]; object v = reader[name];
if (f.FieldType == typeof(bool) ) if (f.FieldType == typeof(bool))
{ {
f.SetValue(es, Convert.ToInt32(v) != 0); f.SetValue(es, Convert.ToInt32(v) != 0);
} }
else if (f.FieldType == typeof(UUID) ) else if (f.FieldType == typeof(UUID))
{ {
f.SetValue(es, new UUID((Guid)v)); // uuid); f.SetValue(es, new UUID((Guid)v)); // uuid);
} }
else if (f.FieldType == typeof(string)) else if (f.FieldType == typeof(string))
{ {
f.SetValue(es, v.ToString()); f.SetValue(es, v.ToString());
} }
else if (f.FieldType == typeof(UInt32)) else if (f.FieldType == typeof(UInt32))
{ {
f.SetValue(es, Convert.ToUInt32(v)); f.SetValue(es, Convert.ToUInt32(v));
} }
@ -186,7 +191,7 @@ namespace OpenSim.Data.MSSQL
} }
catch (Exception e) catch (Exception e)
{ {
_Log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e); m_log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
} }
} }
@ -310,12 +315,12 @@ namespace OpenSim.Data.MSSQL
conn.Open(); conn.Open();
using (SqlCommand cmd = conn.CreateCommand()) using (SqlCommand cmd = conn.CreateCommand())
{ {
cmd.CommandText = "delete from estateban where EstateID = @EstateID"; cmd.CommandText = "delete from estateban where EstateID = @EstateID";
cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID); cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
//Insert after //Insert after
cmd.CommandText = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )"; cmd.CommandText = "insert into estateban (EstateID, bannedUUID,bannedIp, bannedIpHostMask, bannedNameMask) values ( @EstateID, @bannedUUID, '','','' )";
cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty); cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty);
foreach (EstateBan b in es.EstateBans) foreach (EstateBan b in es.EstateBans)
{ {
@ -350,43 +355,195 @@ namespace OpenSim.Data.MSSQL
public EstateSettings LoadEstateSettings(int estateID) public EstateSettings LoadEstateSettings(int estateID)
{ {
// TODO: Implementation! EstateSettings es = new EstateSettings();
return new EstateSettings(); string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = @EstateID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
foreach (string name in FieldList)
{
FieldInfo f = _FieldMap[name];
object v = reader[name];
if (f.FieldType == typeof(bool))
{
f.SetValue(es, Convert.ToInt32(v) != 0);
}
else if (f.FieldType == typeof(UUID))
{
f.SetValue(es, new UUID((Guid)v)); // uuid);
}
else if (f.FieldType == typeof(string))
{
f.SetValue(es, v.ToString());
}
else if (f.FieldType == typeof(UInt32))
{
f.SetValue(es, Convert.ToUInt32(v));
}
else if (f.FieldType == typeof(Single))
{
f.SetValue(es, Convert.ToSingle(v));
}
else
f.SetValue(es, v);
}
}
}
}
}
LoadBanList(es);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
//Set event
es.OnSave += StoreEstateSettings;
return es;
} }
public List<EstateSettings> LoadEstateSettingsAll() public List<EstateSettings> LoadEstateSettingsAll()
{ {
// TODO: Implementation! List<EstateSettings> allEstateSettings = new List<EstateSettings>();
return new List<EstateSettings>();
List<int> allEstateIds = GetEstatesAll();
foreach (int estateId in allEstateIds)
allEstateSettings.Add(LoadEstateSettings(estateId));
return allEstateSettings;
} }
public List<int> GetEstates(string search) public List<int> GetEstates(string search)
{ {
// TODO: Implementation! List<int> result = new List<int>();
return new List<int>(); string sql = "select estateID from estate_settings where EstateName = @EstateName";
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@EstateName", search);
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(Convert.ToInt32(reader["EstateID"]));
}
reader.Close();
}
}
}
return result;
} }
public List<int> GetEstatesAll() public List<int> GetEstatesAll()
{ {
// TODO: Implementation! List<int> result = new List<int>();
return new List<int>(); string sql = "select estateID from estate_settings";
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(Convert.ToInt32(reader["EstateID"]));
}
reader.Close();
}
}
}
return result;
} }
public List<int> GetEstatesByOwner(UUID ownerID) public List<int> GetEstatesByOwner(UUID ownerID)
{ {
return new List<int>(); List<int> result = new List<int>();
string sql = "select estateID from estate_settings where EstateOwner = @EstateOwner";
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@EstateOwner", ownerID);
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(Convert.ToInt32(reader["EstateID"]));
}
reader.Close();
}
}
}
return result;
} }
public bool LinkRegion(UUID regionID, int estateID) public bool LinkRegion(UUID regionID, int estateID)
{ {
// TODO: Implementation! string sql = "insert into estate_map values (@RegionID, @EstateID)";
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
try
{
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@RegionID", regionID);
cmd.Parameters.AddWithValue("@EstateID", estateID);
int ret = cmd.ExecuteNonQuery();
return (ret != 0);
}
}
catch (Exception ex)
{
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
}
}
return false; return false;
} }
public List<UUID> GetRegions(int estateID) public List<UUID> GetRegions(int estateID)
{ {
// TODO: Implementation! List<UUID> result = new List<UUID>();
return new List<UUID>(); string sql = "select RegionID from estate_map where EstateID = @EstateID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@EstateID", estateID);
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(DBGuid.FromDB(reader["RegionID"]));
}
reader.Close();
}
}
}
return result;
} }
public bool DeleteEstate(int estateID) public bool DeleteEstate(int estateID)

View File

@ -51,6 +51,11 @@ namespace OpenSim.Data.MSSQL
} }
public bool Delete(UUID principalID, string friend) public bool Delete(UUID principalID, string friend)
{
return Delete(principalID.ToString(), friend);
}
public bool Delete(string principalID, string friend)
{ {
using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand()) using (SqlCommand cmd = new SqlCommand())
@ -67,6 +72,11 @@ namespace OpenSim.Data.MSSQL
} }
public FriendsData[] GetFriends(UUID principalID) public FriendsData[] GetFriends(UUID principalID)
{
return GetFriends(principalID.ToString());
}
public FriendsData[] GetFriends(string principalID)
{ {
using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand()) using (SqlCommand cmd = new SqlCommand())

View File

@ -168,14 +168,13 @@ namespace OpenSim.Data.MSSQL
protected T[] DoQuery(SqlCommand cmd) protected T[] DoQuery(SqlCommand cmd)
{ {
List<T> result = new List<T>();
using (SqlDataReader reader = cmd.ExecuteReader()) using (SqlDataReader reader = cmd.ExecuteReader())
{ {
if (reader == null) if (reader == null)
return new T[0]; return new T[0];
CheckColumnNames(reader); CheckColumnNames(reader);
List<T> result = new List<T>();
while (reader.Read()) while (reader.Read())
{ {
@ -262,6 +261,15 @@ namespace OpenSim.Data.MSSQL
{ {
names.Add(fi.Name); names.Add(fi.Name);
values.Add("@" + fi.Name); values.Add("@" + fi.Name);
// Temporarily return more information about what field is unexpectedly null for
// http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
// InventoryTransferModule or we may be required to substitute a DBNull here.
if (fi.GetValue(row) == null)
throw new NullReferenceException(
string.Format(
"[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
fi.Name, row));
if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name)) if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
{ {
constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString())); constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
@ -335,16 +343,33 @@ namespace OpenSim.Data.MSSQL
} }
} }
public virtual bool Delete(string field, string val) public virtual bool Delete(string field, string key)
{ {
return Delete(new string[] { field }, new string[] { key });
}
public virtual bool Delete(string[] fields, string[] keys)
{
if (fields.Length != keys.Length)
return false;
List<string> terms = new List<string>();
using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand()) using (SqlCommand cmd = new SqlCommand())
{ {
string deleteCommand = String.Format("DELETE FROM {0} WHERE [{1}] = @{1}", m_Realm, field); for (int i = 0; i < fields.Length; i++)
cmd.CommandText = deleteCommand; {
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
cmd.Parameters.Add(m_database.CreateParameter(field, val)); terms.Add("[" + fields[i] + "] = @" + fields[i]);
}
string where = String.Join(" AND ", terms.ToArray());
string query = String.Format("DELETE FROM {0} WHERE {1}", m_Realm, where);
cmd.Connection = conn; cmd.Connection = conn;
cmd.CommandText = query;
conn.Open(); conn.Open();
if (cmd.ExecuteNonQuery() > 0) if (cmd.ExecuteNonQuery() > 0)

View File

@ -29,16 +29,19 @@ using System;
using System.Data; using System.Data;
using System.Data.Common; using System.Data.Common;
using System.Reflection; using System.Reflection;
using System.Data.SqlClient;
namespace OpenSim.Data.MSSQL namespace OpenSim.Data.MSSQL
{ {
public class MSSQLMigration : Migration public class MSSQLMigration : Migration
{ {
public MSSQLMigration(DbConnection conn, Assembly assem, string type) : base(conn, assem, type) public MSSQLMigration(DbConnection conn, Assembly assem, string type)
: base(conn, assem, type)
{ {
} }
public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type) : base(conn, assem, subtype, type) public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type)
: base(conn, assem, subtype, type)
{ {
} }
@ -67,5 +70,30 @@ namespace OpenSim.Data.MSSQL
} }
return version; return version;
} }
protected override void ExecuteScript(DbConnection conn, string[] script)
{
if (!(conn is SqlConnection))
{
base.ExecuteScript(conn, script);
return;
}
foreach (string sql in script)
{
try
{
using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)conn))
{
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
throw new Exception(sql);
}
}
}
} }
} }

View File

@ -70,6 +70,7 @@ namespace OpenSim.Data.MSSQL
string sql = "select * from ["+m_Realm+"] where regionName like @regionName"; string sql = "select * from ["+m_Realm+"] where regionName like @regionName";
if (scopeID != UUID.Zero) if (scopeID != UUID.Zero)
sql += " and ScopeID = @scopeID"; sql += " and ScopeID = @scopeID";
sql += " order by regionName";
using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn)) using (SqlCommand cmd = new SqlCommand(sql, conn))
{ {

View File

@ -55,6 +55,10 @@ namespace OpenSim.Data.MSSQL
/// </summary> /// </summary>
private MSSQLManager _Database; private MSSQLManager _Database;
private string m_connectionString; private string m_connectionString;
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
public MSSQLSimulationData() public MSSQLSimulationData()
{ {
@ -74,9 +78,28 @@ namespace OpenSim.Data.MSSQL
m_connectionString = connectionString; m_connectionString = connectionString;
_Database = new MSSQLManager(connectionString); _Database = new MSSQLManager(connectionString);
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
//New Migration settings
Migration m = new Migration(conn, Assembly, "RegionStore");
m.Update();
//Migration settings // Clean dropped attachments
_Database.CheckMigration(_migrationStore); //
try
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "delete from prims where prims.UUID in (select UUID from primshapes where PCode = 9 and State <> 0); delete from primshapes where PCode = 9 and State <> 0";
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
_Log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
}
}
} }
/// <summary> /// <summary>
@ -214,7 +237,7 @@ namespace OpenSim.Data.MSSQL
{ {
command.Parameters.Clear(); command.Parameters.Clear();
command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID)); command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID));
List<TaskInventoryItem> inventory = new List<TaskInventoryItem>(); List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
using (SqlDataReader reader = command.ExecuteReader()) using (SqlDataReader reader = command.ExecuteReader())
@ -241,6 +264,14 @@ namespace OpenSim.Data.MSSQL
/// <param name="regionUUID"></param> /// <param name="regionUUID"></param>
public void StoreObject(SceneObjectGroup obj, UUID regionUUID) public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
{ {
uint flags = obj.RootPart.GetEffectiveObjectFlags();
// Eligibility check
//
if ((flags & (uint)PrimFlags.Temporary) != 0)
return;
if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
return;
_Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length); _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length);
using (SqlConnection conn = new SqlConnection(m_connectionString)) using (SqlConnection conn = new SqlConnection(m_connectionString))
@ -700,16 +731,470 @@ VALUES
} }
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
{ {
//This connector doesn't support the windlight module yet RegionLightShareData nWP = new RegionLightShareData();
//Return default LL windlight settings nWP.OnSave += StoreRegionWindlightSettings;
return new RegionLightShareData(); string sql = "select * from [regionwindlight] where region_id = @regionID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@regionID", regionUUID));
conn.Open();
using (SqlDataReader result = cmd.ExecuteReader())
{
if (!result.Read())
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
StoreRegionWindlightSettings(nWP);
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
}
}
}
return nWP;
} }
public void RemoveRegionWindlightSettings(UUID regionID) public void RemoveRegionWindlightSettings(UUID regionID)
{ {
string sql = "delete from [regionwindlight] where region_id = @region_id";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionID));
cmd.ExecuteNonQuery();
}
} }
public void StoreRegionWindlightSettings(RegionLightShareData wl) public void StoreRegionWindlightSettings(RegionLightShareData wl)
{ {
//This connector doesn't support the windlight module yet string sql = "select count (region_id) from regionwindlight where region_id = @region_id";
bool exists = false;
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@region_id", wl.regionID));
exists = (int)cmd.ExecuteScalar() > 0;
}
}
if (exists)
{
RemoveRegionWindlightSettings(wl.regionID);
}
// sql insert
sql = @"INSERT INTO [regionwindlight]
([region_id]
,[water_color_r]
,[water_color_g]
,[water_color_b]
,[water_fog_density_exponent]
,[underwater_fog_modifier]
,[reflection_wavelet_scale_1]
,[reflection_wavelet_scale_2]
,[reflection_wavelet_scale_3]
,[fresnel_scale]
,[fresnel_offset]
,[refract_scale_above]
,[refract_scale_below]
,[blur_multiplier]
,[big_wave_direction_x]
,[big_wave_direction_y]
,[little_wave_direction_x]
,[little_wave_direction_y]
,[normal_map_texture]
,[horizon_r]
,[horizon_g]
,[horizon_b]
,[horizon_i]
,[haze_horizon]
,[blue_density_r]
,[blue_density_g]
,[blue_density_b]
,[blue_density_i]
,[haze_density]
,[density_multiplier]
,[distance_multiplier]
,[max_altitude]
,[sun_moon_color_r]
,[sun_moon_color_g]
,[sun_moon_color_b]
,[sun_moon_color_i]
,[sun_moon_position]
,[ambient_r]
,[ambient_g]
,[ambient_b]
,[ambient_i]
,[east_angle]
,[sun_glow_focus]
,[sun_glow_size]
,[scene_gamma]
,[star_brightness]
,[cloud_color_r]
,[cloud_color_g]
,[cloud_color_b]
,[cloud_color_i]
,[cloud_x]
,[cloud_y]
,[cloud_density]
,[cloud_coverage]
,[cloud_scale]
,[cloud_detail_x]
,[cloud_detail_y]
,[cloud_detail_density]
,[cloud_scroll_x]
,[cloud_scroll_x_lock]
,[cloud_scroll_y]
,[cloud_scroll_y_lock]
,[draw_classic_clouds])
VALUES
(@region_id
,@water_color_r
,@water_color_g
,@water_color_b
,@water_fog_density_exponent
,@underwater_fog_modifier
,@reflection_wavelet_scale_1
,@reflection_wavelet_scale_2
,@reflection_wavelet_scale_3
,@fresnel_scale
,@fresnel_offset
,@refract_scale_above
,@refract_scale_below
,@blur_multiplier
,@big_wave_direction_x
,@big_wave_direction_y
,@little_wave_direction_x
,@little_wave_direction_y
,@normal_map_texture
,@horizon_r
,@horizon_g
,@horizon_b
,@horizon_i
,@haze_horizon
,@blue_density_r
,@blue_density_g
,@blue_density_b
,@blue_density_i
,@haze_density
,@density_multiplier
,@distance_multiplier
,@max_altitude
,@sun_moon_color_r
,@sun_moon_color_g
,@sun_moon_color_b
,@sun_moon_color_i
,@sun_moon_position
,@ambient_r
,@ambient_g
,@ambient_b
,@ambient_i
,@east_angle
,@sun_glow_focus
,@sun_glow_size
,@scene_gamma
,@star_brightness
,@cloud_color_r
,@cloud_color_g
,@cloud_color_b
,@cloud_color_i
,@cloud_x
,@cloud_y
,@cloud_density
,@cloud_coverage
,@cloud_scale
,@cloud_detail_x
,@cloud_detail_y
,@cloud_detail_density
,@cloud_scroll_x
,@cloud_scroll_x_lock
,@cloud_scroll_y
,@cloud_scroll_y_lock
,@draw_classic_clouds)";
using (SqlConnection conn = new SqlConnection(m_connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID));
cmd.Parameters.Add(_Database.CreateParameter("water_color_r", wl.waterColor.X));
cmd.Parameters.Add(_Database.CreateParameter("water_color_g", wl.waterColor.Y));
cmd.Parameters.Add(_Database.CreateParameter("water_color_b", wl.waterColor.Z));
cmd.Parameters.Add(_Database.CreateParameter("water_fog_density_exponent", wl.waterFogDensityExponent));
cmd.Parameters.Add(_Database.CreateParameter("underwater_fog_modifier", wl.underwaterFogModifier));
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X));
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y));
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z));
cmd.Parameters.Add(_Database.CreateParameter("fresnel_scale", wl.fresnelScale));
cmd.Parameters.Add(_Database.CreateParameter("fresnel_offset", wl.fresnelOffset));
cmd.Parameters.Add(_Database.CreateParameter("refract_scale_above", wl.refractScaleAbove));
cmd.Parameters.Add(_Database.CreateParameter("refract_scale_below", wl.refractScaleBelow));
cmd.Parameters.Add(_Database.CreateParameter("blur_multiplier", wl.blurMultiplier));
cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_x", wl.bigWaveDirection.X));
cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_y", wl.bigWaveDirection.Y));
cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_x", wl.littleWaveDirection.X));
cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_y", wl.littleWaveDirection.Y));
cmd.Parameters.Add(_Database.CreateParameter("normal_map_texture", wl.normalMapTexture));
cmd.Parameters.Add(_Database.CreateParameter("horizon_r", wl.horizon.X));
cmd.Parameters.Add(_Database.CreateParameter("horizon_g", wl.horizon.Y));
cmd.Parameters.Add(_Database.CreateParameter("horizon_b", wl.horizon.Z));
cmd.Parameters.Add(_Database.CreateParameter("horizon_i", wl.horizon.W));
cmd.Parameters.Add(_Database.CreateParameter("haze_horizon", wl.hazeHorizon));
cmd.Parameters.Add(_Database.CreateParameter("blue_density_r", wl.blueDensity.X));
cmd.Parameters.Add(_Database.CreateParameter("blue_density_g", wl.blueDensity.Y));
cmd.Parameters.Add(_Database.CreateParameter("blue_density_b", wl.blueDensity.Z));
cmd.Parameters.Add(_Database.CreateParameter("blue_density_i", wl.blueDensity.W));
cmd.Parameters.Add(_Database.CreateParameter("haze_density", wl.hazeDensity));
cmd.Parameters.Add(_Database.CreateParameter("density_multiplier", wl.densityMultiplier));
cmd.Parameters.Add(_Database.CreateParameter("distance_multiplier", wl.distanceMultiplier));
cmd.Parameters.Add(_Database.CreateParameter("max_altitude", wl.maxAltitude));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_r", wl.sunMoonColor.X));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_g", wl.sunMoonColor.Y));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_b", wl.sunMoonColor.Z));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_i", wl.sunMoonColor.W));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_position", wl.sunMoonPosition));
cmd.Parameters.Add(_Database.CreateParameter("ambient_r", wl.ambient.X));
cmd.Parameters.Add(_Database.CreateParameter("ambient_g", wl.ambient.Y));
cmd.Parameters.Add(_Database.CreateParameter("ambient_b", wl.ambient.Z));
cmd.Parameters.Add(_Database.CreateParameter("ambient_i", wl.ambient.W));
cmd.Parameters.Add(_Database.CreateParameter("east_angle", wl.eastAngle));
cmd.Parameters.Add(_Database.CreateParameter("sun_glow_focus", wl.sunGlowFocus));
cmd.Parameters.Add(_Database.CreateParameter("sun_glow_size", wl.sunGlowSize));
cmd.Parameters.Add(_Database.CreateParameter("scene_gamma", wl.sceneGamma));
cmd.Parameters.Add(_Database.CreateParameter("star_brightness", wl.starBrightness));
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_r", wl.cloudColor.X));
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_g", wl.cloudColor.Y));
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_b", wl.cloudColor.Z));
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_i", wl.cloudColor.W));
cmd.Parameters.Add(_Database.CreateParameter("cloud_x", wl.cloudXYDensity.X));
cmd.Parameters.Add(_Database.CreateParameter("cloud_y", wl.cloudXYDensity.Y));
cmd.Parameters.Add(_Database.CreateParameter("cloud_density", wl.cloudXYDensity.Z));
cmd.Parameters.Add(_Database.CreateParameter("cloud_coverage", wl.cloudCoverage));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scale", wl.cloudScale));
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_x", wl.cloudDetailXYDensity.X));
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_y", wl.cloudDetailXYDensity.Y));
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_density", wl.cloudDetailXYDensity.Z));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x", wl.cloudScrollX));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x_lock", wl.cloudScrollXLock));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y", wl.cloudScrollY));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y_lock", wl.cloudScrollYLock));
cmd.Parameters.Add(_Database.CreateParameter("draw_classic_clouds", wl.drawClassicClouds));
cmd.ExecuteNonQuery();
}
}
#region update
// }
// else
// {
// // sql update
// sql = @"UPDATE [OpenSim].[dbo].[regionwindlight]
// SET [region_id] = @region_id
// ,[water_color_r] = @water_color_r
// ,[water_color_g] = @water_color_g
// ,[water_color_b] = @water_color_b
// ,[water_fog_density_exponent] = @water_fog_density_exponent
// ,[underwater_fog_modifier] = @underwater_fog_modifier
// ,[reflection_wavelet_scale_1] = @reflection_wavelet_scale_1
// ,[reflection_wavelet_scale_2] = @reflection_wavelet_scale_2
// ,[reflection_wavelet_scale_3] = @reflection_wavelet_scale_3
// ,[fresnel_scale] = @fresnel_scale
// ,[fresnel_offset] = @fresnel_offset
// ,[refract_scale_above] = @refract_scale_above
// ,[refract_scale_below] = @refract_scale_below
// ,[blur_multiplier] = @blur_multiplier
// ,[big_wave_direction_x] = @big_wave_direction_x
// ,[big_wave_direction_y] = @big_wave_direction_y
// ,[little_wave_direction_x] = @little_wave_direction_x
// ,[little_wave_direction_y] = @little_wave_direction_y
// ,[normal_map_texture] = @normal_map_texture
// ,[horizon_r] = @horizon_r
// ,[horizon_g] = @horizon_g
// ,[horizon_b] = @horizon_b
// ,[horizon_i] = @horizon_i
// ,[haze_horizon] = @haze_horizon
// ,[blue_density_r] = @blue_density_r
// ,[blue_density_g] = @blue_density_g
// ,[blue_density_b] = @blue_density_b
// ,[blue_density_i] = @blue_density_i
// ,[haze_density] = @haze_density
// ,[density_multiplier] = @density_multiplier
// ,[distance_multiplier] = @distance_multiplier
// ,[max_altitude] = @max_altitude
// ,[sun_moon_color_r] = @sun_moon_color_r
// ,[sun_moon_color_g] = @sun_moon_color_g
// ,[sun_moon_color_b] = @sun_moon_color_b
// ,[sun_moon_color_i] = @sun_moon_color_i
// ,[sun_moon_position] = @sun_moon_position
// ,[ambient_r] = @ambient_r
// ,[ambient_g] = @ambient_g
// ,[ambient_b] = @ambient_b
// ,[ambient_i] = @ambient_i
// ,[east_angle] = @east_angle
// ,[sun_glow_focus] = @sun_glow_focus
// ,[sun_glow_size] = @sun_glow_size
// ,[scene_gamma] = @scene_gamma
// ,[star_brightness] = @star_brightness
// ,[cloud_color_r] = @cloud_color_r
// ,[cloud_color_g] = @cloud_color_g
// ,[cloud_color_b] = @cloud_color_b
// ,[cloud_color_i] = @cloud_color_i
// ,[cloud_x] = @cloud_x
// ,[cloud_y] = @cloud_y
// ,[cloud_density] = @cloud_density
// ,[cloud_coverage] = @cloud_coverage
// ,[cloud_scale] = @cloud_scale
// ,[cloud_detail_x] = @cloud_detail_x
// ,[cloud_detail_y] = @cloud_detail_y
// ,[cloud_detail_density] = @cloud_detail_density
// ,[cloud_scroll_x] = @cloud_scroll_x
// ,[cloud_scroll_x_lock] = @cloud_scroll_x_lock
// ,[cloud_scroll_y] = @cloud_scroll_y
// ,[cloud_scroll_y_lock] = @cloud_scroll_y_lock
// ,[draw_classic_clouds] = @draw_classic_clouds
// WHERE region_id = @region_id";
// using (SqlConnection conn = new SqlConnection(m_connectionString))
// {
// conn.Open();
// using (SqlCommand cmd = new SqlCommand(sql, conn))
// {
// cmd.Parameters.AddWithValue("region_id", wl.regionID);
// cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
// cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
// cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
// cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
// cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
// cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
// cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
// cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
// cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
// cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
// cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
// cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
// cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
// cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
// cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
// cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
// cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
// cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
// cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
// cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
// cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
// cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
// cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
// cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
// cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
// cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
// cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
// cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
// cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
// cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
// cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
// cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
// cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
// cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
// cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
// cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
// cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
// cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
// cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
// cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
// cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
// cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
// cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
// cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
// cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
// cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
// cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
// cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
// cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
// cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
// cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
// cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
// cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
// cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
// cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
// cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
// cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
// cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
// cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
// cmd.ExecuteNonQuery();
// }
// }
// }
#endregion
} }
/// <summary> /// <summary>
/// Loads the settings of a region. /// Loads the settings of a region.
@ -1136,7 +1621,7 @@ VALUES
if (Convert.ToInt16(primRow["PassTouches"]) != 0) if (Convert.ToInt16(primRow["PassTouches"]) != 0)
prim.PassTouches = true; prim.PassTouches = true;
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
if (!(primRow["MediaURL"] is System.DBNull)) if (!(primRow["MediaURL"] is System.DBNull))
prim.MediaUrl = (string)primRow["MediaURL"]; prim.MediaUrl = (string)primRow["MediaURL"];
@ -1192,11 +1677,11 @@ VALUES
{ {
} }
if (!(shapeRow["Media"] is System.DBNull) ) if (!(shapeRow["Media"] is System.DBNull))
{ {
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]); baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
} }
return baseShape; return baseShape;
} }
@ -1576,15 +2061,15 @@ VALUES
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
parameters.Add(_Database.CreateParameter("State", s.State)); parameters.Add(_Database.CreateParameter("State", s.State));
if(null == s.Media ) if (null == s.Media)
{ {
parameters.Add(_Database.CreateParameter("Media", DBNull.Value)); parameters.Add(_Database.CreateParameter("Media", DBNull.Value));
} }
else else
{ {
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml())); parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
} }
return parameters.ToArray(); return parameters.ToArray();
} }

View File

@ -66,11 +66,18 @@ namespace OpenSim.Data.MSSQL
public bool StoreFolder(XInventoryFolder folder) public bool StoreFolder(XInventoryFolder folder)
{ {
if (folder.folderName.Length > 64)
folder.folderName = folder.folderName.Substring(0, 64);
return m_Folders.Store(folder); return m_Folders.Store(folder);
} }
public bool StoreItem(XInventoryItem item) public bool StoreItem(XInventoryItem item)
{ {
if (item.inventoryName.Length > 64)
item.inventoryName = item.inventoryName.Substring(0, 64);
if (item.inventoryDescription.Length > 128)
item.inventoryDescription = item.inventoryDescription.Substring(0, 128);
return m_Items.Store(item); return m_Items.Store(item);
} }
@ -78,12 +85,19 @@ namespace OpenSim.Data.MSSQL
{ {
return m_Folders.Delete(field, val); return m_Folders.Delete(field, val);
} }
public bool DeleteFolders(string[] fields, string[] vals)
{
return m_Folders.Delete(fields, vals);
}
public bool DeleteItems(string field, string val) public bool DeleteItems(string field, string val)
{ {
return m_Items.Delete(field, val); 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) public bool MoveItem(string id, string newParent)
{ {
return m_Items.MoveItem(id, newParent); return m_Items.MoveItem(id, newParent);
@ -162,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 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 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") PRIMARY KEY ("region_id")
) )
COMMIT TRANSACTION COMMIT
:VERSION 26 :VERSION 26

View File

@ -43,6 +43,11 @@ namespace OpenSim.Data.MySQL
} }
public bool Delete(UUID principalID, string friend) public bool Delete(UUID principalID, string friend)
{
return Delete(principalID.ToString(), friend);
}
public bool Delete(string principalID, string friend)
{ {
MySqlCommand cmd = new MySqlCommand(); MySqlCommand cmd = new MySqlCommand();
@ -64,5 +69,14 @@ namespace OpenSim.Data.MySQL
return DoQuery(cmd); return DoQuery(cmd);
} }
public FriendsData[] GetFriends(string principalID)
{
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
return DoQuery(cmd);
}
} }
} }

View File

@ -264,18 +264,33 @@ namespace OpenSim.Data.MySQL
} }
} }
public virtual bool Delete(string field, string val) public virtual bool Delete(string field, string key)
{ {
return Delete(new string[] { field }, new string[] { key });
}
public virtual bool Delete(string[] fields, string[] keys)
{
if (fields.Length != keys.Length)
return false;
List<string> terms = new List<string>();
using (MySqlCommand cmd = new MySqlCommand()) using (MySqlCommand cmd = new MySqlCommand())
{ {
for (int i = 0 ; i < fields.Length ; i++)
{
cmd.Parameters.AddWithValue(fields[i], keys[i]);
terms.Add("`" + fields[i] + "` = ?" + fields[i]);
}
cmd.CommandText = String.Format("delete from {0} where `{1}` = ?{1}", m_Realm, field); string where = String.Join(" and ", terms.ToArray());
cmd.Parameters.AddWithValue(field, val);
if (ExecuteNonQuery(cmd) > 0) string query = String.Format("delete from {0} where {1}", m_Realm, where);
return true;
return false; cmd.CommandText = query;
return ExecuteNonQuery(cmd) > 0;
} }
} }
} }

View File

@ -85,11 +85,21 @@ namespace OpenSim.Data.MySQL
return m_Folders.Delete(field, val); return m_Folders.Delete(field, val);
} }
public bool DeleteFolders(string[] fields, string[] vals)
{
return m_Folders.Delete(fields, vals);
}
public bool DeleteItems(string field, string val) public bool DeleteItems(string field, string val)
{ {
return m_Items.Delete(field, val); 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) public bool MoveItem(string id, string newParent)
{ {
return m_Items.MoveItem(id, newParent); return m_Items.MoveItem(id, newParent);

View File

@ -21,5 +21,12 @@ INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userf
COMMIT; COMMIT;
:VERSION 3 # -------------------------
BEGIN;
ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
ALTER TABLE `Friends` DROP PRIMARY KEY;
ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36));
COMMIT;

View File

@ -826,3 +826,19 @@ ALTER TABLE `prims` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
COMMIT; COMMIT;
:VERSION 38 #---------------------
BEGIN;
alter table land ENGINE = MyISAM;
alter table landaccesslist ENGINE = MyISAM;
alter table migrations ENGINE = MyISAM;
alter table primitems ENGINE = MyISAM;
alter table prims ENGINE = MyISAM;
alter table primshapes ENGINE = MyISAM;
alter table regionban ENGINE = MyISAM;
alter table regionsettings ENGINE = MyISAM;
alter table terrain ENGINE = MyISAM;
COMMIT;

View File

@ -42,6 +42,11 @@ namespace OpenSim.Data.Null
{ {
} }
public FriendsData[] GetFriends(UUID principalID)
{
return GetFriends(principalID.ToString());
}
/// <summary> /// <summary>
/// Tries to implement the Get [] semantics, but it cuts corners. /// Tries to implement the Get [] semantics, but it cuts corners.
/// Specifically, it gets all friendships even if they weren't accepted yet. /// Specifically, it gets all friendships even if they weren't accepted yet.
@ -49,11 +54,11 @@ namespace OpenSim.Data.Null
/// <param name="fields"></param> /// <param name="fields"></param>
/// <param name="values"></param> /// <param name="values"></param>
/// <returns></returns> /// <returns></returns>
public FriendsData[] GetFriends(UUID userID) public FriendsData[] GetFriends(string userID)
{ {
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata) List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
{ {
return fdata.PrincipalID == userID; return fdata.PrincipalID == userID.ToString();
}); });
if (lst != null) if (lst != null)
@ -72,9 +77,14 @@ namespace OpenSim.Data.Null
return true; return true;
} }
public bool Delete(UUID userID, string friendID) public bool Delete(UUID principalID, string friend)
{ {
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID; }); return Delete(principalID.ToString(), friend);
}
public bool Delete(string userID, string friendID)
{
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
if (lst != null) if (lst != null)
{ {
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; }); FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });

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(); SqliteCommand cmd = new SqliteCommand();
@ -58,6 +63,11 @@ namespace OpenSim.Data.SQLite
} }
public bool Delete(UUID principalID, string friend) public bool Delete(UUID principalID, string friend)
{
return Delete(principalID.ToString(), friend);
}
public bool Delete(string principalID, string friend)
{ {
SqliteCommand cmd = new SqliteCommand(); SqliteCommand cmd = new SqliteCommand();

View File

@ -258,17 +258,33 @@ namespace OpenSim.Data.SQLite
return false; return false;
} }
public bool Delete(string field, string val) public virtual bool Delete(string field, string key)
{ {
return Delete(new string[] { field }, new string[] { key });
}
public bool Delete(string[] fields, string[] keys)
{
if (fields.Length != keys.Length)
return false;
List<string> terms = new List<string>();
SqliteCommand cmd = new SqliteCommand(); SqliteCommand cmd = new SqliteCommand();
cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field); for (int i = 0 ; i < fields.Length ; i++)
cmd.Parameters.Add(new SqliteParameter(field, val)); {
cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
terms.Add("`" + fields[i] + "` = :" + fields[i]);
}
if (ExecuteNonQuery(cmd, m_Connection) > 0) string where = String.Join(" and ", terms.ToArray());
return true;
return false; string query = String.Format("delete from {0} where {1}", m_Realm, where);
cmd.CommandText = query;
return ExecuteNonQuery(cmd, m_Connection) > 0;
} }
} }
} }

View File

@ -91,11 +91,21 @@ namespace OpenSim.Data.SQLite
return m_Folders.Delete(field, val); return m_Folders.Delete(field, val);
} }
public bool DeleteFolders(string[] fields, string[] vals)
{
return m_Folders.Delete(fields, vals);
}
public bool DeleteItems(string field, string val) public bool DeleteItems(string field, string val)
{ {
return m_Items.Delete(field, val); 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) public bool MoveItem(string id, string newParent)
{ {
return m_Items.MoveItem(id, newParent); return m_Items.MoveItem(id, newParent);

View File

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

View File

@ -215,6 +215,12 @@ namespace OpenSim.Framework
set { m_metadata.Temporary = value; } set { m_metadata.Temporary = value; }
} }
public string CreatorID
{
get { return m_metadata.CreatorID; }
set { m_metadata.CreatorID = value; }
}
public AssetFlags Flags public AssetFlags Flags
{ {
get { return m_metadata.Flags; } get { return m_metadata.Flags; }

View File

@ -35,6 +35,7 @@ namespace OpenSim.Framework
public Vector3 Position; public Vector3 Position;
public ulong RegionHandle; public ulong RegionHandle;
public UUID RegionID; public UUID RegionID;
public string Gatekeeper = string.Empty;
public int Version; public int Version;
public AssetLandmark(AssetBase a) public AssetLandmark(AssetBase a)
@ -51,6 +52,8 @@ namespace OpenSim.Framework
string[] parts = temp.Split('\n'); string[] parts = temp.Split('\n');
int.TryParse(parts[0].Substring(17, 1), out Version); int.TryParse(parts[0].Substring(17, 1), out Version);
UUID.TryParse(parts[1].Substring(10, 36), out RegionID); UUID.TryParse(parts[1].Substring(10, 36), out RegionID);
if (parts.Length >= 5)
Gatekeeper = parts[4].Replace("gatekeeper ", "");
// The position is a vector with spaces as separators ("10.3 32.5 43"). // The position is a vector with spaces as separators ("10.3 32.5 43").
// Parse each scalar separately to take into account the system's culture setting. // Parse each scalar separately to take into account the system's culture setting.
string[] scalars = parts[2].Substring(10, parts[2].Length - 10).Split(' '); string[] scalars = parts[2].Substring(10, parts[2].Length - 10).Split(' ');

View File

@ -87,7 +87,7 @@ namespace OpenSim.Framework
public delegate void SameRegionTeleportlRequest(IClientAPI remoteClient, byte[] tpLocReq); public delegate void SameRegionTeleportlRequest(IClientAPI remoteClient, byte[] tpLocReq);
public delegate void TeleportLandmarkRequest( public delegate void TeleportLandmarkRequest(
IClientAPI remoteClient, UUID regionID, Vector3 position); IClientAPI remoteClient, AssetLandmark lm);
public delegate void DisconnectUser(); public delegate void DisconnectUser();
@ -1171,7 +1171,19 @@ namespace OpenSim.Framework
void SendAgentAlertMessage(string message, bool modal); void SendAgentAlertMessage(string message, bool modal);
void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url); void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url);
void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, /// <summary>
/// Open a dialog box on the client.
/// </summary>
/// <param name="objectname"></param>
/// <param name="objectID"></param>
/// <param name="ownerID">/param>
/// <param name="ownerFirstName"></param>
/// <param name="ownerLastName"></param>
/// <param name="msg"></param>
/// <param name="textureID"></param>
/// <param name="ch"></param>
/// <param name="buttonlabels"></param>
void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch,
string[] buttonlabels); string[] buttonlabels);
bool AddMoney(int debit); bool AddMoney(int debit);

View File

@ -35,8 +35,8 @@ namespace OpenSim.Framework
public interface ILandObject public interface ILandObject
{ {
int GetParcelMaxPrimCount(ILandObject thisObject); int GetParcelMaxPrimCount();
int GetSimulatorMaxPrimCount(ILandObject thisObject); int GetSimulatorMaxPrimCount();
int GetPrimsFree(); int GetPrimsFree();
LandData LandData { get; set; } LandData LandData { get; set; }

View File

@ -182,6 +182,9 @@ namespace OpenSim.Framework.Serialization.External
case "FixedSun": case "FixedSun":
settings.FixedSun = bool.Parse(xtr.ReadElementContentAsString()); settings.FixedSun = bool.Parse(xtr.ReadElementContentAsString());
break; break;
case "SunPosition":
settings.SunPosition = double.Parse(xtr.ReadElementContentAsString());
break;
} }
} }
@ -237,8 +240,9 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("TerrainLowerLimit", settings.TerrainLowerLimit.ToString()); xtw.WriteElementString("TerrainLowerLimit", settings.TerrainLowerLimit.ToString());
xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString()); xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString());
xtw.WriteElementString("FixedSun", settings.FixedSun.ToString()); xtw.WriteElementString("FixedSun", settings.FixedSun.ToString());
// XXX: Need to expose interface to get sun phase information from sun module xtw.WriteElementString("SunPosition", settings.SunPosition.ToString());
// xtw.WriteStartElement("SunPhase", // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which
// calculates it automatically according to the date and other factors.
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.WriteEndElement(); xtw.WriteEndElement();

View File

@ -412,7 +412,7 @@ namespace OpenSim.Framework.Servers.HttpServer
// OpenSim.Framework.WebUtil.OSHeaderRequestID // OpenSim.Framework.WebUtil.OSHeaderRequestID
if (request.Headers["opensim-request-id"] != null) if (request.Headers["opensim-request-id"] != null)
reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]); reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]);
// m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl); //m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
@ -440,7 +440,7 @@ namespace OpenSim.Framework.Servers.HttpServer
string path = request.RawUrl; string path = request.RawUrl;
string handlerKey = GetHandlerKey(request.HttpMethod, path); string handlerKey = GetHandlerKey(request.HttpMethod, path);
// m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
if (TryGetStreamHandler(handlerKey, out requestHandler)) if (TryGetStreamHandler(handlerKey, out requestHandler))
{ {

View File

@ -33,7 +33,6 @@ using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
using Animation = OpenSim.Framework.Animation; using Animation = OpenSim.Framework.Animation;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests

View File

@ -1694,5 +1694,68 @@ namespace OpenSim.Framework
return (T)Enum.Parse(typeof(T), value); ; return (T)Enum.Parse(typeof(T), value); ;
} }
#endregion #endregion
#region Universal User Identifiers
/// <summary>
/// </summary>
/// <param name="value">uuid[;endpoint[;name]]</param>
/// <param name="uuid"></param>
/// <param name="url"></param>
/// <param name="firstname"></param>
/// <param name="lastname"></param>
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
{
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
string[] parts = value.Split(';');
if (parts.Length >= 1)
if (!UUID.TryParse(parts[0], out uuid))
return false;
if (parts.Length >= 2)
url = parts[1];
if (parts.Length >= 3)
{
string[] name = parts[2].Split();
if (name.Length == 2)
{
firstname = name[0];
lastname = name[1];
}
}
if (parts.Length >= 4)
secret = parts[3];
return true;
}
/// <summary>
///
/// </summary>
/// <param name="acircuit"></param>
/// <returns>uuid[;endpoint[;name]]</returns>
public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
{
if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
{
string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
if (!agentsURI.EndsWith("/"))
agentsURI += "/";
// This is ugly, but there's no other way, given that the name is changed
// in the agent circuit data for foreigners
if (acircuit.lastname.Contains("@"))
{
string[] parts = acircuit.firstname.Split(new char[] { '.' });
if (parts.Length == 2)
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
}
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
}
else
return acircuit.AgentID.ToString();
}
#endregion
} }
} }

View File

@ -251,11 +251,11 @@ namespace OpenSim.Framework
// This just dumps a warning for any operation that takes more than 100 ms // This just dumps a warning for any operation that takes more than 100 ms
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > LongCallTime) if (tickdiff > LongCallTime)
m_log.InfoFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
reqnum,url,method,tickdiff,tickdata); reqnum,url,method,tickdiff,tickdata);
} }
m_log.WarnFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage); m_log.DebugFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
return ErrorResponseMap(errorMessage); return ErrorResponseMap(errorMessage);
} }
@ -967,7 +967,7 @@ namespace OpenSim.Framework
} }
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e); m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e);
return deserial; return deserial;
} }
finally finally
@ -979,8 +979,11 @@ namespace OpenSim.Framework
try try
{ {
using (WebResponse resp = request.GetResponse()) using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{ {
if (resp.StatusCode == HttpStatusCode.NotFound)
return deserial;
if (resp.ContentLength != 0) if (resp.ContentLength != 0)
{ {
Stream respStream = resp.GetResponseStream(); Stream respStream = resp.GetResponseStream();
@ -989,18 +992,18 @@ namespace OpenSim.Framework
respStream.Close(); respStream.Close();
} }
else else
m_log.WarnFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb); m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
} }
} }
catch (System.InvalidOperationException) catch (System.InvalidOperationException)
{ {
// This is what happens when there is invalid XML // This is what happens when there is invalid XML
m_log.WarnFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString()); m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString());
} }
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e); m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e);
} }
return deserial; return deserial;

View File

@ -231,6 +231,8 @@ namespace OpenSim
configSource.Alias.AddAlias("Off", false); configSource.Alias.AddAlias("Off", false);
configSource.Alias.AddAlias("True", true); configSource.Alias.AddAlias("True", true);
configSource.Alias.AddAlias("False", false); configSource.Alias.AddAlias("False", false);
configSource.Alias.AddAlias("Yes", true);
configSource.Alias.AddAlias("No", false);
configSource.AddSwitch("Startup", "background"); configSource.AddSwitch("Startup", "background");
configSource.AddSwitch("Startup", "inifile"); configSource.AddSwitch("Startup", "inifile");
@ -239,6 +241,8 @@ namespace OpenSim
configSource.AddSwitch("Startup", "physics"); configSource.AddSwitch("Startup", "physics");
configSource.AddSwitch("Startup", "gui"); configSource.AddSwitch("Startup", "gui");
configSource.AddSwitch("Startup", "console"); configSource.AddSwitch("Startup", "console");
configSource.AddSwitch("Startup", "save_crashes");
configSource.AddSwitch("Startup", "crash_dir");
configSource.AddConfig("StandAlone"); configSource.AddConfig("StandAlone");
configSource.AddConfig("Network"); configSource.AddConfig("Network");

View File

@ -267,12 +267,13 @@ namespace OpenSim
m_console.Commands.AddCommand("region", false, "save oar", m_console.Commands.AddCommand("region", false, "save oar",
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
"save oar [-p|--profile=<url>] [<OAR path>]", "save oar [-p|--profile=<url>] [--noassets] [<OAR path>]",
"Save a region's data to an OAR archive.", "Save a region's data to an OAR archive.",
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine // "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
"-p|--profile=<url> adds the url of the profile service to the saved user information" + Environment.NewLine "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
+ "The OAR path must be a filesystem path." + " The OAR path must be a filesystem path."
+ " If this is not given then the oar is saved to region.oar in the current directory.", + " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine
+ "--noassets stops assets being saved to the OAR.",
SaveOar); SaveOar);
m_console.Commands.AddCommand("region", false, "edit scale", m_console.Commands.AddCommand("region", false, "edit scale",

View File

@ -842,7 +842,7 @@ namespace OpenSim
if (regInfo.EstateSettings.EstateID == 0) // No record at all if (regInfo.EstateSettings.EstateID == 0) // No record at all
{ {
MainConsole.Instance.OutputFormat("Region {0} is not part of an estate.", regInfo.RegionName); m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll(); List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
List<string> estateNames = new List<string>(); List<string> estateNames = new List<string>();
@ -853,7 +853,7 @@ namespace OpenSim
{ {
if (estates.Count == 0) if (estates.Count == 0)
{ {
MainConsole.Instance.Output("No existing estates found. You must create a new one."); m_log.Info("[ESTATE] No existing estates found. You must create a new one.");
if (CreateEstate(regInfo, estateNames)) if (CreateEstate(regInfo, estateNames))
break; break;

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Reflection;
using log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Region.ClientStack.Linden
{
/// <summary>
/// SimulatorFeatures capability. This is required for uploading Mesh.
/// Since is accepts an open-ended response, we also send more information
/// for viewers that care to interpret it.
///
/// NOTE: Part of this code was adapted from the Aurora project, specifically
/// the normal part of the response in the capability handler.
/// </summary>
///
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimulatorFeaturesModule : ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
private string m_MapImageServerURL = string.Empty;
private string m_SearchURL = string.Empty;
#region ISharedRegionModule Members
public void Initialise(IConfigSource source)
{
IConfig config = source.Configs["SimulatorFeatures"];
if (config == null)
return;
m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty);
if (m_MapImageServerURL != string.Empty)
{
m_MapImageServerURL = m_MapImageServerURL.Trim();
if (!m_MapImageServerURL.EndsWith("/"))
m_MapImageServerURL = m_MapImageServerURL + "/";
}
m_SearchURL = config.GetString("SearchServerURI", string.Empty);
}
public void AddRegion(Scene s)
{
m_scene = s;
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
}
public void RemoveRegion(Scene s)
{
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
}
public void RegionLoaded(Scene s)
{
}
public void PostInitialise()
{
}
public void Close() { }
public string Name { get { return "SimulatorFeaturesModule"; } }
public Type ReplaceableInterface
{
get { return null; }
}
#endregion
public void RegisterCaps(UUID agentID, Caps caps)
{
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), SimulatorFeatures);
caps.RegisterHandler("SimulatorFeatures", reqHandler);
}
private Hashtable SimulatorFeatures(Hashtable mDhttpMethod)
{
m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
OSDMap data = new OSDMap();
data["MeshRezEnabled"] = true;
data["MeshUploadEnabled"] = true;
data["MeshXferEnabled"] = true;
data["PhysicsMaterialsEnabled"] = true;
OSDMap typesMap = new OSDMap();
typesMap["convex"] = true;
typesMap["none"] = true;
typesMap["prim"] = true;
data["PhysicsShapeTypes"] = typesMap;
// Extra information for viewers that want to use it
OSDMap gridServicesMap = new OSDMap();
if (m_MapImageServerURL != string.Empty)
gridServicesMap["map-server-url"] = m_MapImageServerURL;
if (m_SearchURL != string.Empty)
gridServicesMap["search"] = m_SearchURL;
data["GridServices"] = gridServicesMap;
//Send back data
Hashtable responsedata = new Hashtable();
responsedata["int_response_code"] = 200;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data);
return responsedata;
}
}
}

View File

@ -504,6 +504,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Properties #endregion Properties
// ~LLClientView()
// {
// m_log.DebugFormat("[LLCLIENTVIEW]: Destructor called for {0}, circuit code {1}", Name, CircuitCode);
// }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
@ -1545,6 +1550,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
money.MoneyData.TransactionSuccess = success; money.MoneyData.TransactionSuccess = success;
money.MoneyData.Description = description; money.MoneyData.Description = description;
money.MoneyData.MoneyBalance = balance; money.MoneyData.MoneyBalance = balance;
money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE");
OutPacket(money, ThrottleOutPacketType.Task); OutPacket(money, ThrottleOutPacketType.Task);
} }
@ -2289,7 +2295,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(loadURL, ThrottleOutPacketType.Task); OutPacket(loadURL, ThrottleOutPacketType.Task);
} }
public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) public void SendDialog(
string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg,
UUID textureID, int ch, string[] buttonlabels)
{ {
ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
dialog.Data.ObjectID = objectID; dialog.Data.ObjectID = objectID;
@ -2307,6 +2315,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]); buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
} }
dialog.Buttons = buttons; dialog.Buttons = buttons;
dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
dialog.OwnerData[0].OwnerID = ownerID;
OutPacket(dialog, ThrottleOutPacketType.Task); OutPacket(dialog, ThrottleOutPacketType.Task);
} }
@ -2369,8 +2382,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff; OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff;
} }
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage); SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
viewertime.TimeInfo.SunDirection = Position; viewertime.TimeInfo.SunDirection = Position;
viewertime.TimeInfo.SunAngVelocity = Velocity; viewertime.TimeInfo.SunAngVelocity = Velocity;
@ -8403,16 +8414,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AssetLandmark lm; AssetLandmark lm;
if (lmid != UUID.Zero) if (lmid != UUID.Zero)
{ {
//AssetBase lma = m_assetCache.GetAsset(lmid, false); //AssetBase lma = m_assetCache.GetAsset(lmid, false);
AssetBase lma = m_assetService.Get(lmid.ToString()); AssetBase lma = m_assetService.Get(lmid.ToString());
if (lma == null) if (lma == null)
{ {
// Failed to find landmark // Failed to find landmark
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
tpCancel.Info.SessionID = tpReq.Info.SessionID; // Let's try to search in the user's home asset server
tpCancel.Info.AgentID = tpReq.Info.AgentID; lma = FindAssetInUserAssetServer(lmid.ToString());
OutPacket(tpCancel, ThrottleOutPacketType.Task);
if (lma == null)
{
// Really doesn't exist
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
tpCancel.Info.SessionID = tpReq.Info.SessionID;
tpCancel.Info.AgentID = tpReq.Info.AgentID;
OutPacket(tpCancel, ThrottleOutPacketType.Task);
}
} }
try try
@ -8443,13 +8463,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest;
if (handlerTeleportLandmarkRequest != null) if (handlerTeleportLandmarkRequest != null)
{ {
handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position); handlerTeleportLandmarkRequest(this, lm);
} }
else else
{ {
//no event handler so cancel request //no event handler so cancel request
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel); TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
tpCancel.Info.AgentID = tpReq.Info.AgentID; tpCancel.Info.AgentID = tpReq.Info.AgentID;
tpCancel.Info.SessionID = tpReq.Info.SessionID; tpCancel.Info.SessionID = tpReq.Info.SessionID;
@ -8459,6 +8477,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
} }
private AssetBase FindAssetInUserAssetServer(string id)
{
AgentCircuitData aCircuit = ((Scene)Scene).AuthenticateHandler.GetAgentCircuitData(CircuitCode);
if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
{
string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString();
return ((Scene)Scene).AssetService.Get(assetServer + "/" + id);
}
return null;
}
private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack) private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack)
{ {
TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack; TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;

View File

@ -64,13 +64,13 @@ namespace Flotsam.RegionModules.AssetCache
private bool m_Enabled; private bool m_Enabled;
private const string m_ModuleName = "FlotsamAssetCache"; private const string m_ModuleName = "FlotsamAssetCache";
private const string m_DefaultCacheDirectory = m_ModuleName; private const string m_DefaultCacheDirectory = "./assetcache";
private string m_CacheDirectory = m_DefaultCacheDirectory; private string m_CacheDirectory = m_DefaultCacheDirectory;
private readonly List<char> m_InvalidChars = new List<char>(); private readonly List<char> m_InvalidChars = new List<char>();
private int m_LogLevel = 0; private int m_LogLevel = 0;
private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests private ulong m_HitRateDisplay = 100; // How often to display hit statistics, given in requests
private static ulong m_Requests; private static ulong m_Requests;
private static ulong m_RequestsForInprogress; private static ulong m_RequestsForInprogress;
@ -87,14 +87,14 @@ namespace Flotsam.RegionModules.AssetCache
#endif #endif
private ExpiringCache<string, AssetBase> m_MemoryCache; private ExpiringCache<string, AssetBase> m_MemoryCache;
private bool m_MemoryCacheEnabled = true; private bool m_MemoryCacheEnabled = false;
// Expiration is expressed in hours. // Expiration is expressed in hours.
private const double m_DefaultMemoryExpiration = 1.0; private const double m_DefaultMemoryExpiration = 2;
private const double m_DefaultFileExpiration = 48; private const double m_DefaultFileExpiration = 48;
private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration); private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration);
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(m_DefaultFileExpiration); private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(0.166);
private static int m_CacheDirectoryTiers = 1; private static int m_CacheDirectoryTiers = 1;
private static int m_CacheDirectoryTierLen = 3; private static int m_CacheDirectoryTierLen = 3;
@ -141,26 +141,38 @@ namespace Flotsam.RegionModules.AssetCache
IConfig assetConfig = source.Configs["AssetCache"]; IConfig assetConfig = source.Configs["AssetCache"];
if (assetConfig == null) if (assetConfig == null)
{ {
m_log.Warn("[FLOTSAM ASSET CACHE]: AssetCache missing from OpenSim.ini, using defaults."); m_log.Warn(
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory); "[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults.");
return; }
else
{
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled);
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
#if WAIT_ON_INPROGRESS_REQUESTS
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
#endif
m_LogLevel = assetConfig.GetInt("LogLevel", m_LogLevel);
m_HitRateDisplay = (ulong)assetConfig.GetLong("HitRateDisplay", (long)m_HitRateDisplay);
m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
m_FileExpirationCleanupTimer
= TimeSpan.FromHours(
assetConfig.GetDouble("FileCleanupTimer", m_FileExpirationCleanupTimer.TotalHours));
m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", m_CacheDirectoryTiers);
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen);
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt);
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge);
} }
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_CacheDirectory);
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", false);
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
#if WAIT_ON_INPROGRESS_REQUESTS
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
#endif
m_LogLevel = assetConfig.GetInt("LogLevel", 0);
m_HitRateDisplay = (ulong)assetConfig.GetInt("HitRateDisplay", 1000);
m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration));
if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
{ {
m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds); m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
@ -170,7 +182,6 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheCleanTimer.Start(); m_CacheCleanTimer.Start();
} }
m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1);
if (m_CacheDirectoryTiers < 1) if (m_CacheDirectoryTiers < 1)
{ {
m_CacheDirectoryTiers = 1; m_CacheDirectoryTiers = 1;
@ -180,7 +191,6 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheDirectoryTiers = 3; m_CacheDirectoryTiers = 3;
} }
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", 3);
if (m_CacheDirectoryTierLen < 1) if (m_CacheDirectoryTierLen < 1)
{ {
m_CacheDirectoryTierLen = 1; m_CacheDirectoryTierLen = 1;
@ -190,14 +200,10 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheDirectoryTierLen = 4; m_CacheDirectoryTierLen = 4;
} }
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", 30000); MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", false); MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
} }
} }
} }
@ -723,24 +729,39 @@ namespace Flotsam.RegionModules.AssetCache
break; break;
case "clear": case "clear":
if (cmdparams.Length < 3) if (cmdparams.Length < 2)
{ {
m_log.Warn("[FLOTSAM ASSET CACHE] Please specify memory and/or file cache."); m_log.Warn("[FLOTSAM ASSET CACHE] Usage is fcache clear [file] [memory]");
break; break;
} }
bool clearMemory = false, clearFile = false;
if (cmdparams.Length == 2)
{
clearMemory = true;
clearFile = true;
}
foreach (string s in cmdparams) foreach (string s in cmdparams)
{ {
if (s.ToLower() == "memory") if (s.ToLower() == "memory")
{ clearMemory = true;
m_MemoryCache.Clear();
m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared.");
}
else if (s.ToLower() == "file") else if (s.ToLower() == "file")
{ clearFile = true;
ClearFileCache();
m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared.");
}
} }
if (clearMemory)
{
m_MemoryCache.Clear();
m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared.");
}
if (clearFile)
{
ClearFileCache();
m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared.");
}
break; break;

View File

@ -131,7 +131,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
ScenePresence sp = m_scene.GetScenePresence(avatarID); ScenePresence sp = m_scene.GetScenePresence(avatarID);
if (sp != null) if (sp != null)
sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); sp.ControllingClient.SendDialog(
objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
} }
public void SendUrlToUser( public void SendUrlToUser(

View File

@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
public class FriendsModule : ISharedRegionModule, IFriendsModule public class FriendsModule : ISharedRegionModule, IFriendsModule
{ {
protected bool m_Enabled = false;
protected class UserFriendData protected class UserFriendData
{ {
public UUID PrincipalID; public UUID PrincipalID;
@ -67,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected List<Scene> m_Scenes = new List<Scene>(); protected List<Scene> m_Scenes = new List<Scene>();
@ -130,7 +132,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
#region ISharedRegionModule
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{
IConfig moduleConfig = config.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
if (name == Name)
{
InitModule(config);
m_Enabled = true;
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
}
}
}
protected void InitModule(IConfigSource config)
{ {
IConfig friendsConfig = config.Configs["Friends"]; IConfig friendsConfig = config.Configs["Friends"];
if (friendsConfig != null) if (friendsConfig != null)
@ -153,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue"); m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
throw new Exception("Connector load error"); throw new Exception("Connector load error");
} }
} }
public void PostInitialise() public void PostInitialise()
@ -164,8 +182,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
} }
public void AddRegion(Scene scene) public virtual void AddRegion(Scene scene)
{ {
if (!m_Enabled)
return;
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
m_Scenes.Add(scene); m_Scenes.Add(scene);
scene.RegisterModuleInterface<IFriendsModule>(this); scene.RegisterModuleInterface<IFriendsModule>(this);
@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
if (!m_Enabled)
return;
m_Scenes.Remove(scene); m_Scenes.Remove(scene);
} }
public string Name public virtual string Name
{ {
get { return "FriendsModule"; } get { return "FriendsModule"; }
} }
@ -194,13 +219,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
get { return null; } get { return null; }
} }
public uint GetFriendPerms(UUID principalID, UUID friendID) #endregion
public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
{ {
FriendInfo[] friends = GetFriends(principalID); FriendInfo[] friends = GetFriends(principalID);
foreach (FriendInfo fi in friends) FriendInfo finfo = GetFriend(friends, friendID);
if (finfo != null)
{ {
if (fi.Friend == friendID.ToString()) return (uint)finfo.TheirFlags;
return (uint)fi.TheirFlags;
} }
return 0; return 0;
@ -214,30 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.OnTerminateFriendship += OnTerminateFriendship; client.OnTerminateFriendship += OnTerminateFriendship;
client.OnGrantUserRights += OnGrantUserRights; client.OnGrantUserRights += OnGrantUserRights;
// Asynchronously fetch the friends list or increment the refcount for the existing Util.FireAndForget(delegate { FetchFriendslist(client); });
// friends list }
Util.FireAndForget(
delegate(object o)
{
lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(client.AgentId, out friendsData))
{
friendsData.Refcount++;
}
else
{
friendsData = new UserFriendData();
friendsData.PrincipalID = client.AgentId;
friendsData.Friends = FriendsService.GetFriends(client.AgentId);
friendsData.Refcount = 1;
m_Friends[client.AgentId] = friendsData; /// Fetch the friends list or increment the refcount for the existing
} /// friends list
} /// Returns true if the list was fetched, false if it wasn't
protected virtual bool FetchFriendslist(IClientAPI client)
{
UUID agentID = client.AgentId;
lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData))
{
friendsData.Refcount++;
return false;
} }
); else
{
friendsData = new UserFriendData();
friendsData.PrincipalID = agentID;
friendsData.Friends = GetFriendsFromService(client);
friendsData.Refcount = 1;
m_Friends[agentID] = friendsData;
return true;
}
}
} }
private void OnClientClosed(UUID agentID, Scene scene) private void OnClientClosed(UUID agentID, Scene scene)
@ -263,14 +294,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnMakeRootAgent(ScenePresence sp) private void OnMakeRootAgent(ScenePresence sp)
{ {
UUID agentID = sp.ControllingClient.AgentId; RefetchFriends(sp.ControllingClient);
UpdateFriendsCache(agentID);
} }
private void OnClientLogin(IClientAPI client) private void OnClientLogin(IClientAPI client)
{ {
UUID agentID = client.AgentId; UUID agentID = client.AgentId;
//m_log.DebugFormat("[XXX]: OnClientLogin!");
// Inform the friends that this user is online // Inform the friends that this user is online
StatusChange(agentID, true); StatusChange(agentID, true);
@ -279,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_NeedsListOfFriends.Add(agentID); m_NeedsListOfFriends.Add(agentID);
} }
public void SendFriendsOnlineIfNeeded(IClientAPI client) public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
{ {
UUID agentID = client.AgentId; UUID agentID = client.AgentId;
@ -287,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
lock (m_NeedsListOfFriends) lock (m_NeedsListOfFriends)
{ {
if (!m_NeedsListOfFriends.Remove(agentID)) if (!m_NeedsListOfFriends.Remove(agentID))
return; return false;
} }
// Send the friends online // Send the friends online
@ -313,10 +344,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
foreach (string fid in outstanding) foreach (string fid in outstanding)
{ {
UUID fromAgentID; UUID fromAgentID;
if (!UUID.TryParse(fid, out fromAgentID)) string firstname = "Unknown", lastname = "User";
if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
{
m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
continue; continue;
}
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
PresenceInfo presence = null; PresenceInfo presence = null;
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
@ -326,13 +359,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
im.offline = 0; im.offline = 0;
im.fromAgentID = fromAgentID.Guid; im.fromAgentID = fromAgentID.Guid;
im.fromAgentName = account.FirstName + " " + account.LastName; im.fromAgentName = firstname + " " + lastname;
im.offline = (byte)((presence == null) ? 1 : 0); im.offline = (byte)((presence == null) ? 1 : 0);
im.imSessionID = im.fromAgentID; im.imSessionID = im.fromAgentID;
im.message = FriendshipMessage(fid);
// Finally // Finally
LocalFriendshipOffered(agentID, im); LocalFriendshipOffered(agentID, im);
} }
return true;
}
protected virtual string FriendshipMessage(string friendID)
{
return "Will you be my friend?";
}
protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
{
first = "Unknown"; last = "User";
if (!UUID.TryParse(fid, out agentID))
return false;
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
if (account != null)
{
first = account.FirstName;
last = account.LastName;
}
return true;
} }
List<UUID> GetOnlineFriends(UUID userID) List<UUID> GetOnlineFriends(UUID userID)
@ -348,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
if (friendList.Count > 0) if (friendList.Count > 0)
{ GetOnlineFriends(userID, friendList, online);
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
foreach (PresenceInfo pi in presence)
{
UUID presenceID;
if (UUID.TryParse(pi.UserID, out presenceID))
online.Add(presenceID);
}
}
return online; return online;
} }
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
{
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
foreach (PresenceInfo pi in presence)
{
UUID presenceID;
if (UUID.TryParse(pi.UserID, out presenceID))
online.Add(presenceID);
}
}
/// <summary> /// <summary>
/// Find the client for a ID /// Find the client for a ID
/// </summary> /// </summary>
@ -415,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
Util.FireAndForget( Util.FireAndForget(
delegate delegate
{ {
foreach (FriendInfo fi in friendList) m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
{ // Notify about this user status
//m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); StatusNotify(friendList, agentID, online);
// Notify about this user status
StatusNotify(fi, agentID, online);
}
} }
); );
} }
} }
private void StatusNotify(FriendInfo friend, UUID userID, bool online) protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{ {
UUID friendID; foreach (FriendInfo friend in friendList)
if (UUID.TryParse(friend.Friend, out friendID))
{ {
// Try local UUID friendID;
if (LocalStatusNotification(userID, friendID, online)) if (UUID.TryParse(friend.Friend, out friendID))
return;
// The friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0)
{ {
PresenceInfo friendSession = null; // Try local
foreach (PresenceInfo pinfo in friendSessions) if (LocalStatusNotification(userID, friendID, online))
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad return;
{
friendSession = pinfo;
break;
}
if (friendSession != null) // The friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0)
{ {
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); PresenceInfo friendSession = null;
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); foreach (PresenceInfo pinfo in friendSessions)
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
} {
} friendSession = pinfo;
break;
}
// Friend is not online. Ignore. if (friendSession != null)
} {
else GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
{ //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
}
}
// Friend is not online. Ignore.
}
else
{
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
}
} }
} }
@ -475,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// This user wants to be friends with the other user. // This user wants to be friends with the other user.
// Let's add the relation backwards, in case the other is not online // Let's add the relation backwards, in case the other is not online
FriendsService.StoreFriend(friendID, principalID.ToString(), 0); StoreBackwards(friendID, principalID);
// Now let's ask the other user to be friends with this user // Now let's ask the other user to be friends with this user
ForwardFriendshipOffer(principalID, friendID, im); ForwardFriendshipOffer(principalID, friendID, im);
@ -487,11 +547,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
// We stick this agent's ID as imSession, so that it's directly available on the receiving end // We stick this agent's ID as imSession, so that it's directly available on the receiving end
im.imSessionID = im.fromAgentID; im.imSessionID = im.fromAgentID;
im.fromAgentName = GetFriendshipRequesterName(agentID);
// Try the local sim // Try the local sim
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
if (LocalFriendshipOffered(friendID, im)) if (LocalFriendshipOffered(friendID, im))
return; return;
@ -509,15 +567,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// If the prospective friend is not online, he'll get the message upon login. // If the prospective friend is not online, he'll get the message upon login.
} }
protected virtual string GetFriendshipRequesterName(UUID agentID)
{
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
}
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
{ {
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID); m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
FriendsService.StoreFriend(agentID, friendID.ToString(), 1); StoreFriendships(agentID, friendID);
FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
// Update the local cache // Update the local cache
UpdateFriendsCache(agentID); RefetchFriends(client);
// //
// Notify the friend // Notify the friend
@ -548,8 +611,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
FriendsService.Delete(agentID, friendID.ToString()); DeleteFriendship(agentID, friendID);
FriendsService.Delete(friendID, agentID.ToString());
// //
// Notify the friend // Notify the friend
@ -576,11 +638,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
{ {
FriendsService.Delete(agentID, exfriendID.ToString()); if (!DeleteFriendship(agentID, exfriendID))
FriendsService.Delete(exfriendID, agentID.ToString()); client.SendAlertMessage("Unable to terminate friendship on this sim.");
// Update local cache // Update local cache
UpdateFriendsCache(agentID); RefetchFriends(client);
client.SendTerminateFriend(exfriendID); client.SendTerminateFriend(exfriendID);
@ -606,23 +668,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
{ {
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
FriendInfo[] friends = GetFriends(remoteClient.AgentId); FriendInfo[] friends = GetFriends(remoteClient.AgentId);
if (friends.Length == 0) if (friends.Length == 0)
return;
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
// Let's find the friend in this user's friend list
FriendInfo friend = null;
foreach (FriendInfo fi in friends)
{ {
if (fi.Friend == target.ToString()) return;
friend = fi;
} }
// Let's find the friend in this user's friend list
FriendInfo friend = GetFriend(friends, target);
if (friend != null) // Found it if (friend != null) // Found it
{ {
// Store it on the DB // Store it on the DB
FriendsService.StoreFriend(requester, target.ToString(), rights); if (!StoreRights(requester, target, rights))
{
remoteClient.SendAlertMessage("Unable to grant rights.");
return;
}
// Store it in the local cache // Store it in the local cache
int myFlags = friend.MyFlags; int myFlags = friend.MyFlags;
@ -652,6 +716,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
} }
else
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
}
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
{
foreach (FriendInfo fi in friends)
{
if (fi.Friend == friendID.ToString())
return fi;
}
return null;
} }
#region Local #region Local
@ -680,7 +756,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendClient.SendInstantMessage(im); friendClient.SendInstantMessage(im);
// Update the local cache // Update the local cache
UpdateFriendsCache(friendID); RefetchFriends(friendClient);
// we're done // we're done
return true; return true;
@ -713,7 +789,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// the friend in this sim as root agent // the friend in this sim as root agent
friendClient.SendTerminateFriend(exfriendID); friendClient.SendTerminateFriend(exfriendID);
// update local cache // update local cache
UpdateFriendsCache(exfriendID); RefetchFriends(friendClient);
// we're done // we're done
return true; return true;
} }
@ -743,15 +819,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
// Update local cache // Update local cache
lock (m_Friends) UpdateLocalCache(userID, friendID, rights);
{
FriendInfo[] friends = GetFriends(friendID);
foreach (FriendInfo finfo in friends)
{
if (finfo.Friend == userID.ToString())
finfo.TheirFlags = rights;
}
}
return true; return true;
} }
@ -762,10 +830,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online) public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
{ {
m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
IClientAPI friendClient = LocateClientObject(friendID); IClientAPI friendClient = LocateClientObject(friendID);
if (friendClient != null) if (friendClient != null)
{ {
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
// the friend in this sim as root agent // the friend in this sim as root agent
if (online) if (online)
friendClient.SendAgentOnline(new UUID[] { userID }); friendClient.SendAgentOnline(new UUID[] { userID });
@ -780,7 +848,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion #endregion
private FriendInfo[] GetFriends(UUID agentID) #region Get / Set friends in several flavours
/// <summary>
/// Get friends from local cache only
/// </summary>
/// <param name="agentID"></param>
/// <returns></returns>
protected FriendInfo[] GetFriends(UUID agentID)
{ {
UserFriendData friendsData; UserFriendData friendsData;
@ -793,14 +867,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return EMPTY_FRIENDS; return EMPTY_FRIENDS;
} }
private void UpdateFriendsCache(UUID agentID) /// <summary>
/// Update loca cache only
/// </summary>
/// <param name="userID"></param>
/// <param name="friendID"></param>
/// <param name="rights"></param>
protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
{ {
// Update local cache
lock (m_Friends)
{
FriendInfo[] friends = GetFriends(friendID);
FriendInfo finfo = GetFriend(friends, userID);
finfo.TheirFlags = rights;
}
}
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
{
return FriendsService.GetFriends(client.AgentId);
}
private void RefetchFriends(IClientAPI client)
{
UUID agentID = client.AgentId;
lock (m_Friends) lock (m_Friends)
{ {
UserFriendData friendsData; UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData)) if (m_Friends.TryGetValue(agentID, out friendsData))
friendsData.Friends = FriendsService.GetFriends(agentID); friendsData.Friends = GetFriendsFromService(client);
} }
} }
protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
{
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
return true;
}
protected virtual void StoreBackwards(UUID friendID, UUID agentID)
{
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
}
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
{
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
}
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
{
FriendsService.Delete(agentID, exfriendID.ToString());
FriendsService.Delete(exfriendID, agentID.ToString());
return true;
}
#endregion
} }
} }

View File

@ -0,0 +1,623 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using Nini.Config;
using Nwc.XmlRpc;
using Mono.Addins;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.Avatar.Friends
{
public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region ISharedRegionModule
public override string Name
{
get { return "HGFriendsModule"; }
}
public override void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
base.AddRegion(scene);
scene.RegisterModuleInterface<IFriendsSimConnector>(this);
}
#endregion
#region IFriendsSimConnector
/// <summary>
/// Notify the user that the friend's status changed
/// </summary>
/// <param name="userID">user to be notified</param>
/// <param name="friendID">friend whose status changed</param>
/// <param name="online">status</param>
/// <returns></returns>
public bool StatusNotify(UUID friendID, UUID userID, bool online)
{
return LocalStatusNotification(friendID, userID, online);
}
#endregion
protected override bool FetchFriendslist(IClientAPI client)
{
if (base.FetchFriendslist(client))
{
UUID agentID = client.AgentId;
// we do this only for the root agent
if (m_Friends[agentID].Refcount == 1)
{
// We need to preload the user management cache with the names
// of foreign friends, just like we do with SOPs' creators
foreach (FriendInfo finfo in m_Friends[agentID].Friends)
{
if (finfo.TheirFlags != -1)
{
UUID id;
if (!UUID.TryParse(finfo.Friend, out id))
{
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
{
IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
uMan.AddUser(id, url + ";" + first + " " + last);
}
}
}
}
return true;
}
}
return false;
}
public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
{
if (base.SendFriendsOnlineIfNeeded(client))
{
AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
{
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
if (account == null) // foreign
{
FriendInfo[] friends = GetFriends(client.AgentId);
foreach (FriendInfo f in friends)
{
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
}
}
}
}
return false;
}
protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
{
List<string> fList = new List<string>();
foreach (string s in friendList)
fList.Add(s.Substring(0, 36));
PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
foreach (PresenceInfo pi in presence)
{
UUID presenceID;
if (UUID.TryParse(pi.UserID, out presenceID))
online.Add(presenceID);
}
}
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
//{
// // Let's single out the UUIs
// List<string> localFriends = new List<string>();
// List<string> foreignFriends = new List<string>();
// string tmp = string.Empty;
// foreach (string s in friendList)
// {
// UUID id;
// if (UUID.TryParse(s, out id))
// localFriends.Add(s);
// else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
// {
// foreignFriends.Add(s);
// // add it here too, who knows maybe the foreign friends happens to be on this grid
// localFriends.Add(id.ToString());
// }
// }
// // OK, see who's present on this grid
// List<string> toBeRemoved = new List<string>();
// PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
// foreach (PresenceInfo pi in presence)
// {
// UUID presenceID;
// if (UUID.TryParse(pi.UserID, out presenceID))
// {
// online.Add(presenceID);
// foreach (string s in foreignFriends)
// if (s.StartsWith(pi.UserID))
// toBeRemoved.Add(s);
// }
// }
// foreach (string s in toBeRemoved)
// foreignFriends.Remove(s);
// // OK, let's send this up the stack, and leave a closure here
// // collecting online friends in other grids
// Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
//}
//private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
//{
// // let's divide the friends on a per-domain basis
// Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
// foreach (string friend in foreignFriends)
// {
// UUID friendID;
// if (!UUID.TryParse(friend, out friendID))
// {
// // it's a foreign friend
// string url = string.Empty, tmp = string.Empty;
// if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
// {
// if (!friendsPerDomain.ContainsKey(url))
// friendsPerDomain[url] = new List<string>();
// friendsPerDomain[url].Add(friend);
// }
// }
// }
// // Now, call those worlds
// foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
// {
// List<string> ids = new List<string>();
// foreach (string f in kvp.Value)
// ids.Add(f);
// UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
// List<UUID> online = uConn.GetOnlineFriends(userID, ids);
// // Finally send the notifications to the user
// // this whole process may take a while, so let's check at every
// // iteration that the user is still here
// IClientAPI client = LocateClientObject(userID);
// if (client != null)
// client.SendAgentOnline(online.ToArray());
// else
// break;
// }
//}
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{
// First, let's divide the friends on a per-domain basis
Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
foreach (FriendInfo friend in friendList)
{
UUID friendID;
if (UUID.TryParse(friend.Friend, out friendID))
{
if (!friendsPerDomain.ContainsKey("local"))
friendsPerDomain["local"] = new List<FriendInfo>();
friendsPerDomain["local"].Add(friend);
}
else
{
// it's a foreign friend
string url = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
{
// Let's try our luck in the local sim. Who knows, maybe it's here
if (LocalStatusNotification(userID, friendID, online))
continue;
if (!friendsPerDomain.ContainsKey(url))
friendsPerDomain[url] = new List<FriendInfo>();
friendsPerDomain[url].Add(friend);
}
}
}
// For the local friends, just call the base method
// Let's do this first of all
if (friendsPerDomain.ContainsKey("local"))
base.StatusNotify(friendsPerDomain["local"], userID, online);
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
{
if (kvp.Key != "local")
{
// For the others, call the user agent service
List<string> ids = new List<string>();
foreach (FriendInfo f in kvp.Value)
ids.Add(f.Friend);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
if (online && friendsOnline.Count > 0)
{
IClientAPI client = LocateClientObject(userID);
if (client != null)
client.SendAgentOnline(friendsOnline.ToArray());
}
}
}
}
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
{
first = "Unknown"; last = "User";
if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
return true;
// fid is not a UUID...
string url = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
{
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
userMan.AddUser(agentID, first, last, url);
return true;
}
return false;
}
protected override string GetFriendshipRequesterName(UUID agentID)
{
// For the time being we assume that HG friendship requests can only happen
// when avies are on the same region.
IClientAPI client = LocateClientObject(agentID);
if (client != null)
return client.FirstName + " " + client.LastName;
else
return base.GetFriendshipRequesterName(agentID);
}
protected override string FriendshipMessage(string friendID)
{
UUID id;
if (UUID.TryParse(friendID, out id))
return base.FriendshipMessage(friendID);
return "Please confirm this friendship you made while you were away.";
}
protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
{
foreach (FriendInfo fi in friends)
{
if (fi.Friend.StartsWith(friendID.ToString()))
return fi;
}
return null;
}
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
{
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
if (account1 != null)
return base.GetFriendsFromService(client);
FriendInfo[] finfos = new FriendInfo[0];
// Foreigner
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
if (agentClientCircuit != null)
{
string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
finfos = FriendsService.GetFriends(agentUUI);
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
}
return finfos;
}
protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
{
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
// Are they both local users?
if (account1 != null && account2 != null)
{
// local grid users
return base.StoreRights(agentID, friendID, rights);
}
if (account1 != null) // agent is local, friend is foreigner
{
FriendInfo[] finfos = GetFriends(agentID);
FriendInfo finfo = GetFriend(finfos, friendID);
if (finfo != null)
{
FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
return true;
}
}
if (account2 != null) // agent is foreigner, friend is local
{
string agentUUI = GetUUI(friendID, agentID);
if (agentUUI != string.Empty)
{
FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
return true;
}
}
return false;
}
protected override void StoreBackwards(UUID friendID, UUID agentID)
{
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
// Are they both local users?
if (account1 != null && account2 != null)
{
// local grid users
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
base.StoreBackwards(friendID, agentID);
return;
}
// no provision for this temporary friendship state
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
}
protected override void StoreFriendships(UUID agentID, UUID friendID)
{
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
// Are they both local users?
if (agentAccount != null && friendAccount != null)
{
// local grid users
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
base.StoreFriendships(agentID, friendID);
return;
}
// ok, at least one of them is foreigner, let's get their data
IClientAPI agentClient = LocateClientObject(agentID);
IClientAPI friendClient = LocateClientObject(friendID);
AgentCircuitData agentClientCircuit = null;
AgentCircuitData friendClientCircuit = null;
string agentUUI = string.Empty;
string friendUUI = string.Empty;
string agentFriendService = string.Empty;
string friendFriendService = string.Empty;
if (agentClient != null)
{
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
}
if (friendClient != null)
{
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
}
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
agentUUI, friendUUI, agentFriendService, friendFriendService);
// Generate a random 8-character hex number that will sign this friendship
string secret = UUID.Random().ToString().Substring(0, 8);
if (agentAccount != null) // agent is local, 'friend' is foreigner
{
// This may happen when the agent returned home, in which case the friend is not there
// We need to look for its information in the friends list itself
bool confirming = false;
if (friendUUI == string.Empty)
{
FriendInfo[] finfos = GetFriends(agentID);
foreach (FriendInfo finfo in finfos)
{
if (finfo.TheirFlags == -1)
{
if (finfo.Friend.StartsWith(friendID.ToString()))
{
friendUUI = finfo.Friend;
confirming = true;
}
}
}
}
// If it's confirming the friendship, we already have the full friendUUI with the secret
string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
// store in the local friends service a reference to the foreign friend
FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
// and also the converse
FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
if (!confirming && friendClientCircuit != null)
{
// store in the foreign friends service a reference to the local agent
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
}
}
else if (friendAccount != null) // 'friend' is local, agent is foreigner
{
// store in the local friends service a reference to the foreign agent
FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
// and also the converse
FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
if (agentClientCircuit != null)
{
// store in the foreign friends service a reference to the local agent
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
}
}
else // They're both foreigners!
{
HGFriendsServicesConnector friendsConn;
if (agentClientCircuit != null)
{
friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
}
if (friendClientCircuit != null)
{
friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
}
}
// my brain hurts now
}
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
{
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
// Are they both local users?
if (agentAccount != null && friendAccount != null)
{
// local grid users
return base.DeleteFriendship(agentID, exfriendID);
}
// ok, at least one of them is foreigner, let's get their data
string agentUUI = string.Empty;
string friendUUI = string.Empty;
if (agentAccount != null) // agent is local, 'friend' is foreigner
{
// We need to look for its information in the friends list itself
FriendInfo[] finfos = GetFriends(agentID);
FriendInfo finfo = GetFriend(finfos, exfriendID);
if (finfo != null)
{
friendUUI = finfo.Friend;
// delete in the local friends service the reference to the foreign friend
FriendsService.Delete(agentID, friendUUI);
// and also the converse
FriendsService.Delete(friendUUI, agentID.ToString());
// notify the exfriend's service
Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
return true;
}
}
else if (friendAccount != null) // agent is foreigner, 'friend' is local
{
agentUUI = GetUUI(exfriendID, agentID);
if (agentUUI != string.Empty)
{
// delete in the local friends service the reference to the foreign agent
FriendsService.Delete(exfriendID, agentUUI);
// and also the converse
FriendsService.Delete(agentUUI, exfriendID.ToString());
// notify the agent's service?
Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
return true;
}
}
//else They're both foreigners! Can't handle this
return false;
}
private string GetUUI(UUID localUser, UUID foreignUser)
{
// Let's see if the user is here by any chance
FriendInfo[] finfos = GetFriends(localUser);
if (finfos != EMPTY_FRIENDS) // friend is here, cool
{
FriendInfo finfo = GetFriend(finfos, foreignUser);
if (finfo != null)
{
return finfo.Friend;
}
}
else // user is not currently on this sim, need to get from the service
{
finfos = FriendsService.GetFriends(localUser);
foreach (FriendInfo finfo in finfos)
{
if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
{
return finfo.Friend;
}
}
}
return string.Empty;
}
private void Delete(UUID foreignUser, UUID localUser, string uui)
{
UUID id;
string url = string.Empty, secret = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
friendConn.DeleteFriendship(foreignUser, localUser, secret);
}
}
}
}

View File

@ -0,0 +1,356 @@
/*
* 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;
}
//DSG: make this function public, so that we can call from outside to
//use the Grid Service to send the instant message.
public virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
{
}
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

@ -49,7 +49,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
private bool m_Enabled = false; private bool m_Enabled = false;
protected List<Scene> m_Scenes = new List<Scene>(); protected List<Scene> m_Scenes = new List<Scene>();
protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>(); protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>();
protected Dictionary<UUID, GridRegion> m_RegionInfoMap = new Dictionary<UUID, GridRegion>();
public event UndeliveredMessage OnUndeliveredMessage; public event UndeliveredMessage OnUndeliveredMessage;
@ -537,19 +536,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
if (upd != null) if (upd != null)
{ {
GridRegion reginfo = null; GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, upd.RegionID);
// Try to pull reginfo from our cache
lock (m_RegionInfoMap)
{
if (!m_RegionInfoMap.TryGetValue(upd.RegionID, out reginfo))
reginfo = null;
}
// If it wasn't there, then look it up from grid.
if (reginfo == null)
{
reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, upd.RegionID);
}
// If we found the reginfo, send the IM to the region // If we found the reginfo, send the IM to the region
if (reginfo != null) if (reginfo != null)
@ -574,13 +561,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
m_UserRegionMap.Add(toAgentID, upd.RegionID); m_UserRegionMap.Add(toAgentID, upd.RegionID);
} }
} }
lock (m_RegionInfoMap)
{
// Since we never look it up again, we don't need to update it
// but if it's not in the map yet, add it now.
if (!m_RegionInfoMap.ContainsKey(upd.RegionID))
m_RegionInfoMap.Add(upd.RegionID, reginfo);
}
result(true); result(true);
} }
else else

View File

@ -149,14 +149,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <summary> /// <summary>
/// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder. /// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder.
/// /// </summary>
/// <remarks>
/// This method does not handle paths that contain multiple delimitors /// This method does not handle paths that contain multiple delimitors
/// ///
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
/// XPath like expression /// XPath like expression
/// ///
/// FIXME: Delimitors which occur in names themselves are not currently escapable. /// FIXME: Delimitors which occur in names themselves are not currently escapable.
/// </summary> /// </remarks>
/// ///
/// <param name="inventoryService"> /// <param name="inventoryService">
/// Inventory service to query /// Inventory service to query
@ -178,32 +179,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return FindItemByPath(inventoryService, rootFolder, path); return FindItemByPath(inventoryService, rootFolder, path);
} }
/// <summary> /// <summary>
/// Find an item given a PATH_DELIMITOR delimited path starting from this folder. /// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
/// /// </summary>
/// This method does not handle paths that contain multiple delimitors /// <remarks>
/// This method does not handle paths that contain multiple delimiters
/// ///
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
/// XPath like expression /// XPath like expression
/// ///
/// FIXME: Delimitors which occur in names themselves are not currently escapable. /// FIXME: Delimitors which occur in names themselves are not currently escapable.
/// </summary> /// </remarks>
/// ///
/// <param name="inventoryService"> /// <param name="inventoryService">Inventory service to query</param>
/// Inventory service to query /// <param name="startFolder">The folder from which the path starts</param>
/// </param> /// <param name="path">The path to the required item.</param>
/// <param name="startFolder">
/// The folder from which the path starts
/// </param>
/// <param name="path">
/// <param name="path">
/// The path to the required item.
/// </param>
/// <returns>null if the item is not found</returns> /// <returns>null if the item is not found</returns>
public static InventoryItemBase FindItemByPath( public static InventoryItemBase FindItemByPath(
IInventoryService inventoryService, InventoryFolderBase startFolder, string path) IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
{ {
List<InventoryItemBase> foundItems = FindItemsByPath(inventoryService, startFolder, path);
if (foundItems.Count != 0)
return foundItems[0];
else
return null;
}
public static List<InventoryItemBase> FindItemsByPath(
IInventoryService inventoryService, UUID userId, string path)
{
InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
if (null == rootFolder)
return new List<InventoryItemBase>();
return FindItemsByPath(inventoryService, rootFolder, path);
}
/// <summary>
/// Find items that match a given PATH_DELIMITOR delimited path starting from this folder.
/// </summary>
/// <remarks>
/// This method does not handle paths that contain multiple delimiters
///
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
/// XPath like expression
///
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
/// </remarks>
///
/// <param name="inventoryService">Inventory service to query</param>
/// <param name="startFolder">The folder from which the path starts</param>
/// <param name="path">The path to the required item.</param>
/// <returns>The items that were found with this path. An empty list if no items were found.</returns>
public static List<InventoryItemBase> FindItemsByPath(
IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
{
List<InventoryItemBase> foundItems = new List<InventoryItemBase>();
// If the path isn't just / then trim any starting extraneous slashes // If the path isn't just / then trim any starting extraneous slashes
path = path.TrimStart(new char[] { PATH_DELIMITER }); path = path.TrimStart(new char[] { PATH_DELIMITER });
@ -215,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (components.Length == 1) if (components.Length == 1)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}", // "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
// components[0], startFolder.Name, startFolder.ID); // components[0], startFolder.Name, startFolder.ID);
List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count); // m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
foreach (InventoryItemBase item in items) foreach (InventoryItemBase item in items)
@ -227,24 +262,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID); // m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
if (item.Name == components[0]) if (item.Name == components[0])
return item; foundItems.Add(item);
} }
} }
else else
{ {
// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]); // m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
foreach (InventoryFolderBase folder in contents.Folders) foreach (InventoryFolderBase folder in contents.Folders)
{ {
if (folder.Name == components[0]) if (folder.Name == components[0])
return FindItemByPath(inventoryService, folder, components[1]); foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1]));
} }
} }
// We didn't find an item or intermediate folder with the given name return foundItems;
return null;
} }
/// <summary> /// <summary>

View File

@ -46,6 +46,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Determine whether this archive will save assets. Default is true.
/// </summary>
public bool SaveAssets { get; set; }
/// <value> /// <value>
/// Used to select all inventory nodes in a folder but not the folder itself /// Used to select all inventory nodes in a folder but not the folder itself
/// </value> /// </value>
@ -112,6 +117,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_invPath = invPath; m_invPath = invPath;
m_saveStream = saveStream; m_saveStream = saveStream;
m_assetGatherer = new UuidGatherer(m_scene.AssetService); m_assetGatherer = new UuidGatherer(m_scene.AssetService);
SaveAssets = true;
} }
protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
@ -140,7 +147,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
{ {
if (options.ContainsKey("verbose")) if (options.ContainsKey("verbose"))
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving item {0} with asset {1}", inventoryItem.ID, inventoryItem.AssetID); m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}",
inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID);
string filename = path + CreateArchiveItemName(inventoryItem); string filename = path + CreateArchiveItemName(inventoryItem);
@ -150,7 +159,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
m_archiveWriter.WriteFile(filename, serialization); m_archiveWriter.WriteFile(filename, serialization);
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); 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);
} }
/// <summary> /// <summary>
@ -195,6 +208,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// </summary> /// </summary>
public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
{ {
if (options.ContainsKey("noassets") && (bool)options["noassets"])
SaveAssets = false;
try try
{ {
InventoryFolderBase inventoryFolder = null; InventoryFolderBase inventoryFolder = null;
@ -241,10 +257,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// The path may point to an item instead // The path may point to an item instead
if (inventoryFolder == null) if (inventoryFolder == null)
{
inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
//inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
}
if (null == inventoryFolder && null == inventoryItem) if (null == inventoryFolder && null == inventoryItem)
{ {
@ -285,12 +298,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// Don't put all this profile information into the archive right now. // Don't put all this profile information into the archive right now.
//SaveUsers(); //SaveUsers();
new AssetsRequest( if (SaveAssets)
new AssetsArchiver(m_archiveWriter), {
m_assetUuids, m_scene.AssetService, m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count);
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
options, ReceivedAllAssets).Execute(); new AssetsRequest(
new AssetsArchiver(m_archiveWriter),
m_assetUuids, m_scene.AssetService,
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
options, ReceivedAllAssets).Execute();
}
else
{
m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified");
ReceivedAllAssets(new List<UUID>(), new List<UUID>());
}
} }
catch (Exception) catch (Exception)
{ {
@ -387,19 +411,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// </summary> /// </summary>
/// <param name="options"></param> /// <param name="options"></param>
/// <returns></returns> /// <returns></returns>
public static string CreateControlFile(Dictionary<string, object> options) public string CreateControlFile(Dictionary<string, object> options)
{ {
int majorVersion, minorVersion; int majorVersion, minorVersion;
if (options.ContainsKey("profile")) if (options.ContainsKey("profile"))
{ {
majorVersion = 1; majorVersion = 1;
minorVersion = 1; minorVersion = 2;
} }
else else
{ {
majorVersion = 0; majorVersion = 0;
minorVersion = 2; minorVersion = 3;
} }
m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion);
@ -411,6 +435,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
xtw.WriteStartElement("archive"); xtw.WriteStartElement("archive");
xtw.WriteAttributeString("major_version", majorVersion.ToString()); xtw.WriteAttributeString("major_version", majorVersion.ToString());
xtw.WriteAttributeString("minor_version", minorVersion.ToString()); xtw.WriteAttributeString("minor_version", minorVersion.ToString());
xtw.WriteElementString("assets_included", SaveAssets.ToString());
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();

View File

@ -122,7 +122,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
scene.AddCommand( scene.AddCommand(
this, "save iar", this, "save iar",
"save iar [--p|-profile=<url>] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]", "save iar [--p|-profile=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]",
"Save user inventory archive (IAR).", "Save user inventory archive (IAR).",
"<first> is the user's first name." + Environment.NewLine "<first> is the user's first name." + Environment.NewLine
+ "<last> is the user's last name." + Environment.NewLine + "<last> is the user's last name." + Environment.NewLine
@ -130,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
+ "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine + "-c|--creators preserves information about foreign creators." + Environment.NewLine
+ "-v|--verbose extra debug messages." + Environment.NewLine + "-v|--verbose extra debug messages." + Environment.NewLine
+ "--noassets stops assets being saved to the IAR."
+ "<IAR path> is the filesystem path at which to save the IAR." + "<IAR path> is the filesystem path at which to save the IAR."
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
HandleSaveInvConsoleCommand); HandleSaveInvConsoleCommand);
@ -398,6 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
List<string> mainParams = ops.Parse(cmdparams); List<string> mainParams = ops.Parse(cmdparams);
@ -406,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (mainParams.Count < 6) if (mainParams.Count < 6)
{ {
m_log.Error( m_log.Error(
"[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] <first name> <last name> <inventory path> <user password> [<save file path>]"); "[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>]");
return; return;
} }
@ -423,16 +425,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_log.InfoFormat( m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
savePath, invPath, firstName, lastName); savePath, invPath, firstName, lastName);
lock (m_pendingConsoleSaves)
m_pendingConsoleSaves.Add(id);
ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
} }
catch (InventoryArchiverException e) catch (InventoryArchiverException e)
{ {
m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
} }
lock (m_pendingConsoleSaves)
m_pendingConsoleSaves.Add(id);
} }
private void SaveInvConsoleCommandCompleted( private void SaveInvConsoleCommandCompleted(

View File

@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{ {
@ -104,7 +103,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Scene scene = SceneSetupHelpers.SetupScene(); Scene scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(scene, archiverModule); SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
MemoryStream archiveWriteStream = new MemoryStream(); MemoryStream archiveWriteStream = new MemoryStream();

View File

@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{ {
@ -72,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
TestHelper.InMethod(); TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL1, "password"); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
InventoryItemBase coaItem InventoryItemBase coaItem
@ -124,11 +123,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
} }
/// <summary> /// <summary>
/// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive /// Test saving a single inventory item to an IAR
/// (subject to change since there is no fixed format yet). /// (subject to change since there is no fixed format yet).
/// </summary> /// </summary>
[Test] [Test]
public void TestSaveItemToIarV0_1() public void TestSaveItemToIar()
{ {
TestHelper.InMethod(); TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
@ -138,7 +137,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string userLastName = "Stirrup"; string userLastName = "Stirrup";
string userPassword = "troll"; string userPassword = "troll";
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
UserProfileTestUtils.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
// Create asset // Create asset
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
@ -212,6 +211,106 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
} }
} }
// Assert.That(gotControlFile, Is.True, "No control file in archive");
Assert.That(gotObject1File, Is.True, "No item1 file in archive");
// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
// TODO: Test presence of more files and contents of files.
}
/// <summary>
/// Test saving a single inventory item to an IAR without its asset
/// </summary>
[Test]
public void TestSaveItemToIarNoAssets()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
// Create user
string userFirstName = "Jock";
string userLastName = "Stirrup";
string userPassword = "troll";
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
// Create asset
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
m_scene.AssetService.Store(asset1);
// Create item
UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
string item1Name = "My Little Dog";
InventoryItemBase item1 = new InventoryItemBase();
item1.Name = item1Name;
item1.AssetID = asset1.FullID;
item1.ID = item1Id;
InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0];
item1.Folder = objsFolder.ID;
m_scene.AddInventoryItem(item1);
MemoryStream archiveWriteStream = new MemoryStream();
Dictionary<string, Object> options = new Dictionary<string, Object>();
options.Add("noassets", true);
// When we're not saving assets, archiving is being done synchronously.
m_archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
byte[] archive = archiveWriteStream.ToArray();
MemoryStream archiveReadStream = new MemoryStream(archive);
TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
//bool gotControlFile = false;
bool gotObject1File = false;
//bool gotObject2File = false;
string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1);
string expectedObject1FilePath = string.Format(
"{0}{1}",
ArchiveConstants.INVENTORY_PATH,
expectedObject1FileName);
string filePath;
TarArchiveReader.TarEntryType tarEntryType;
// Console.WriteLine("Reading archive");
while (tar.ReadEntry(out filePath, out tarEntryType) != null)
{
Console.WriteLine("Got {0}", filePath);
// if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
// {
// gotControlFile = true;
// }
if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
{
// string fileName = filePath.Remove(0, "Objects/".Length);
//
// if (fileName.StartsWith(part1.Name))
// {
Assert.That(expectedObject1FilePath, Is.EqualTo(filePath));
gotObject1File = true;
// }
// else if (fileName.StartsWith(part2.Name))
// {
// Assert.That(fileName, Is.EqualTo(expectedObject2FileName));
// gotObject2File = true;
// }
}
else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
{
Assert.Fail("Found asset path in TestSaveItemToIarNoAssets()");
}
}
// Assert.That(gotControlFile, Is.True, "No control file in archive"); // Assert.That(gotControlFile, Is.True, "No control file in archive");
Assert.That(gotObject1File, Is.True, "No item1 file in archive"); Assert.That(gotObject1File, Is.True, "No item1 file in archive");
// Assert.That(gotObject2File, Is.True, "No object2 file in archive"); // Assert.That(gotObject2File, Is.True, "No object2 file in archive");
@ -229,7 +328,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
TestHelper.InMethod(); TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1 InventoryItemBase foundItem1
@ -261,8 +360,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
TestHelper.InMethod(); TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1 InventoryItemBase foundItem1
@ -294,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
TestHelper.InMethod(); TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaMT, "password"); UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
InventoryItemBase foundItem1 InventoryItemBase foundItem1

View File

@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{ {
@ -71,7 +70,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string userLastName = "Stirrup"; string userLastName = "Stirrup";
string userPassword = "troll"; string userPassword = "troll";
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword); UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword);
// Create asset // Create asset
SceneObjectGroup object1; SceneObjectGroup object1;
@ -184,8 +183,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, m_uaMT, "meowfood"); UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
UserProfileTestUtils.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1 InventoryItemBase foundItem1
@ -194,7 +193,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
// Now try loading to a root child folder // Now try loading to a root child folder
UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA"); UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA");
MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray());
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
@ -203,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
// Now try loading to a more deeply nested folder // Now try loading to a more deeply nested folder
UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC"); UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC");
archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
@ -226,7 +225,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Scene scene = SceneSetupHelpers.SetupScene(); Scene scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, m_uaMT, "password"); UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
InventoryItemBase foundItem1 InventoryItemBase foundItem1
@ -255,7 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string userFirstName = "Jock"; string userFirstName = "Jock";
string userLastName = "Stirrup"; string userLastName = "Stirrup";
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "meowfood"); UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "meowfood");
// Create asset // Create asset
SceneObjectGroup object1; SceneObjectGroup object1;
@ -328,7 +327,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene(); Scene scene = SceneSetupHelpers.SetupScene();
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>(); HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>();
@ -395,13 +394,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
//log4net.Config.XmlConfigurator.Configure(); //log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene(); Scene scene = SceneSetupHelpers.SetupScene();
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
string folder1ExistingName = "a"; string folder1ExistingName = "a";
string folder2Name = "b"; string folder2Name = "b";
InventoryFolderBase folder1 InventoryFolderBase folder1
= UserInventoryTestUtils.CreateInventoryFolder( = UserInventoryHelpers.CreateInventoryFolder(
scene.InventoryService, ua1.PrincipalID, folder1ExistingName); scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
@ -446,13 +445,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene(); Scene scene = SceneSetupHelpers.SetupScene();
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
string folder1ExistingName = "a"; string folder1ExistingName = "a";
string folder2Name = "b"; string folder2Name = "b";
InventoryFolderBase folder1 InventoryFolderBase folder1
= UserInventoryTestUtils.CreateInventoryFolder( = UserInventoryHelpers.CreateInventoryFolder(
scene.InventoryService, ua1.PrincipalID, folder1ExistingName); scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());

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 readonly List<Scene> m_scenes = new List<Scene>();
private IMessageTransferModule m_TransferModule = null; private IMessageTransferModule m_TransferModule = null;
private bool m_Enabled = true; private bool m_Enabled = false;
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
if (config.Configs["Messaging"] != null) if (config.Configs["Messaging"] != null)
{ {
if (config.Configs["Messaging"].GetString( if (config.Configs["Messaging"].GetString(
"LureModule", "LureModule") != "LureModule", "LureModule") ==
"LureModule") "LureModule")
m_Enabled = false; {
m_Enabled = true;
m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
}
} }
} }
@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
{ {
if (!m_Enabled)
return;
if (m_TransferModule == null) if (m_TransferModule == null)
{ {
m_TransferModule = m_TransferModule =
@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
if (!m_Enabled)
return;
lock (m_scenes) lock (m_scenes)
{ {
m_scenes.Remove(scene); m_scenes.Remove(scene);

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 bool m_Enabled = false;
protected Scene m_aScene; protected Scene m_aScene;
protected List<Scene> m_Scenes = new List<Scene>();
protected List<UUID> m_agentsInTransit; protected List<UUID> m_agentsInTransit;
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
@ -96,6 +97,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (m_aScene == null) if (m_aScene == null)
m_aScene = scene; m_aScene = scene;
m_Scenes.Add(scene);
scene.RegisterModuleInterface<IEntityTransferModule>(this); scene.RegisterModuleInterface<IEntityTransferModule>(this);
scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnNewClient += OnNewClient;
} }
@ -103,6 +105,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected virtual void OnNewClient(IClientAPI client) protected virtual void OnNewClient(IClientAPI client)
{ {
client.OnTeleportHomeRequest += TeleportHome; client.OnTeleportHomeRequest += TeleportHome;
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
} }
public virtual void Close() public virtual void Close()
@ -118,6 +121,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return; return;
if (scene == m_aScene) if (scene == m_aScene)
m_aScene = null; m_aScene = null;
m_Scenes.Remove(scene);
} }
public virtual void RegionLoaded(Scene scene) public virtual void RegionLoaded(Scene scene)
@ -127,7 +132,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
#endregion #endregion
#region Agent Teleports #region Agent Teleports
@ -248,7 +252,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
} }
protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
{ {
if (reg == null || finalDestination == null) if (reg == null || finalDestination == null)
{ {
@ -556,6 +560,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#endregion #endregion
#region Landmark Teleport
/// <summary>
/// Tries to teleport agent to landmark.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="regionHandle"></param>
/// <param name="position"></param>
public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
{
GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
if (info == null)
{
// can't find the region: Tell viewer and abort
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
return;
}
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
}
#endregion
#region Teleport Home #region Teleport Home
public virtual void TeleportHome(UUID id, IClientAPI client) public virtual void TeleportHome(UUID id, IClientAPI client)

View File

@ -87,6 +87,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected override void OnNewClient(IClientAPI client) protected override void OnNewClient(IClientAPI client)
{ {
client.OnTeleportHomeRequest += TeleportHome; client.OnTeleportHomeRequest += TeleportHome;
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
} }
@ -146,8 +147,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{ {
base.AgentHasMovedAway(sp, logout); base.AgentHasMovedAway(sp, logout);
if (logout) if (logout)
{
// Log them out of this grid // Log them out of this grid
m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
}
} }
protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
@ -228,6 +231,57 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
} }
/// <summary>
/// Tries to teleport agent to landmark.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="regionHandle"></param>
/// <param name="position"></param>
public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
(lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
if (lm.Gatekeeper == string.Empty)
{
base.RequestTeleportLandmark(remoteClient, lm);
return;
}
GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
// Local region?
if (info != null)
{
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
return;
}
else
{
// Foreign region
Scene scene = (Scene)(remoteClient.Scene);
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
GridRegion gatekeeper = new GridRegion();
gatekeeper.ServerURI = lm.Gatekeeper;
GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID));
if (finalDestination != null)
{
ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
if (transferMod != null && sp != null && eq != null)
transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position,
Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq);
}
}
// can't find the region: Tell viewer and abort
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
}
#endregion #endregion
#region IUserAgentVerificationModule #region IUserAgentVerificationModule

View File

@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
private string m_ProfileServerURI; private string m_ProfileServerURI;
private bool m_OutboundPermission; private bool m_OutboundPermission;
private string m_ThisGatekeeper;
// private bool m_Initialized = false; // private bool m_Initialized = false;
@ -85,6 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{ {
m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
} }
else else
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
@ -110,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
{ {
string userAssetServer = string.Empty; string userAssetServer = string.Empty;
if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission) if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
{ {
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); }); Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
} }
@ -119,6 +121,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
#endregion #endregion
#region Overrides of Basic Inventory Access methods #region Overrides of Basic Inventory Access methods
protected override string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
{
UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, presence.UUID);
if (account == null)
prefix = "HG ";
else
prefix = string.Empty;
suffix = " @ " + m_ThisGatekeeper;
Vector3 pos = presence.AbsolutePosition;
return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n",
presence.Scene.RegionInfo.RegionID,
pos.X, pos.Y, pos.Z,
presence.RegionHandle,
m_ThisGatekeeper);
}
/// ///
/// CapsUpdateInventoryItemAsset /// CapsUpdateInventoryItemAsset
/// ///
@ -180,10 +200,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
{ {
string userAssetServer = string.Empty; string userAssetServer = string.Empty;
if (IsForeignUser(sender, out userAssetServer)) if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty)
m_assMapper.Get(item.AssetID, sender, userAssetServer); m_assMapper.Get(item.AssetID, sender, userAssetServer);
if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission) if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
m_assMapper.Post(item.AssetID, receiver, userAssetServer); m_assMapper.Post(item.AssetID, receiver, userAssetServer);
} }
@ -203,9 +223,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
{ {
assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true; assetServerURL = assetServerURL.Trim(new char[] { '/' });
} }
} }
else
{
assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI");
assetServerURL = assetServerURL.Trim(new char[] { '/' });
}
return true;
} }
return false; return false;

View File

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Net; using System.Net;
using System.Xml; using System.Xml;
using System.Reflection; using System.Reflection;
using System.Text;
using System.Threading; using System.Threading;
using OpenSim.Framework; using OpenSim.Framework;
@ -128,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
protected virtual void OnNewClient(IClientAPI client) protected virtual void OnNewClient(IClientAPI client)
{ {
client.OnCreateNewInventoryItem += CreateNewInventoryItem;
} }
public virtual void Close() public virtual void Close()
@ -156,6 +157,87 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
#region Inventory Access #region Inventory Access
/// <summary>
/// Create a new inventory item. Called when the client creates a new item directly within their
/// inventory (e.g. by selecting a context inventory menu option).
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="transactionID"></param>
/// <param name="folderID"></param>
/// <param name="callbackID"></param>
/// <param name="description"></param>
/// <param name="name"></param>
/// <param name="invType"></param>
/// <param name="type"></param>
/// <param name="wearableType"></param>
/// <param name="nextOwnerMask"></param>
public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
uint callbackID, string description, string name, sbyte invType,
sbyte assetType,
byte wearableType, uint nextOwnerMask, int creationDate)
{
m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
return;
InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f);
if (folder == null || folder.Owner != remoteClient.AgentId)
return;
if (transactionID == UUID.Zero)
{
ScenePresence presence;
if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
byte[] data = null;
if (invType == (sbyte)InventoryType.Landmark && presence != null)
{
string suffix = string.Empty, prefix = string.Empty;
string strdata = GenerateLandmark(presence, out prefix, out suffix);
data = Encoding.ASCII.GetBytes(strdata);
name = prefix + name;
description += suffix;
}
AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
m_Scene.AssetService.Store(asset);
m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
}
else
{
m_log.ErrorFormat(
"ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
remoteClient.AgentId);
}
}
else
{
IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>();
if (agentTransactions != null)
{
agentTransactions.HandleItemCreationFromTransaction(
remoteClient, transactionID, folderID, callbackID, description,
name, invType, assetType, wearableType, nextOwnerMask);
}
}
}
protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
{
prefix = string.Empty;
suffix = string.Empty;
Vector3 pos = presence.AbsolutePosition;
return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
presence.Scene.RegionInfo.RegionID,
pos.X, pos.Y, pos.Z,
presence.RegionHandle);
}
/// <summary> /// <summary>
/// Capability originating call to update the asset of an item in an agent's inventory /// Capability originating call to update the asset of an item in an agent's inventory
/// </summary> /// </summary>

View File

@ -45,7 +45,6 @@ using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
{ {
@ -73,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
string userFirstName = "Jock"; string userFirstName = "Jock";
string userLastName = "Stirrup"; string userLastName = "Stirrup";
string userPassword = "troll"; string userPassword = "troll";
UserProfileTestUtils.CreateUserWithInventory(m_scene, userFirstName, userLastName, m_userId, userPassword); UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, m_userId, userPassword);
AgentCircuitData acd = new AgentCircuitData(); AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = m_userId; acd.AgentID = m_userId;

View File

@ -30,11 +30,13 @@ using System.IO;
using System.Reflection; using System.Reflection;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework; using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using OpenMetaverse; using OpenMetaverse;
using log4net; using log4net;
@ -47,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public UUID Id; public UUID Id;
public string FirstName; public string FirstName;
public string LastName; public string LastName;
public string ProfileURL; public string HomeURL;
public Dictionary<string, object> ServerURLs;
} }
public class UserManagementModule : ISharedRegionModule, IUserManagement public class UserManagementModule : ISharedRegionModule, IUserManagement
@ -78,6 +81,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
// } // }
// } // }
//} //}
MainConsole.Instance.Commands.AddCommand("grid", true,
"show names",
"show names",
"Show the bindings between user UUIDs and user names",
String.Empty,
HandleShowUsers);
} }
public bool IsSharedModule public bool IsSharedModule
@ -101,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
scene.RegisterModuleInterface<IUserManagement>(this); scene.RegisterModuleInterface<IUserManagement>(this);
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -109,18 +121,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
m_Scenes.Remove(scene); m_Scenes.Remove(scene);
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene s)
{ {
} }
public void PostInitialise() public void PostInitialise()
{ {
foreach (Scene s in m_Scenes)
{
// let's sniff all the user names referenced by objects in the scene
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
}
} }
public void Close() public void Close()
@ -134,6 +140,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#region Event Handlers #region Event Handlers
void EventManager_OnPrimsLoaded(Scene s)
{
// let's sniff all the user names referenced by objects in the scene
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
}
void EventManager_OnNewClient(IClientAPI client) void EventManager_OnNewClient(IClientAPI client)
{ {
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
@ -150,6 +164,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
string[] names = GetUserNames(uuid); string[] names = GetUserNames(uuid);
if (names.Length == 2) if (names.Length == 2)
{ {
//m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]);
remote_client.SendNameReply(uuid, names[0], names[1]); remote_client.SendNameReply(uuid, names[0], names[1]);
} }
@ -210,6 +225,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public string GetUserName(UUID uuid) public string GetUserName(UUID uuid)
{ {
//m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
string[] names = GetUserNames(uuid); string[] names = GetUserNames(uuid);
if (names.Length == 2) if (names.Length == 2)
{ {
@ -222,6 +238,60 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return "(hippos)"; return "(hippos)";
} }
public string GetUserHomeURL(UUID userID)
{
if (m_UserCache.ContainsKey(userID))
return m_UserCache[userID].HomeURL;
return string.Empty;
}
public string GetUserServerURL(UUID userID, string serverType)
{
if (m_UserCache.ContainsKey(userID))
{
UserData userdata = m_UserCache[userID];
if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
return userdata.ServerURLs[serverType].ToString();
if (userdata.HomeURL != string.Empty)
{
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
userdata.ServerURLs = uConn.GetServerURLs(userID);
if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
return userdata.ServerURLs[serverType].ToString();
}
}
return string.Empty;
}
public string GetUserUUI(UUID userID)
{
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
if (account != null)
return userID.ToString();
if (m_UserCache.ContainsKey(userID))
{
UserData ud = m_UserCache[userID];
string homeURL = ud.HomeURL;
string first = ud.FirstName, last = ud.LastName;
if (ud.LastName.StartsWith("@"))
{
string[] parts = ud.FirstName.Split('.');
if (parts.Length >= 2)
{
first = parts[0];
last = parts[1];
}
return userID + ";" + homeURL + ";" + first + " " + last;
}
}
return userID.ToString();
}
public void AddUser(UUID id, string creatorData) public void AddUser(UUID id, string creatorData)
{ {
if (m_UserCache.ContainsKey(id)) if (m_UserCache.ContainsKey(id))
@ -247,13 +317,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
string[] parts = creatorData.Split(';'); string[] parts = creatorData.Split(';');
if (parts.Length >= 1) if (parts.Length >= 1)
{ {
user.ProfileURL = parts[0]; user.HomeURL = parts[0];
try try
{ {
Uri uri = new Uri(parts[0]); Uri uri = new Uri(parts[0]);
user.LastName = "@" + uri.Authority; user.LastName = "@" + uri.Authority;
} }
catch catch (UriFormatException)
{ {
m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
user.LastName = "@unknown"; user.LastName = "@unknown";
@ -272,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
lock (m_UserCache) lock (m_UserCache)
m_UserCache[id] = user; m_UserCache[id] = user;
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL); m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL);
} }
public void AddUser(UUID uuid, string first, string last, string profileURL) public void AddUser(UUID uuid, string first, string last, string profileURL)
@ -311,5 +381,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
//} //}
#endregion IUserManagement #endregion IUserManagement
private void HandleShowUsers(string module, string[] cmd)
{
if (m_UserCache.Count == 0)
{
MainConsole.Instance.Output("No users not found");
return;
}
MainConsole.Instance.Output("UUID User Name");
MainConsole.Instance.Output("-----------------------------------------------------------------------------");
foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
{
MainConsole.Instance.Output(String.Format("{0} {1} {2}",
kvp.Key, kvp.Value.FirstName, kvp.Value.LastName));
}
return;
}
} }
} }

View File

@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using log4net; using log4net;
@ -40,7 +41,10 @@ namespace OpenSim.Region.CoreModules.Hypergrid
{ {
public class HGWorldMapModule : WorldMapModule public class HGWorldMapModule : WorldMapModule
{ {
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// Remember the map area that each client has been exposed to in this region
private Dictionary<UUID, List<MapBlockData>> m_SeenMapBlocks = new Dictionary<UUID, List<MapBlockData>>();
#region INonSharedRegionModule Members #region INonSharedRegionModule Members
@ -51,6 +55,13 @@ namespace OpenSim.Region.CoreModules.Hypergrid
m_Enabled = true; m_Enabled = true;
} }
public override void AddRegion(Scene scene)
{
base.AddRegion(scene);
scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed);
}
public override string Name public override string Name
{ {
get { return "HGWorldMap"; } get { return "HGWorldMap"; }
@ -58,47 +69,70 @@ namespace OpenSim.Region.CoreModules.Hypergrid
#endregion #endregion
protected override void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) void EventManager_OnClientClosed(UUID clientID, Scene scene)
{ {
List<MapBlockData> mapBlocks = new List<MapBlockData>(); ScenePresence sp = scene.GetScenePresence(clientID);
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, if (sp != null)
minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize,
minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize);
foreach (GridRegion r in regions)
{ {
MapBlockData block = new MapBlockData(); if (m_SeenMapBlocks.ContainsKey(clientID))
MapBlockFromGridRegion(block, r);
mapBlocks.Add(block);
}
// Different from super
FillInMap(mapBlocks, minX, minY, maxX, maxY);
//
remoteClient.SendMapBlock(mapBlocks, 0);
}
private void FillInMap(List<MapBlockData> mapBlocks, int minX, int minY, int maxX, int maxY)
{
for (int x = minX; x <= maxX; x++)
{
for (int y = minY; y <= maxY; y++)
{ {
MapBlockData mblock = mapBlocks.Find(delegate(MapBlockData mb) { return ((mb.X == x) && (mb.Y == y)); }); List<MapBlockData> mapBlocks = m_SeenMapBlocks[clientID];
if (mblock == null) foreach (MapBlockData b in mapBlocks)
{ {
mblock = new MapBlockData(); b.Name = string.Empty;
mblock.X = (ushort)x; b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's
mblock.Y = (ushort)y;
mblock.Name = "";
mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's
mblock.MapImageId = UUID.Zero;
mapBlocks.Add(mblock);
} }
m_log.DebugFormat("[HG MAP]: Reseting {0} blocks", mapBlocks.Count);
sp.ControllingClient.SendMapBlock(mapBlocks, 0);
m_SeenMapBlocks.Remove(clientID);
} }
} }
} }
protected override List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
{
List<MapBlockData> mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag);
lock (m_SeenMapBlocks)
{
if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId))
{
m_SeenMapBlocks.Add(remoteClient.AgentId, mapBlocks);
}
else
{
List<MapBlockData> seen = m_SeenMapBlocks[remoteClient.AgentId];
List<MapBlockData> newBlocks = new List<MapBlockData>();
foreach (MapBlockData b in mapBlocks)
if (seen.Find(delegate(MapBlockData bdata) { return bdata.X == b.X && bdata.Y == b.Y; }) == null)
newBlocks.Add(b);
seen.AddRange(newBlocks);
}
}
return mapBlocks;
}
}
class MapArea
{
public int minX;
public int minY;
public int maxX;
public int maxY;
public MapArea(int mix, int miy, int max, int may)
{
minX = mix;
minY = miy;
maxX = max;
maxY = may;
}
public void Print()
{
Console.WriteLine(String.Format(" --> Area is minX={0} minY={1} minY={2} maxY={3}", minX, minY, maxY, maxY));
}
} }
} }

View File

@ -615,13 +615,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_log.Debug("[REGION SYNC AVATAR] AttachObject"); m_log.Debug("[REGION SYNC AVATAR] AttachObject");
} }
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)
{ {
IGridDialogModule gridDialogModule = m_scene.RequestModuleInterface<IGridDialogModule>(); IGridDialogModule gridDialogModule = m_scene.RequestModuleInterface<IGridDialogModule>();
if (gridDialogModule != null) if (gridDialogModule != null)
{ {
gridDialogModule.SendGridDialogViaXMLRPC(this.AgentId, objectname, objectID, ownerFirstName, ownerLastName, gridDialogModule.SendGridDialogViaXMLRPC(this.AgentId, objectname, objectID, ownerID, ownerFirstName, ownerLastName,
msg, textureID, ch, buttonlabels, UUID.Zero); msg, textureID, ch, buttonlabels, UUID.Zero);
} }
} }

View File

@ -126,7 +126,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
#region GridCommunication #region GridCommunication
public delegate void GridDialogDelegate(UUID avatarID, string objectName, UUID objectID, string ownerFirstName, public delegate void GridDialogDelegate(UUID avatarID, string objectName, UUID objectID, UUID ownerID, string ownerFirstName,
string ownerLastName, string message, UUID textureID, int ch, string[] buttonlabels, UUID prevRegionID); string ownerLastName, string message, UUID textureID, int ch, string[] buttonlabels, UUID prevRegionID);
protected virtual void GridDialogCompleted(IAsyncResult iar) protected virtual void GridDialogCompleted(IAsyncResult iar)
@ -136,17 +136,17 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
icon.EndInvoke(iar); icon.EndInvoke(iar);
} }
public void SendGridDialogViaXMLRPC(UUID avatarID, string objectName, UUID objectID, string ownerFirstName, public void SendGridDialogViaXMLRPC(UUID avatarID, string objectName, UUID objectID, UUID ownerID, string ownerFirstName,
string ownerLastName, string message, UUID textureID, int ch, string[] buttonlabels, UUID prevRegionID) string ownerLastName, string message, UUID textureID, int ch, string[] buttonlabels, UUID prevRegionID)
{ {
GridDialogDelegate d = SendGridDialogViaXMLRPCAsync; GridDialogDelegate d = SendGridDialogViaXMLRPCAsync;
d.BeginInvoke(avatarID, objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels, prevRegionID, d.BeginInvoke(avatarID, objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels, prevRegionID,
GridDialogCompleted, d); GridDialogCompleted, d);
} }
private void SendGridDialogViaXMLRPCAsync(UUID avatarID, string objectName, UUID objectID, string ownerFirstName, private void SendGridDialogViaXMLRPCAsync(UUID avatarID, string objectName, UUID objectID, UUID ownerID, string ownerFirstName,
string ownerLastName, string message, UUID textureID, int ch, string[] buttonlabels, UUID prevRegionID) string ownerLastName, string message, UUID textureID, int ch, string[] buttonlabels, UUID prevRegionID)
{ {
PresenceInfo upd = null; PresenceInfo upd = null;
@ -190,7 +190,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
upd.RegionID); upd.RegionID);
if (reginfo != null) if (reginfo != null)
{ {
Hashtable msgdata = ConvertGridDialogToXMLRPC(avatarID, objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); Hashtable msgdata = ConvertGridDialogToXMLRPC(avatarID, objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
//= ConvertGridInstantMessageToXMLRPC(im); //= ConvertGridInstantMessageToXMLRPC(im);
// Not actually used anymore, left in for compatibility // Not actually used anymore, left in for compatibility
// Remove at next interface change // Remove at next interface change
@ -200,7 +200,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
bool imresult = doDialogSending(reginfo, msgdata); bool imresult = doDialogSending(reginfo, msgdata);
if (!imresult) if (!imresult)
{ {
//SendGridDialogViaXMLRPCAsync(avatarID, objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels, prevRegionID); SendGridDialogViaXMLRPCAsync(avatarID, objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels, prevRegionID);
m_log.WarnFormat("Couldn't deliver dialog to {0}" + avatarID); m_log.WarnFormat("Couldn't deliver dialog to {0}" + avatarID);
return; return;
} }
@ -208,13 +208,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
} }
private Hashtable ConvertGridDialogToXMLRPC(UUID avatarID, string objectName, UUID objectID, string ownerFirstName, string ownerLastName, private Hashtable ConvertGridDialogToXMLRPC(UUID avatarID, string objectName, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName,
string message, UUID textureID, int ch, string[] buttonlabels) string message, UUID textureID, int ch, string[] buttonlabels)
{ {
Hashtable msgdata = new Hashtable(); Hashtable msgdata = new Hashtable();
msgdata["avatarID"] = avatarID.ToString(); msgdata["avatarID"] = avatarID.ToString();
msgdata["objectName"] = objectName; msgdata["objectName"] = objectName;
msgdata["objectID"] = objectID.ToString(); msgdata["objectID"] = objectID.ToString();
msgdata["ownerID"] = ownerID.ToString();
msgdata["ownerFirstName"] = ownerFirstName; msgdata["ownerFirstName"] = ownerFirstName;
msgdata["ownerLastName"] = ownerLastName; msgdata["ownerLastName"] = ownerLastName;
msgdata["message"] = message; msgdata["message"] = message;
@ -287,6 +288,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
UUID avatarID = UUID.Zero; UUID avatarID = UUID.Zero;
UUID objectID = UUID.Zero; UUID objectID = UUID.Zero;
UUID textureID = UUID.Zero; UUID textureID = UUID.Zero;
UUID ownerID = UUID.Zero;
string objectName="", ownerFirstName="", ownerLastName=""; string objectName="", ownerFirstName="", ownerLastName="";
string message=""; string message="";
int ch=0; int ch=0;
@ -297,6 +299,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
// Check if it's got all the data // Check if it's got all the data
if (requestData.ContainsKey("avatarID") if (requestData.ContainsKey("avatarID")
&& requestData.ContainsKey("objectName") && requestData.ContainsKey("objectID") && requestData.ContainsKey("objectName") && requestData.ContainsKey("objectID")
&& requestData.ContainsKey("ownerID")
&& requestData.ContainsKey("ownerFirstName") && requestData.ContainsKey("ownerLastName") && requestData.ContainsKey("ownerFirstName") && requestData.ContainsKey("ownerLastName")
&& requestData.ContainsKey("message") && requestData.ContainsKey("textureID") && requestData.ContainsKey("message") && requestData.ContainsKey("textureID")
&& requestData.ContainsKey("ch") && requestData.ContainsKey("ch")
@ -308,6 +311,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
UUID.TryParse((string)requestData["avatarID"], out avatarID); UUID.TryParse((string)requestData["avatarID"], out avatarID);
UUID.TryParse((string)requestData["objectID"], out objectID); UUID.TryParse((string)requestData["objectID"], out objectID);
UUID.TryParse((string)requestData["textureID"], out textureID); UUID.TryParse((string)requestData["textureID"], out textureID);
UUID.TryParse((string)requestData["ownerID"], out ownerID);
objectName = (string)requestData["objectName"]; objectName = (string)requestData["objectName"];
ownerFirstName = (string)requestData["ownerFirstName"]; ownerFirstName = (string)requestData["ownerFirstName"];
@ -351,7 +355,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
if (!user.IsChildAgent) if (!user.IsChildAgent)
{ {
user.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); user.ControllingClient.SendDialog(objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
deliverSuccessful = true; deliverSuccessful = true;
} }
} }

View File

@ -4425,8 +4425,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
XmlTextReader reader = new XmlTextReader(sr); XmlTextReader reader = new XmlTextReader(sr);
PrimitiveBaseShape shapeValue; PrimitiveBaseShape shapeValue;
try try
{ {
shapeValue = SceneObjectSerializer.ReadShape(reader, "Shape"); bool errors = false;
shapeValue = SceneObjectSerializer.ReadShape(reader, "Shape", out errors);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -24,6 +24,7 @@
<RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" /> <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
<RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" /> <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
<RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" /> <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" />
<RegionModule id="HGFriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.HGFriendsModule" />
<RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" /> <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" />
<RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" /> <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
<RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" /> <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" />

View File

@ -113,8 +113,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
new UserAgentServerConnector(m_Config, MainServer.Instance); IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
} }
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper); scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
} }

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using System.Collections.Generic;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Server.Base;
using OpenSim.Server.Handlers.Base;
using OpenSim.Server.Handlers.MapImage;
using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class MapImageServiceInConnectorModule : ISharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static bool m_Enabled = false;
private IConfigSource m_Config;
bool m_Registered = false;
#region IRegionModule interface
public void Initialise(IConfigSource config)
{
m_Config = config;
IConfig moduleConfig = config.Configs["Modules"];
if (moduleConfig != null)
{
m_Enabled = moduleConfig.GetBoolean("MapImageServiceInConnector", false);
if (m_Enabled)
{
m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled");
new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService");
}
}
}
public void PostInitialise()
{
}
public void Close()
{
}
public Type ReplaceableInterface
{
get { return null; }
}
public string Name
{
get { return "MapImageServiceIn"; }
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
}
#endregion
}
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using System.Collections.Generic;
using OpenSim.Framework;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using log4net;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{
public class RegionInfoCache
{
private const double CACHE_EXPIRATION_SECONDS = 300.0; // 5 minutes
// private static readonly ILog m_log =
// LogManager.GetLogger(
// MethodBase.GetCurrentMethod().DeclaringType);
internal struct ScopedRegionUUID
{
public UUID m_scopeID;
public UUID m_regionID;
public ScopedRegionUUID(UUID scopeID, UUID regionID)
{
m_scopeID = scopeID;
m_regionID = regionID;
}
}
internal struct ScopedRegionName
{
public UUID m_scopeID;
public string m_name;
public ScopedRegionName(UUID scopeID, string name)
{
m_scopeID = scopeID;
m_name = name;
}
}
private ExpiringCache<ScopedRegionUUID, GridRegion> m_UUIDCache;
private ExpiringCache<ScopedRegionName, ScopedRegionUUID> m_NameCache;
public RegionInfoCache()
{
m_UUIDCache = new ExpiringCache<ScopedRegionUUID, GridRegion>();
m_NameCache = new ExpiringCache<ScopedRegionName, ScopedRegionUUID>();
}
public void Cache(GridRegion rinfo)
{
if (rinfo != null)
this.Cache(rinfo.ScopeID,rinfo.RegionID,rinfo);
}
public void Cache(UUID scopeID, UUID regionID, GridRegion rinfo)
{
// for now, do not cache negative results; this is because
// we need to figure out how to handle regions coming online
// in a timely way
if (rinfo == null)
return;
ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID);
// Cache even null accounts
m_UUIDCache.AddOrUpdate(id, rinfo, CACHE_EXPIRATION_SECONDS);
if (rinfo != null)
{
ScopedRegionName name = new ScopedRegionName(scopeID,rinfo.RegionName);
m_NameCache.AddOrUpdate(name, id, CACHE_EXPIRATION_SECONDS);
}
}
public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache)
{
inCache = false;
GridRegion rinfo = null;
ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID);
if (m_UUIDCache.TryGetValue(id, out rinfo))
{
inCache = true;
return rinfo;
}
return null;
}
public GridRegion Get(UUID scopeID, string name, out bool inCache)
{
inCache = false;
ScopedRegionName sname = new ScopedRegionName(scopeID,name);
ScopedRegionUUID id;
if (m_NameCache.TryGetValue(sname, out id))
{
GridRegion rinfo = null;
if (m_UUIDCache.TryGetValue(id, out rinfo))
{
inCache = true;
return rinfo;
}
}
return null;
}
}
}

View File

@ -53,6 +53,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
private IGridService m_LocalGridService; private IGridService m_LocalGridService;
private IGridService m_RemoteGridService; private IGridService m_RemoteGridService;
private RegionInfoCache m_RegionInfoCache = new RegionInfoCache();
public RemoteGridServicesConnector() public RemoteGridServicesConnector()
{ {
} }
@ -169,10 +171,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
{ {
GridRegion rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID); bool inCache = false;
GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache);
if (inCache)
return rinfo;
rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID);
if (rinfo == null) if (rinfo == null)
rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID); rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID);
m_RegionInfoCache.Cache(scopeID,regionID,rinfo);
return rinfo; return rinfo;
} }
@ -187,10 +195,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public GridRegion GetRegionByName(UUID scopeID, string regionName) public GridRegion GetRegionByName(UUID scopeID, string regionName)
{ {
GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName); bool inCache = false;
GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionName, out inCache);
if (inCache)
return rinfo;
rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName);
if (rinfo == null) if (rinfo == null)
rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName); rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName);
// can't cache negative results for name lookups
m_RegionInfoCache.Cache(rinfo);
return rinfo; return rinfo;
} }
@ -204,8 +219,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{ {
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionsByName {0} found {1} regions", name, grinfo.Count); //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionsByName {0} found {1} regions", name, grinfo.Count);
foreach (GridRegion r in grinfo) foreach (GridRegion r in grinfo)
{
m_RegionInfoCache.Cache(r);
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
rinfo.Add(r); rinfo.Add(r);
}
} }
return rinfo; return rinfo;
@ -221,8 +239,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{ {
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionRange {0} found {1} regions", name, grinfo.Count); //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionRange {0} found {1} regions", name, grinfo.Count);
foreach (GridRegion r in grinfo) foreach (GridRegion r in grinfo)
{
m_RegionInfoCache.Cache(r);
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
rinfo.Add(r); rinfo.Add(r);
}
} }
return rinfo; return rinfo;
@ -238,8 +259,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{ {
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultRegions {0} found {1} regions", name, grinfo.Count); //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultRegions {0} found {1} regions", name, grinfo.Count);
foreach (GridRegion r in grinfo) foreach (GridRegion r in grinfo)
{
m_RegionInfoCache.Cache(r);
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
rinfo.Add(r); rinfo.Add(r);
}
} }
return rinfo; return rinfo;
@ -255,8 +279,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{ {
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetFallbackRegions {0} found {1} regions", name, grinfo.Count); //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetFallbackRegions {0} found {1} regions", name, grinfo.Count);
foreach (GridRegion r in grinfo) foreach (GridRegion r in grinfo)
{
m_RegionInfoCache.Cache(r);
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
rinfo.Add(r); rinfo.Add(r);
}
} }
return rinfo; return rinfo;
@ -272,8 +299,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{ {
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetHyperlinks {0} found {1} regions", name, grinfo.Count); //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetHyperlinks {0} found {1} regions", name, grinfo.Count);
foreach (GridRegion r in grinfo) foreach (GridRegion r in grinfo)
{
m_RegionInfoCache.Cache(r);
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
rinfo.Add(r); rinfo.Add(r);
}
} }
return rinfo; return rinfo;

View File

@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using GridRegion = OpenSim.Services.Interfaces.GridRegion; using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
{ {

View File

@ -58,6 +58,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
private List<Scene> m_Scenes = new List<Scene>(); private List<Scene> m_Scenes = new List<Scene>();
protected IUserManagement m_UserManagement;
protected IUserManagement UserManagementModule
{
get
{
if (m_UserManagement == null)
m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>();
return m_UserManagement;
}
}
public Type ReplaceableInterface public Type ReplaceableInterface
{ {
get { return null; } get { return null; }
@ -207,6 +218,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
} }
} }
} }
if (sp == null)
{
inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI");
if (inventoryURL != null && inventoryURL != string.Empty)
{
inventoryURL = inventoryURL.Trim(new char[] { '/' });
m_InventoryURLs.Add(userID, inventoryURL);
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
}
}
} }
} }

View File

@ -0,0 +1,232 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Net;
using System.IO;
using System.Timers;
using System.Drawing;
using System.Drawing.Imaging;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Server.Base;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
{
/// <summary>
/// </summary>
/// <remarks>
/// </remarks>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class MapImageServiceModule : ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private bool m_enabled = false;
private IMapImageService m_MapService;
private string m_serverUrl = String.Empty;
private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
private int m_refreshtime = 0;
private int m_lastrefresh = 0;
private System.Timers.Timer m_refreshTimer = new System.Timers.Timer();
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public string Name { get { return "MapImageServiceModule"; } }
public void RegionLoaded(Scene scene) { }
public void Close() { }
public void PostInitialise() { }
///<summary>
///
///</summary>
public void Initialise(IConfigSource source)
{
IConfig moduleConfig = source.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("MapImageService", "");
if (name != Name)
return;
}
IConfig config = source.Configs["MapImageService"];
if (config == null)
return;
int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime"));
if (refreshminutes <= 0)
{
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled.");
return;
}
m_refreshtime = refreshminutes * 60 * 1000; // convert from minutes to ms
string service = config.GetString("LocalServiceModule", string.Empty);
if (service == string.Empty)
{
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No service dll given in config. Unable to proceed.");
return;
}
Object[] args = new Object[] { source };
m_MapService = ServerUtils.LoadPlugin<IMapImageService>(service, args);
m_refreshTimer.Enabled = true;
m_refreshTimer.AutoReset = true;
m_refreshTimer.Interval = m_refreshtime;
m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}",
refreshminutes, service);
m_enabled = true;
}
///<summary>
///
///</summary>
///<summary>
///
///</summary>
public void AddRegion(Scene scene)
{
if (! m_enabled)
return;
// Every shared region module has to maintain an indepedent list of
// currently running regions
lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene;
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
}
///<summary>
///
///</summary>
public void RemoveRegion(Scene scene)
{
if (! m_enabled)
return;
lock (m_scenes)
m_scenes.Remove(scene.RegionInfo.RegionID);
}
#endregion ISharedRegionModule
void EventManager_OnPrimsLoaded(Scene s)
{
UploadMapTile(s);
}
///<summary>
///
///</summary>
private void HandleMaptileRefresh(object sender, EventArgs ea)
{
// this approach is a bit convoluted becase we want to wait for the
// first upload to happen on startup but after all the objects are
// loaded and initialized
if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime)
return;
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: map refresh!");
lock (m_scenes)
{
foreach (IScene scene in m_scenes.Values)
{
try
{
UploadMapTile(scene);
}
catch (Exception ex)
{
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: something bad happened {0}", ex.Message);
}
}
}
m_lastrefresh = Util.EnvironmentTickCount();
}
///<summary>
///
///</summary>
private void UploadMapTile(IScene scene)
{
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: upload maptile for {0}", scene.RegionInfo.RegionName);
// Create a PNG map tile and upload it to the AddMapTile API
byte[] jpgData = Utils.EmptyBytes;
IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>();
if (tileGenerator == null)
{
m_log.Warn("[MAP IMAGE SERVICE MODULE]: Cannot upload PNG map tile without an ImageGenerator");
return;
}
using (Image mapTile = tileGenerator.CreateMapTile())
{
using (MemoryStream stream = new MemoryStream())
{
mapTile.Save(stream, ImageFormat.Jpeg);
jpgData = stream.ToArray();
}
}
string reason = string.Empty;
if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason))
{
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}",
scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason);
}
}
}
}

View File

@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests
{ {

View File

@ -347,12 +347,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
landData.Add(parcel); landData.Add(parcel);
} }
if (!m_merge) if (!m_merge)
m_scene.LandChannel.Clear(false); {
bool setupDefaultParcel = (landData.Count == 0);
m_scene.LandChannel.Clear(setupDefaultParcel);
}
m_scene.EventManager.TriggerIncomingLandDataFromStorage(landData); m_scene.EventManager.TriggerIncomingLandDataFromStorage(landData);
m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count);
} }
/// <summary> /// <summary>
@ -485,6 +488,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
currentRegionSettings.Elevation2SE = loadedRegionSettings.Elevation2SE; currentRegionSettings.Elevation2SE = loadedRegionSettings.Elevation2SE;
currentRegionSettings.Elevation2SW = loadedRegionSettings.Elevation2SW; currentRegionSettings.Elevation2SW = loadedRegionSettings.Elevation2SW;
currentRegionSettings.FixedSun = loadedRegionSettings.FixedSun; currentRegionSettings.FixedSun = loadedRegionSettings.FixedSun;
currentRegionSettings.SunPosition = loadedRegionSettings.SunPosition;
currentRegionSettings.ObjectBonus = loadedRegionSettings.ObjectBonus; currentRegionSettings.ObjectBonus = loadedRegionSettings.ObjectBonus;
currentRegionSettings.RestrictPushing = loadedRegionSettings.RestrictPushing; currentRegionSettings.RestrictPushing = loadedRegionSettings.RestrictPushing;
currentRegionSettings.TerrainLowerLimit = loadedRegionSettings.TerrainLowerLimit; currentRegionSettings.TerrainLowerLimit = loadedRegionSettings.TerrainLowerLimit;
@ -497,6 +501,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight;
currentRegionSettings.Save(); currentRegionSettings.Save();
m_scene.TriggerEstateSunUpdate();
IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();

View File

@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
public class ArchiveWriteRequestPreparation public class ArchiveWriteRequestPreparation
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary> /// <summary>
/// The minimum major version of OAR that we can write. /// The minimum major version of OAR that we can write.
/// </summary> /// </summary>
@ -58,7 +58,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// <summary> /// <summary>
/// The maximum major version of OAR that we can write. /// The maximum major version of OAR that we can write.
/// </summary> /// </summary>
public static int MAX_MAJOR_VERSION = 0; public static int MAX_MAJOR_VERSION = 0;
/// <summary>
/// Determine whether this archive will save assets. Default is true.
/// </summary>
public bool SaveAssets { get; set; }
protected Scene m_scene; protected Scene m_scene;
protected Stream m_saveStream; protected Stream m_saveStream;
@ -73,10 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// <exception cref="System.IO.IOException"> /// <exception cref="System.IO.IOException">
/// If there was a problem opening a stream for the file specified by the savePath /// If there was a problem opening a stream for the file specified by the savePath
/// </exception> /// </exception>
public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId)
{ {
m_scene = scene;
try try
{ {
m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress); m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress);
@ -86,10 +89,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_log.ErrorFormat( m_log.ErrorFormat(
"[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream." "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
+ "If you've manually installed Mono, have you appropriately updated zlib1g as well?"); + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
m_log.Error(e); m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
} }
m_requestId = requestId;
} }
/// <summary> /// <summary>
@ -98,11 +99,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// <param name="scene"></param> /// <param name="scene"></param>
/// <param name="saveStream">The stream to which to save data.</param> /// <param name="saveStream">The stream to which to save data.</param>
/// <param name="requestId">The id associated with this request</param> /// <param name="requestId">The id associated with this request</param>
public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId)
{
m_saveStream = saveStream;
}
protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId)
{ {
m_scene = scene; m_scene = scene;
m_saveStream = saveStream;
m_requestId = requestId; m_requestId = requestId;
SaveAssets = true;
} }
/// <summary> /// <summary>
@ -111,22 +118,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
public void ArchiveRegion(Dictionary<string, object> options) public void ArchiveRegion(Dictionary<string, object> options)
{ {
if (options.ContainsKey("noassets") && (bool)options["noassets"])
SaveAssets = false;
try try
{ {
Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
EntityBase[] entities = m_scene.GetEntities(); EntityBase[] entities = m_scene.GetEntities();
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
/*
foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
{
if (name == lo.LandData.Name)
{
// This is the parcel we want
}
}
*/
// Filter entities so that we only have scene objects. // Filter entities so that we only have scene objects.
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
@ -141,17 +141,24 @@ namespace OpenSim.Region.CoreModules.World.Archiver
sceneObjects.Add((SceneObjectGroup)entity); sceneObjects.Add((SceneObjectGroup)entity);
} }
} }
UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); if (SaveAssets)
foreach (SceneObjectGroup sceneObject in sceneObjects)
{ {
assetGatherer.GatherAssetUuids(sceneObject, assetUuids); UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
foreach (SceneObjectGroup sceneObject in sceneObjects)
{
assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
}
m_log.DebugFormat(
"[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
sceneObjects.Count, assetUuids.Count);
}
else
{
m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
} }
m_log.DebugFormat(
"[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
sceneObjects.Count, assetUuids.Count);
// Make sure that we also request terrain texture assets // Make sure that we also request terrain texture assets
RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
@ -187,11 +194,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
new AssetsRequest( if (SaveAssets)
new AssetsArchiver(archiveWriter), assetUuids, new AssetsRequest(
m_scene.AssetService, m_scene.UserAccountService, new AssetsArchiver(archiveWriter), assetUuids,
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute(); m_scene.AssetService, m_scene.UserAccountService,
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
else
awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
} }
catch (Exception) catch (Exception)
{ {
@ -204,9 +214,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// Create the control file for the most up to date archive /// Create the control file for the most up to date archive
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static string CreateControlFile(Dictionary<string, object> options) public string CreateControlFile(Dictionary<string, object> options)
{ {
int majorVersion = MAX_MAJOR_VERSION, minorVersion = 6; int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7;
// //
// if (options.ContainsKey("version")) // if (options.ContainsKey("version"))
// { // {
@ -258,6 +268,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
xtw.WriteElementString("id", UUID.Random().ToString()); xtw.WriteElementString("id", UUID.Random().ToString());
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.WriteElementString("assets_included", SaveAssets.ToString());
xtw.WriteEndElement(); xtw.WriteEndElement();
xtw.Flush(); xtw.Flush();

View File

@ -127,6 +127,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
OptionSet ops = new OptionSet(); OptionSet ops = new OptionSet();
// ops.Add("v|version=", delegate(string v) { options["version"] = v; }); // ops.Add("v|version=", delegate(string v) { options["version"] = v; });
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
List<string> mainParams = ops.Parse(cmdparams); List<string> mainParams = ops.Parse(cmdparams);
@ -160,7 +161,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
public void ArchiveRegion(Stream saveStream, Guid requestId) public void ArchiveRegion(Stream saveStream, Guid requestId)
{ {
new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(new Dictionary<string, object>()); ArchiveRegion(saveStream, requestId, new Dictionary<string, object>());
}
public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options)
{
new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options);
} }
public void DearchiveRegion(string loadPath) public void DearchiveRegion(string loadPath)

View File

@ -198,11 +198,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_log.ErrorFormat( m_log.ErrorFormat(
"[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT); "[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT);
m_log.Error("[ARCHIVER]: OAR save aborted. PLEASE DO NOT USE THIS OAR, IT WILL BE INCOMPLETE."); m_log.Error("[ARCHIVER]: Archive save aborted. PLEASE DO NOT USE THIS ARCHIVE, IT WILL BE INCOMPLETE.");
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}", e); m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}{1}", e.Message, e.StackTrace);
} }
finally finally
{ {
@ -230,6 +230,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// <param name="asset"></param> /// <param name="asset"></param>
public void AssetRequestCallback(string id, object sender, AssetBase asset) public void AssetRequestCallback(string id, object sender, AssetBase asset)
{ {
Culture.SetCurrentCulture();
try try
{ {
lock (this) lock (this)
@ -293,6 +295,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// </summary> /// </summary>
protected void PerformAssetsRequestCallback(object o) protected void PerformAssetsRequestCallback(object o)
{ {
Culture.SetCurrentCulture();
try try
{ {
m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);

View File

@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants;
using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader;
using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter;
@ -212,6 +211,89 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// TODO: Test presence of more files and contents of files. // TODO: Test presence of more files and contents of files.
} }
/// <summary>
/// Test saving an OpenSim Region Archive with the no assets option
/// </summary>
[Test]
public void TestSaveOarNoAssets()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
SceneObjectPart part1 = CreateSceneObjectPart1();
SceneObjectGroup sog1 = new SceneObjectGroup(part1);
m_scene.AddNewSceneObject(sog1, false);
SceneObjectPart part2 = CreateSceneObjectPart2();
AssetNotecard nc = new AssetNotecard();
nc.BodyText = "Hello World!";
nc.Encode();
UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
AssetBase ncAsset
= AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
m_scene.AssetService.Store(ncAsset);
SceneObjectGroup sog2 = new SceneObjectGroup(part2);
TaskInventoryItem ncItem
= new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
part2.Inventory.AddInventoryItem(ncItem, true);
m_scene.AddNewSceneObject(sog2, false);
MemoryStream archiveWriteStream = new MemoryStream();
Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
Dictionary<string, Object> options = new Dictionary<string, Object>();
options.Add("noassets", true);
m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
//AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
//while (assetServer.HasWaitingRequests())
// assetServer.ProcessNextRequest();
// Don't wait for completion - with --noassets save oar happens synchronously
// Monitor.Wait(this, 60000);
Assert.That(m_lastRequestId, Is.EqualTo(requestId));
byte[] archive = archiveWriteStream.ToArray();
MemoryStream archiveReadStream = new MemoryStream(archive);
TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
List<string> foundPaths = new List<string>();
List<string> expectedPaths = new List<string>();
expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog1));
expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2));
string filePath;
TarArchiveReader.TarEntryType tarEntryType;
byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
arr.LoadControlFile(filePath, data);
Assert.That(arr.ControlFileLoaded, Is.True);
while (tar.ReadEntry(out filePath, out tarEntryType) != null)
{
if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
{
Assert.Fail("Asset was found in saved oar of TestSaveOarNoAssets()");
}
else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
{
foundPaths.Add(filePath);
}
}
Assert.That(foundPaths, Is.EquivalentTo(expectedPaths));
// TODO: Test presence of more files and contents of files.
}
/// <summary> /// <summary>
/// Test loading an OpenSim Region Archive. /// Test loading an OpenSim Region Archive.
/// </summary> /// </summary>
@ -231,7 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// upset load // upset load
tar.WriteDir(ArchiveConstants.TERRAINS_PATH); tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>())); tar.WriteFile(
ArchiveConstants.CONTROL_FILE_PATH,
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
SceneObjectPart part1 = CreateSceneObjectPart1(); SceneObjectPart part1 = CreateSceneObjectPart1();
SceneObjectGroup object1 = new SceneObjectGroup(part1); SceneObjectGroup object1 = new SceneObjectGroup(part1);
@ -313,6 +397,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null"); Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels");
// Temporary // Temporary
Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod());
} }
@ -330,7 +416,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
tar.WriteDir(ArchiveConstants.TERRAINS_PATH); tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>())); tar.WriteFile(
ArchiveConstants.CONTROL_FILE_PATH,
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
RegionSettings rs = new RegionSettings(); RegionSettings rs = new RegionSettings();
rs.AgentLimit = 17; rs.AgentLimit = 17;
@ -352,6 +440,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
rs.Elevation2SE = 9.2; rs.Elevation2SE = 9.2;
rs.Elevation2SW = 2.1; rs.Elevation2SW = 2.1;
rs.FixedSun = true; rs.FixedSun = true;
rs.SunPosition = 12.0;
rs.ObjectBonus = 1.4; rs.ObjectBonus = 1.4;
rs.RestrictPushing = true; rs.RestrictPushing = true;
rs.TerrainLowerLimit = 0.4; rs.TerrainLowerLimit = 0.4;
@ -397,6 +486,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2)); Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2));
Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1)); Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1));
Assert.That(loadedRs.FixedSun, Is.True); Assert.That(loadedRs.FixedSun, Is.True);
Assert.AreEqual(12.0, loadedRs.SunPosition);
Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4)); Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4));
Assert.That(loadedRs.RestrictPushing, Is.True); Assert.That(loadedRs.RestrictPushing, Is.True);
Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4)); Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4));

View File

@ -520,8 +520,12 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
} }
/// <summary>
/// Like handleEventManagerOnSignificantClientMovement, but called with an AgentUpdate regardless of distance.
/// </summary>
/// <param name="avatar"></param>
public void EventManagerOnClientMovement(ScenePresence avatar) public void EventManagerOnClientMovement(ScenePresence avatar)
//Like handleEventManagerOnSignificantClientMovement, but called with an AgentUpdate regardless of distance. //
{ {
ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
if (over != null) if (over != null)
@ -534,7 +538,6 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
} }
public void ClientOnParcelAccessListRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID, public void ClientOnParcelAccessListRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID,
int landLocalID, IClientAPI remote_client) int landLocalID, IClientAPI remote_client)
{ {
@ -668,14 +671,14 @@ namespace OpenSim.Region.CoreModules.World.Land
//m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
} }
m_landList.Clear(); m_landList.Clear();
ResetSimLandObjects();
if (setupDefaultParcel)
CreateDefaultParcel();
} }
ResetSimLandObjects();
if (setupDefaultParcel)
CreateDefaultParcel();
} }
private void performFinalLandJoin(ILandObject master, ILandObject slave) private void performFinalLandJoin(ILandObject master, ILandObject slave)
@ -1391,8 +1394,11 @@ namespace OpenSim.Region.CoreModules.World.Land
public void EventManagerOnNoLandDataFromStorage() public void EventManagerOnNoLandDataFromStorage()
{ {
ResetSimLandObjects(); lock (m_landList)
CreateDefaultParcel(); {
ResetSimLandObjects();
CreateDefaultParcel();
}
} }
#endregion #endregion

View File

@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public int GetPrimsFree() public int GetPrimsFree()
{ {
m_scene.EventManager.TriggerParcelPrimCountUpdate(); m_scene.EventManager.TriggerParcelPrimCountUpdate();
int free = GetSimulatorMaxPrimCount(this) - m_landData.SimwidePrims; int free = GetSimulatorMaxPrimCount() - m_landData.SimwidePrims;
return free; return free;
} }
@ -181,11 +181,11 @@ namespace OpenSim.Region.CoreModules.World.Land
overrideSimulatorMaxPrimCount = overrideDel; overrideSimulatorMaxPrimCount = overrideDel;
} }
public int GetParcelMaxPrimCount(ILandObject thisObject) public int GetParcelMaxPrimCount()
{ {
if (overrideParcelMaxPrimCount != null) if (overrideParcelMaxPrimCount != null)
{ {
return overrideParcelMaxPrimCount(thisObject); return overrideParcelMaxPrimCount(this);
} }
else else
{ {
@ -197,11 +197,12 @@ namespace OpenSim.Region.CoreModules.World.Land
return parcelMax; return parcelMax;
} }
} }
public int GetSimulatorMaxPrimCount(ILandObject thisObject)
public int GetSimulatorMaxPrimCount()
{ {
if (overrideSimulatorMaxPrimCount != null) if (overrideSimulatorMaxPrimCount != null)
{ {
return overrideSimulatorMaxPrimCount(thisObject); return overrideSimulatorMaxPrimCount(this);
} }
else else
{ {
@ -244,8 +245,8 @@ namespace OpenSim.Region.CoreModules.World.Land
remote_client.SendLandProperties(seq_id, remote_client.SendLandProperties(seq_id,
snap_selection, request_result, this, snap_selection, request_result, this,
(float)m_scene.RegionInfo.RegionSettings.ObjectBonus, (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
GetParcelMaxPrimCount(this), GetParcelMaxPrimCount(),
GetSimulatorMaxPrimCount(this), regionFlags); GetSimulatorMaxPrimCount(), regionFlags);
} }
public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client)

View File

@ -37,7 +37,6 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.World.Land.Tests namespace OpenSim.Region.CoreModules.World.Land.Tests
{ {

View File

@ -40,7 +40,6 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
{ {

View File

@ -548,18 +548,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// libomv will moan about PrimFlags.ObjectYouOfficer being // libomv will moan about PrimFlags.ObjectYouOfficer being
// deprecated // deprecated
#pragma warning disable 0612 #pragma warning disable 0612
objflags &= (uint) objflags &= (uint)
~(PrimFlags.ObjectCopy | // Tells client you can copy the object ~(PrimFlags.ObjectCopy | // Tells client you can copy the object
PrimFlags.ObjectModify | // tells client you can modify the object PrimFlags.ObjectModify | // tells client you can modify the object
PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
); );
#pragma warning restore 0612 #pragma warning restore 0612
// Creating the three ObjectFlags options for this method to choose from. // Creating the three ObjectFlags options for this method to choose from.
// Customize the OwnerMask // Customize the OwnerMask
@ -576,22 +576,27 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_bypassPermissions) if (m_bypassPermissions)
return objectOwnerMask; return objectOwnerMask;
// Object owners should be able to edit their own content // Object owners should be able to edit their own content
if (user == objectOwner) if (user == objectOwner)
return objectOwnerMask; return objectOwnerMask;
if (IsFriendWithPerms(user, objectOwner))
return objectOwnerMask;
if (IsFriendWithPerms(user, objectOwner))
{
return objectOwnerMask;
}
// Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
{
return objectOwnerMask; return objectOwnerMask;
}
// Admin should be able to edit anything in the sim (including admin objects) // Admin should be able to edit anything in the sim (including admin objects)
if (IsAdministrator(user)) if (IsAdministrator(user))
{
return objectOwnerMask; return objectOwnerMask;
}
// Users should be able to edit what is over their land. // Users should be able to edit what is over their land.
Vector3 taskPos = task.AbsolutePosition; Vector3 taskPos = task.AbsolutePosition;
ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
@ -599,13 +604,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions
{ {
// Admin objects should not be editable by the above // Admin objects should not be editable by the above
if (!IsAdministrator(objectOwner)) if (!IsAdministrator(objectOwner))
{
return objectOwnerMask; return objectOwnerMask;
}
} }
// Group permissions // Group permissions
if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
return objectGroupMask | objectEveryoneMask; return objectGroupMask | objectEveryoneMask;
return objectEveryoneMask; return objectEveryoneMask;
} }
@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// //
// Nobody but the object owner can set permissions on an object // Nobody but the object owner can set permissions on an object
// //
if (locked && (!IsAdministrator(currentUser)) && denyOnLocked) if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
{ {
return false; return false;
@ -704,6 +710,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// Return immediately, so that the administrator can shares group objects // Return immediately, so that the administrator can shares group objects
return true; return true;
} }
// Friends with benefits should be able to edit the objects too
if (IsFriendWithPerms(currentUser, objectOwner))
// Return immediately, so that the administrator can share objects with friends
return true;
// Users should be able to edit what is over their land. // Users should be able to edit what is over their land.
ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);

View File

@ -70,14 +70,14 @@ namespace OpenSim.Region.CoreModules.World.Region
false, "region restart bluebox", false, "region restart bluebox",
"region restart bluebox <message> <delta seconds>+", "region restart bluebox <message> <delta seconds>+",
"Schedule a region restart", "Schedule a region restart",
"Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.", "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.",
HandleRegionRestart); HandleRegionRestart);
MainConsole.Instance.Commands.AddCommand("RestartModule", MainConsole.Instance.Commands.AddCommand("RestartModule",
false, "region restart notice", false, "region restart notice",
"region restart notice <message> <delta seconds>+", "region restart notice <message> <delta seconds>+",
"Schedule a region restart", "Schedule a region restart",
"Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.", "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.",
HandleRegionRestart); HandleRegionRestart);
MainConsole.Instance.Commands.AddCommand("RestartModule", MainConsole.Instance.Commands.AddCommand("RestartModule",

View File

@ -35,7 +35,6 @@ using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.World.Serialiser.Tests namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
{ {

View File

@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule
{ {
private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3");
private static readonly Color4 WATER_COLOR = new Color4(29, 71, 95, 216); private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216);
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
private IRendering m_primMesher; private IRendering m_primMesher;
private IConfigSource m_config; private IConfigSource m_config;
private Dictionary<UUID, Color4> m_colors = new Dictionary<UUID, Color4>(); private Dictionary<UUID, Color4> m_colors = new Dictionary<UUID, Color4>();
private bool m_useAntiAliasing = true; // TODO: Make this a config option private bool m_useAntiAliasing = false; // TODO: Make this a config option
private bool m_Enabled = false; private bool m_Enabled = false;
#region IRegionModule Members #region IRegionModule Members
@ -192,8 +192,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
#endregion Camera #endregion Camera
renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(0.2f, 0.2f, 1f), 0xffffff, 320, 80)); renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40));
renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 100, 40)); renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40));
CreateWater(renderer); CreateWater(renderer);
CreateTerrain(renderer, textureTerrain); CreateTerrain(renderer, textureTerrain);
@ -237,6 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f); renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f);
renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR)); renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR));
renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif
renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f)); renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f));
renderer.SetObjectMaterial("Water", "WaterColor"); renderer.SetObjectMaterial("Water", "WaterColor");
} }
@ -322,6 +323,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
warp_Material material = new warp_Material(texture); warp_Material material = new warp_Material(texture);
material.setReflectivity(50); material.setReflectivity(50);
renderer.Scene.addMaterial("TerrainColor", material); renderer.Scene.addMaterial("TerrainColor", material);
renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif
renderer.SetObjectMaterial("Terrain", "TerrainColor"); renderer.SetObjectMaterial("Terrain", "TerrainColor");
} }
@ -653,4 +655,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
return result; return result;
} }
} }
} }

View File

@ -208,52 +208,65 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
//m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
// path, param, agentID.ToString()); // path, param, agentID.ToString());
// this is here because CAPS map requests work even beyond the 10,000 limit. // There is a major hack going on in this method. The viewer doesn't request
ScenePresence avatarPresence = null; // map blocks (RequestMapBlocks) above 2048. That means that if we don't hack,
// grids above that cell don't have a map at all. So, here's the hack: we wait
// for this CAP request to come, and we inject the map blocks at this point.
// In a normal scenario, this request simply sends back the MapLayer (the blue color).
// In the hacked scenario, it also sends the map blocks via UDP.
//
// 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
// a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
m_scene.TryGetScenePresence(agentID, out avatarPresence); if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
if (avatarPresence != null)
{ {
bool lookup = false; ScenePresence avatarPresence = null;
lock (cachedMapBlocks) m_scene.TryGetScenePresence(agentID, out avatarPresence);
if (avatarPresence != null)
{ {
if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) bool lookup = false;
{
List<MapBlockData> mapBlocks;
mapBlocks = cachedMapBlocks;
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
}
else
{
lookup = true;
}
}
if (lookup)
{
List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
(int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
foreach (GridRegion r in regions)
{
MapBlockData block = new MapBlockData();
MapBlockFromGridRegion(block, r);
mapBlocks.Add(block);
}
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
lock (cachedMapBlocks) lock (cachedMapBlocks)
cachedMapBlocks = mapBlocks; {
if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
{
List<MapBlockData> mapBlocks;
cachedTime = Util.UnixTimeSinceEpoch(); mapBlocks = cachedMapBlocks;
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
}
else
{
lookup = true;
}
}
if (lookup)
{
List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
(int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
foreach (GridRegion r in regions)
{
MapBlockData block = new MapBlockData();
MapBlockFromGridRegion(block, r);
mapBlocks.Add(block);
}
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
lock (cachedMapBlocks)
cachedMapBlocks = mapBlocks;
cachedTime = Util.UnixTimeSinceEpoch();
}
} }
} }
LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
return mapResponse.ToString(); return mapResponse.ToString();
@ -823,7 +836,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
block.Access = 254; // means 'simulator is offline' block.Access = 254; // means 'simulator is offline'
response.Add(block); response.Add(block);
} }
remoteClient.SendMapBlock(response, 0); if ((flag & 2) == 2) // V2 !!!
remoteClient.SendMapBlock(response, 2);
else
remoteClient.SendMapBlock(response, 0);
} }
else else
{ {
@ -832,7 +848,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
} }
} }
protected virtual void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
{ {
List<MapBlockData> mapBlocks = new List<MapBlockData>(); List<MapBlockData> mapBlocks = new List<MapBlockData>();
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
@ -846,7 +862,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
MapBlockFromGridRegion(block, r); MapBlockFromGridRegion(block, r);
mapBlocks.Add(block); mapBlocks.Add(block);
} }
remoteClient.SendMapBlock(mapBlocks, 0); if ((flag & 2) == 2) // V2 !!!
remoteClient.SendMapBlock(mapBlocks, 2);
else
remoteClient.SendMapBlock(mapBlocks, 0);
return mapBlocks;
} }
protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r) protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r)

View File

@ -550,7 +550,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

@ -40,6 +40,9 @@ namespace OpenSim.Region.Framework.Interfaces
void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position,
Vector3 lookAt, uint teleportFlags); Vector3 lookAt, uint teleportFlags);
void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq);
void TeleportHome(UUID id, IClientAPI client); void TeleportHome(UUID id, IClientAPI client);
bool Cross(ScenePresence agent, bool isFlying); bool Cross(ScenePresence agent, bool isFlying);

View File

@ -34,6 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IFriendsModule public interface IFriendsModule
{ {
uint GetFriendPerms(UUID PrincipalID, UUID FriendID); uint GetFriendPerms(UUID PrincipalID, UUID FriendID);
void SendFriendsOnlineIfNeeded(IClientAPI client); bool SendFriendsOnlineIfNeeded(IClientAPI client);
} }
} }

View File

@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces
{ {
public interface IGridDialogModule public interface IGridDialogModule
{ {
void SendGridDialogViaXMLRPC(UUID avatarID, string objectName, UUID objectID, string ownerFirstName, string ownerLastName, void SendGridDialogViaXMLRPC(UUID avatarID, string objectName, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName,
string message, UUID textureID, int ch, string[] buttonlabels, UUID prevRegionID); string message, UUID textureID, int ch, string[] buttonlabels, UUID prevRegionID);
} }
} }

View File

@ -52,31 +52,44 @@ namespace OpenSim.Region.Framework.Interfaces
/// <summary> /// <summary>
/// Archive the region to the given path /// Archive the region to the given path
/// </summary> /// </summary>
/// /// <remarks>
/// This method occurs asynchronously. If you want notification of when it has completed then subscribe to /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
/// the EventManager.OnOarFileSaved event. /// the EventManager.OnOarFileSaved event.
/// /// </remarks>
/// <param name="savePath"></param> /// <param name="savePath"></param>
/// <param name="requestId">If supplied, this request Id is later returned in the saved event</param> /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
/// <param name="options">Options for the save</param>
void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options); void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options);
/// <summary> /// <summary>
/// Archive the region to a stream. /// Archive the region to a stream.
/// </summary> /// </summary>
/// /// <remarks>
/// This method occurs asynchronously. If you want notification of when it has completed then subscribe to /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
/// the EventManager.OnOarFileSaved event. /// the EventManager.OnOarFileSaved event.
/// /// </remarks>
/// <param name="saveStream"></param> /// <param name="saveStream"></param>
/// <param name="requestId">If supplied, this request Id is later returned in the saved event</param> /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
void ArchiveRegion(Stream saveStream, Guid requestId); void ArchiveRegion(Stream saveStream, Guid requestId);
/// <summary>
/// Archive the region to a stream.
/// </summary>
/// <remarks>
/// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
/// the EventManager.OnOarFileSaved event.
/// </remarks>
/// <param name="saveStream"></param>
/// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
/// <param name="options">Options for the save</param>
void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options);
/// <summary> /// <summary>
/// Dearchive the given region archive. This replaces the existing scene. /// Dearchive the given region archive. This replaces the existing scene.
/// </summary> /// </summary>
/// /// <remarks>
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event. /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
/// /// </remarks>
/// <param name="loadPath"></param> /// <param name="loadPath"></param>
void DearchiveRegion(string loadPath); void DearchiveRegion(string loadPath);

View File

@ -50,5 +50,7 @@ namespace OpenSim.Region.Framework.Interfaces
void ResumeScript(UUID itemID); void ResumeScript(UUID itemID);
ArrayList GetScriptErrors(UUID itemID); ArrayList GetScriptErrors(UUID itemID);
void SaveAllState();
} }
} }

View File

@ -8,6 +8,9 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IUserManagement public interface IUserManagement
{ {
string GetUserName(UUID uuid); string GetUserName(UUID uuid);
string GetUserHomeURL(UUID uuid);
string GetUserUUI(UUID uuid);
string GetUserServerURL(UUID uuid, string serverType);
void AddUser(UUID uuid, string userData); void AddUser(UUID uuid, string userData);
void AddUser(UUID uuid, string firstName, string lastName, string profileURL); void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
} }

View File

@ -462,6 +462,10 @@ namespace OpenSim.Region.Framework.Scenes
public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
public delegate void SceneShuttingDownDelegate(Scene scene);
public event SceneShuttingDownDelegate OnSceneShuttingDown;
/// <summary> /// <summary>
/// Fired when an object is touched/grabbed. /// Fired when an object is touched/grabbed.
/// </summary> /// </summary>
@ -736,6 +740,12 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void RegionUp(GridRegion region); public delegate void RegionUp(GridRegion region);
public event RegionUp OnRegionUp; public event RegionUp OnRegionUp;
public delegate void LoginsEnabled(string regionName);
public event LoginsEnabled OnLoginsEnabled;
public delegate void PrimsLoaded(Scene s);
public event PrimsLoaded OnPrimsLoaded;
public class MoneyTransferArgs : EventArgs public class MoneyTransferArgs : EventArgs
{ {
public UUID sender; public UUID sender;
@ -2564,6 +2574,69 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerSceneShuttingDown(Scene s)
{
SceneShuttingDownDelegate handler = OnSceneShuttingDown;
if (handler != null)
{
foreach (SceneShuttingDownDelegate d in handler.GetInvocationList())
{
try
{
d(s);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerSceneShuttingDown failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
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);
}
}
}
}
//REGION SYNC //REGION SYNC
#region REGION SYNC RELATED EVENTS #region REGION SYNC RELATED EVENTS
//OnScriptEngineSyncStop: triggered when user types "sync stop" on the script engine's console //OnScriptEngineSyncStop: triggered when user types "sync stop" on the script engine's console

View File

@ -596,192 +596,198 @@ namespace OpenSim.Region.Framework.Scenes
InventoryItemBase item = new InventoryItemBase(itemId, senderId); InventoryItemBase item = new InventoryItemBase(itemId, senderId);
item = InventoryService.GetItem(item); item = InventoryService.GetItem(item);
if ((item != null) && (item.Owner == senderId)) if (item == null)
{ {
IUserManagement uman = RequestModuleInterface<IUserManagement>(); m_log.WarnFormat(
if (uman != null) "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient);
uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
if (!Permissions.BypassPermissions())
{
if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
return null;
}
// Insert a copy of the item into the recipient
InventoryItemBase itemCopy = new InventoryItemBase();
itemCopy.Owner = recipient;
itemCopy.CreatorId = item.CreatorId;
itemCopy.CreatorData = item.CreatorData;
itemCopy.ID = UUID.Random();
itemCopy.AssetID = item.AssetID;
itemCopy.Description = item.Description;
itemCopy.Name = item.Name;
itemCopy.AssetType = item.AssetType;
itemCopy.InvType = item.InvType;
itemCopy.Folder = recipientFolderId;
if (Permissions.PropagatePermissions() && recipient != senderId)
{
// Trying to do this right this time. This is evil. If
// you believe in Good, go elsewhere. Vampires and other
// evil creatores only beyond this point. You have been
// warned.
// We're going to mask a lot of things by the next perms
// Tweak the next perms to be nicer to our data
//
// In this mask, all the bits we do NOT want to mess
// with are set. These are:
//
// Transfer
// Copy
// Modufy
uint permsMask = ~ ((uint)PermissionMask.Copy |
(uint)PermissionMask.Transfer |
(uint)PermissionMask.Modify);
// Now, reduce the next perms to the mask bits
// relevant to the operation
uint nextPerms = permsMask | (item.NextPermissions &
((uint)PermissionMask.Copy |
(uint)PermissionMask.Transfer |
(uint)PermissionMask.Modify));
// nextPerms now has all bits set, except for the actual
// next permission bits.
// This checks for no mod, no copy, no trans.
// This indicates an error or messed up item. Do it like
// SL and assume trans
if (nextPerms == permsMask)
nextPerms |= (uint)PermissionMask.Transfer;
// Inventory owner perms are the logical AND of the
// folded perms and the root prim perms, however, if
// the root prim is mod, the inventory perms will be
// mod. This happens on "take" and is of little concern
// here, save for preventing escalation
// This hack ensures that items previously permalocked
// get unlocked when they're passed or rezzed
uint basePerms = item.BasePermissions |
(uint)PermissionMask.Move;
uint ownerPerms = item.CurrentPermissions;
// If this is an object, root prim perms may be more
// permissive than folded perms. Use folded perms as
// a mask
if (item.InvType == (int)InventoryType.Object)
{
// Create a safe mask for the current perms
uint foldedPerms = (item.CurrentPermissions & 7) << 13;
foldedPerms |= permsMask;
bool isRootMod = (item.CurrentPermissions &
(uint)PermissionMask.Modify) != 0 ?
true : false;
// Mask the owner perms to the folded perms
ownerPerms &= foldedPerms;
basePerms &= foldedPerms;
// If the root was mod, let the mask reflect that
// We also need to adjust the base here, because
// we should be able to edit in-inventory perms
// for the root prim, if it's mod.
if (isRootMod)
{
ownerPerms |= (uint)PermissionMask.Modify;
basePerms |= (uint)PermissionMask.Modify;
}
}
// These will be applied to the root prim at next rez.
// The slam bit (bit 3) and folded permission (bits 0-2)
// are preserved due to the above mangling
ownerPerms &= nextPerms;
// Mask the base permissions. This is a conservative
// approach altering only the three main perms
basePerms &= nextPerms;
// Assign to the actual item. Make sure the slam bit is
// set, if it wasn't set before.
itemCopy.BasePermissions = basePerms;
itemCopy.CurrentPermissions = ownerPerms;
itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
itemCopy.NextPermissions = item.NextPermissions;
// This preserves "everyone can move"
itemCopy.EveryOnePermissions = item.EveryOnePermissions &
nextPerms;
// Intentionally killing "share with group" here, as
// the recipient will not have the group this is
// set to
itemCopy.GroupPermissions = 0;
}
else
{
itemCopy.CurrentPermissions = item.CurrentPermissions;
itemCopy.NextPermissions = item.NextPermissions;
itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
itemCopy.BasePermissions = item.BasePermissions;
}
if (itemCopy.Folder == UUID.Zero)
{
InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
if (folder != null)
{
itemCopy.Folder = folder.ID;
}
else
{
InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
if (root != null)
itemCopy.Folder = root.ID;
else
return null; // No destination
}
}
itemCopy.GroupID = UUID.Zero;
itemCopy.GroupOwned = false;
itemCopy.Flags = item.Flags;
itemCopy.SalePrice = item.SalePrice;
itemCopy.SaleType = item.SaleType;
if (AddInventoryItem(itemCopy))
{
IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null)
invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
}
if (!Permissions.BypassPermissions())
{
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
{
List<UUID> items = new List<UUID>();
items.Add(itemId);
InventoryService.DeleteItems(senderId, items);
}
}
return itemCopy;
}
else
{
m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId);
return null; return null;
} }
if (item.Owner != senderId)
{
m_log.WarnFormat(
"[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}",
item.Name, item.ID, recipient, senderId, item.Owner);
return null;
}
IUserManagement uman = RequestModuleInterface<IUserManagement>();
if (uman != null)
uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
if (!Permissions.BypassPermissions())
{
if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
return null;
}
// Insert a copy of the item into the recipient
InventoryItemBase itemCopy = new InventoryItemBase();
itemCopy.Owner = recipient;
itemCopy.CreatorId = item.CreatorId;
itemCopy.CreatorData = item.CreatorData;
itemCopy.ID = UUID.Random();
itemCopy.AssetID = item.AssetID;
itemCopy.Description = item.Description;
itemCopy.Name = item.Name;
itemCopy.AssetType = item.AssetType;
itemCopy.InvType = item.InvType;
itemCopy.Folder = recipientFolderId;
if (Permissions.PropagatePermissions() && recipient != senderId)
{
// Trying to do this right this time. This is evil. If
// you believe in Good, go elsewhere. Vampires and other
// evil creatores only beyond this point. You have been
// warned.
// We're going to mask a lot of things by the next perms
// Tweak the next perms to be nicer to our data
//
// In this mask, all the bits we do NOT want to mess
// with are set. These are:
//
// Transfer
// Copy
// Modufy
uint permsMask = ~ ((uint)PermissionMask.Copy |
(uint)PermissionMask.Transfer |
(uint)PermissionMask.Modify);
// Now, reduce the next perms to the mask bits
// relevant to the operation
uint nextPerms = permsMask | (item.NextPermissions &
((uint)PermissionMask.Copy |
(uint)PermissionMask.Transfer |
(uint)PermissionMask.Modify));
// nextPerms now has all bits set, except for the actual
// next permission bits.
// This checks for no mod, no copy, no trans.
// This indicates an error or messed up item. Do it like
// SL and assume trans
if (nextPerms == permsMask)
nextPerms |= (uint)PermissionMask.Transfer;
// Inventory owner perms are the logical AND of the
// folded perms and the root prim perms, however, if
// the root prim is mod, the inventory perms will be
// mod. This happens on "take" and is of little concern
// here, save for preventing escalation
// This hack ensures that items previously permalocked
// get unlocked when they're passed or rezzed
uint basePerms = item.BasePermissions |
(uint)PermissionMask.Move;
uint ownerPerms = item.CurrentPermissions;
// If this is an object, root prim perms may be more
// permissive than folded perms. Use folded perms as
// a mask
if (item.InvType == (int)InventoryType.Object)
{
// Create a safe mask for the current perms
uint foldedPerms = (item.CurrentPermissions & 7) << 13;
foldedPerms |= permsMask;
bool isRootMod = (item.CurrentPermissions &
(uint)PermissionMask.Modify) != 0 ?
true : false;
// Mask the owner perms to the folded perms
ownerPerms &= foldedPerms;
basePerms &= foldedPerms;
// If the root was mod, let the mask reflect that
// We also need to adjust the base here, because
// we should be able to edit in-inventory perms
// for the root prim, if it's mod.
if (isRootMod)
{
ownerPerms |= (uint)PermissionMask.Modify;
basePerms |= (uint)PermissionMask.Modify;
}
}
// These will be applied to the root prim at next rez.
// The slam bit (bit 3) and folded permission (bits 0-2)
// are preserved due to the above mangling
ownerPerms &= nextPerms;
// Mask the base permissions. This is a conservative
// approach altering only the three main perms
basePerms &= nextPerms;
// Assign to the actual item. Make sure the slam bit is
// set, if it wasn't set before.
itemCopy.BasePermissions = basePerms;
itemCopy.CurrentPermissions = ownerPerms;
itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
itemCopy.NextPermissions = item.NextPermissions;
// This preserves "everyone can move"
itemCopy.EveryOnePermissions = item.EveryOnePermissions &
nextPerms;
// Intentionally killing "share with group" here, as
// the recipient will not have the group this is
// set to
itemCopy.GroupPermissions = 0;
}
else
{
itemCopy.CurrentPermissions = item.CurrentPermissions;
itemCopy.NextPermissions = item.NextPermissions;
itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
itemCopy.BasePermissions = item.BasePermissions;
}
if (itemCopy.Folder == UUID.Zero)
{
InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
if (folder != null)
{
itemCopy.Folder = folder.ID;
}
else
{
InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
if (root != null)
itemCopy.Folder = root.ID;
else
return null; // No destination
}
}
itemCopy.GroupID = UUID.Zero;
itemCopy.GroupOwned = false;
itemCopy.Flags = item.Flags;
itemCopy.SalePrice = item.SalePrice;
itemCopy.SaleType = item.SaleType;
if (AddInventoryItem(itemCopy))
{
IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null)
invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
}
if (!Permissions.BypassPermissions())
{
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
{
List<UUID> items = new List<UUID>();
items.Add(itemId);
InventoryService.DeleteItems(senderId, items);
}
}
return itemCopy;
} }
/// <summary> /// <summary>
@ -949,7 +955,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="asset"></param> /// <param name="asset"></param>
/// <param name="invType"></param> /// <param name="invType"></param>
/// <param name="nextOwnerMask"></param> /// <param name="nextOwnerMask"></param>
private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, public void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
{ {
CreateNewInventoryItem( CreateNewInventoryItem(
@ -1003,78 +1009,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Create a new inventory item. Called when the client creates a new item directly within their
/// inventory (e.g. by selecting a context inventory menu option).
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="transactionID"></param>
/// <param name="folderID"></param>
/// <param name="callbackID"></param>
/// <param name="description"></param>
/// <param name="name"></param>
/// <param name="invType"></param>
/// <param name="type"></param>
/// <param name="wearableType"></param>
/// <param name="nextOwnerMask"></param>
public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
uint callbackID, string description, string name, sbyte invType,
sbyte assetType,
byte wearableType, uint nextOwnerMask, int creationDate)
{
m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
return;
InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
InventoryFolderBase folder = InventoryService.GetFolder(f);
if (folder == null || folder.Owner != remoteClient.AgentId)
return;
if (transactionID == UUID.Zero)
{
ScenePresence presence;
if (TryGetScenePresence(remoteClient.AgentId, out presence))
{
byte[] data = null;
if (invType == (sbyte)InventoryType.Landmark && presence != null)
{
Vector3 pos = presence.AbsolutePosition;
string strdata = String.Format(
"Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
presence.Scene.RegionInfo.RegionID,
pos.X, pos.Y, pos.Z,
presence.RegionHandle);
data = Encoding.ASCII.GetBytes(strdata);
}
AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
AssetService.Store(asset);
CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
}
else
{
m_log.ErrorFormat(
"ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
remoteClient.AgentId);
}
}
else
{
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
if (agentTransactions != null)
{
agentTransactions.HandleItemCreationFromTransaction(
remoteClient, transactionID, folderID, callbackID, description,
name, invType, assetType, wearableType, nextOwnerMask);
}
}
}
/// <summary> /// <summary>
/// Link an inventory item to an existing item. /// Link an inventory item to an existing item.
/// </summary> /// </summary>
@ -1095,9 +1029,9 @@ namespace OpenSim.Region.Framework.Scenes
uint callbackID, string description, string name, uint callbackID, string description, string name,
sbyte invType, sbyte type, UUID olditemID) sbyte invType, sbyte type, UUID olditemID)
{ {
m_log.DebugFormat( // m_log.DebugFormat(
"[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}", // "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}",
remoteClient.Name, name, folderID, olditemID); // remoteClient.Name, name, folderID, olditemID);
if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
return; return;
@ -1105,20 +1039,25 @@ namespace OpenSim.Region.Framework.Scenes
ScenePresence presence; ScenePresence presence;
if (TryGetScenePresence(remoteClient.AgentId, out presence)) if (TryGetScenePresence(remoteClient.AgentId, out presence))
{ {
bool linkAlreadyExists = false; // Disabled the check for duplicate links.
List<InventoryItemBase> existingItems = InventoryService.GetFolderItems(remoteClient.AgentId, folderID); //
foreach (InventoryItemBase item in existingItems) // When outfits are being adjusted, the viewer rapidly sends delete link messages followed by
if (item.AssetID == olditemID) // create links. However, since these are handled asynchronously, the deletes do not complete before
linkAlreadyExists = true; // the creates are handled. Therefore, we cannot enforce a duplicate link check.
// InventoryItemBase existingLink = null;
if (linkAlreadyExists) // List<InventoryItemBase> existingItems = InventoryService.GetFolderItems(remoteClient.AgentId, folderID);
{ // foreach (InventoryItemBase item in existingItems)
m_log.WarnFormat( // if (item.AssetID == olditemID)
"[AGENT INVENTORY]: Ignoring request from {0} to create item link {1} in folder {2} pointing to {3} since a link already exists", // existingLink = item;
remoteClient.Name, name, folderID, olditemID); //
// if (existingLink != null)
return; // {
} // m_log.WarnFormat(
// "[AGENT INVENTORY]: Ignoring request from {0} to create item link {1} in folder {2} pointing to {3} since a link named {4} with id {5} already exists",
// remoteClient.Name, name, folderID, olditemID, existingLink.Name, existingLink.ID);
//
// return;
// }
AssetBase asset = new AssetBase(); AssetBase asset = new AssetBase();
asset.FullID = olditemID; asset.FullID = olditemID;
@ -1146,7 +1085,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="itemID"></param> /// <param name="itemID"></param>
private void RemoveInventoryItem(IClientAPI remoteClient, List<UUID> itemIDs) private void RemoveInventoryItem(IClientAPI remoteClient, List<UUID> itemIDs)
{ {
//m_log.Debug("[SCENE INVENTORY]: user " + remoteClient.AgentId); // m_log.DebugFormat(
// "[AGENT INVENTORY]: Removing inventory items {0} for {1}",
// string.Join(",", itemIDs.ConvertAll<string>(uuid => uuid.ToString()).ToArray()),
// remoteClient.Name);
InventoryService.DeleteItems(remoteClient.AgentId, itemIDs); InventoryService.DeleteItems(remoteClient.AgentId, itemIDs);
} }
@ -1566,7 +1509,10 @@ namespace OpenSim.Region.Framework.Scenes
if (item.AssetType == (int)AssetType.Link) if (item.AssetType == (int)AssetType.Link)
{ {
InventoryItemBase linkedItem = InventoryService.GetItem(new InventoryItemBase(item.AssetID)); InventoryItemBase linkedItem = InventoryService.GetItem(new InventoryItemBase(item.AssetID));
linkedItemFolderIdsToSend.Add(linkedItem.Folder);
// Take care of genuinely broken links where the target doesn't exist
if (linkedItem != null)
linkedItemFolderIdsToSend.Add(linkedItem.Folder);
} }
} }
@ -2293,7 +2239,7 @@ namespace OpenSim.Region.Framework.Scenes
sourcePart.Inventory.RemoveInventoryItem(item.ItemID); sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
} }
//AddNewSceneObject(group, true); //AddNewSceneObject(group, true, pos, rot, vel);
//DSG SYNC //DSG SYNC
bool triggerSyncNewObject = false; bool triggerSyncNewObject = false;
AddNewSceneObjectByRez(group, true, true, triggerSyncNewObject); AddNewSceneObjectByRez(group, true, true, triggerSyncNewObject);

View File

@ -94,7 +94,10 @@ namespace OpenSim.Region.Framework.Scenes
// root agents when ACL denies access to root agent // root agents when ACL denies access to root agent
public bool m_strictAccessControl = true; public bool m_strictAccessControl = true;
public int MaxUndoCount = 5; public int MaxUndoCount = 5;
// Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
public bool LoginLock = false;
public bool LoginsDisabled = true; public bool LoginsDisabled = true;
public bool StartDisabled = false;
public bool LoadingPrims; public bool LoadingPrims;
public IXfer XferManager; public IXfer XferManager;
@ -204,6 +207,7 @@ namespace OpenSim.Region.Framework.Scenes
private Timer m_mapGenerationTimer = new Timer(); private Timer m_mapGenerationTimer = new Timer();
private bool m_generateMaptiles; private bool m_generateMaptiles;
private bool m_useBackup = true;
// private Dictionary<UUID, string[]> m_UserNamesCache = new Dictionary<UUID, string[]>(); // private Dictionary<UUID, string[]> m_UserNamesCache = new Dictionary<UUID, string[]>();
@ -975,6 +979,11 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_sceneGraph; } get { return m_sceneGraph; }
} }
public bool UseBackup
{
get { return m_useBackup; }
}
// an instance to the physics plugin's Scene object. // an instance to the physics plugin's Scene object.
public PhysicsScene PhysicsScene public PhysicsScene PhysicsScene
{ {
@ -1116,7 +1125,7 @@ namespace OpenSim.Region.Framework.Scenes
"delete object uuid <UUID>", "delete object uuid <UUID>",
"Delete object by uuid", HandleDeleteObject); "Delete object by uuid", HandleDeleteObject);
MainConsole.Instance.Commands.AddCommand("region", false, "delete object name", MainConsole.Instance.Commands.AddCommand("region", false, "delete object name",
"delete object name <UUID>", "delete object name <name>",
"Delete object by name", HandleDeleteObject); "Delete object by name", HandleDeleteObject);
//Bind Storage Manager functions to some land manager functions for this scene //Bind Storage Manager functions to some land manager functions for this scene
@ -1166,6 +1175,9 @@ namespace OpenSim.Region.Framework.Scenes
IConfig startupConfig = m_config.Configs["Startup"]; IConfig startupConfig = m_config.Configs["Startup"];
m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance); m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance);
m_useBackup = startupConfig.GetBoolean("UseSceneBackup", m_useBackup);
if (!m_useBackup)
m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName);
//Animation states //Animation states
m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
@ -1587,6 +1599,8 @@ namespace OpenSim.Region.Framework.Scenes
shuttingdown = true; shuttingdown = true;
m_log.Debug("[SCENE]: Persisting changed objects for region " + m_regionName); m_log.Debug("[SCENE]: Persisting changed objects for region " + m_regionName);
EventManager.TriggerSceneShuttingDown(this);
EntityBase[] entities = GetEntities(); EntityBase[] entities = GetEntities();
foreach (EntityBase entity in entities) foreach (EntityBase entity in entities)
{ {
@ -1935,10 +1949,26 @@ namespace OpenSim.Region.Framework.Scenes
IConfig startupConfig = m_config.Configs["Startup"]; IConfig startupConfig = m_config.Configs["Startup"];
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
{ {
// This handles a case of a region having no scripts for the RegionReady module
if (m_sceneGraph.GetActiveScriptsCount() == 0)
{
// need to be able to tell these have changed in RegionReady
LoginLock = false;
EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
}
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
LoginsDisabled = false; // For RegionReady lockouts
if( LoginLock == false)
{
LoginsDisabled = false;
}
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
} }
else
{
StartDisabled = true;
LoginsDisabled = true;
}
} }
} }
catch (NotImplementedException) catch (NotImplementedException)
@ -2344,6 +2374,7 @@ namespace OpenSim.Region.Framework.Scenes
m_log.InfoFormat("[SCENE ({0})]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)", m_regionName); m_log.InfoFormat("[SCENE ({0})]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)", m_regionName);
LoadingPrims = false; LoadingPrims = false;
EventManager.TriggerPrimsLoaded(this);
} }
@ -2499,6 +2530,10 @@ namespace OpenSim.Region.Framework.Scenes
sceneObject.SetGroup(groupID, null); sceneObject.SetGroup(groupID, null);
} }
IUserManagement uman = RequestModuleInterface<IUserManagement>();
if (uman != null)
sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
//sceneObject.ScheduleGroupForFullUpdate(); //sceneObject.ScheduleGroupForFullUpdate();
sceneObject.ScheduleGroupForFullUpdate(new List<SceneObjectPartSyncProperties>(){SceneObjectPartSyncProperties.FullUpdate}); //new object, all properties have new value sceneObject.ScheduleGroupForFullUpdate(new List<SceneObjectPartSyncProperties>(){SceneObjectPartSyncProperties.FullUpdate}); //new object, all properties have new value
@ -2592,16 +2627,17 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Add a newly created object to the scene. /// Add a newly created object to the scene.
/// </summary> /// </summary>
/// /// <remarks>
/// This method does not send updates to the client - callers need to handle this themselves. /// This method does not send updates to the client - callers need to handle this themselves.
/// </remarks>
/// <param name="sceneObject"></param> /// <param name="sceneObject"></param>
/// <param name="attachToBackup"></param> /// <param name="attachToBackup"></param>
/// <param name="pos">Position of the object</param> /// <param name="pos">Position of the object. If null then the position stored in the object is used.</param>
/// <param name="rot">Rotation of the object</param> /// <param name="rot">Rotation of the object. If null then the rotation stored in the object is used.</param>
/// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param> /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param>
/// <returns></returns> /// <returns></returns>
public bool AddNewSceneObject( public bool AddNewSceneObject(
SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
{ {
if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel)) if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel))
{ {
@ -3187,12 +3223,38 @@ namespace OpenSim.Region.Framework.Scenes
if (GetScenePresence(client.AgentId) != null) if (GetScenePresence(client.AgentId) != null)
{ {
m_LastLogin = Util.EnvironmentTickCount(); m_LastLogin = Util.EnvironmentTickCount();
// Cache the user's name
CacheUserName(aCircuit);
EventManager.TriggerOnNewClient(client); EventManager.TriggerOnNewClient(client);
if (vialogin) if (vialogin)
EventManager.TriggerOnClientLogin(client); EventManager.TriggerOnClientLogin(client);
} }
} }
private void CacheUserName(AgentCircuitData aCircuit)
{
IUserManagement uMan = RequestModuleInterface<IUserManagement>();
if (uMan != null)
{
string homeURL = string.Empty;
string first = aCircuit.firstname, last = aCircuit.lastname;
if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
if (aCircuit.lastname.StartsWith("@"))
{
string[] parts = aCircuit.firstname.Split('.');
if (parts.Length >= 2)
{
first = parts[0];
last = parts[1];
}
}
uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
}
}
private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin) private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
{ {
vialogin = false; vialogin = false;
@ -3346,7 +3408,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void SubscribeToClientInventoryEvents(IClientAPI client) public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
{ {
client.OnCreateNewInventoryItem += CreateNewInventoryItem;
client.OnLinkInventoryItem += HandleLinkInventoryItem; client.OnLinkInventoryItem += HandleLinkInventoryItem;
client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder; client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder; client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
@ -3369,7 +3431,6 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void SubscribeToClientTeleportEvents(IClientAPI client) public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
{ {
client.OnTeleportLocationRequest += RequestTeleportLocation; client.OnTeleportLocationRequest += RequestTeleportLocation;
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
} }
public virtual void SubscribeToClientScriptEvents(IClientAPI client) public virtual void SubscribeToClientScriptEvents(IClientAPI client)
@ -3473,7 +3534,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client) public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
{ {
client.OnCreateNewInventoryItem -= CreateNewInventoryItem;
client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder; client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder; client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!! client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
@ -3495,7 +3556,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
{ {
client.OnTeleportLocationRequest -= RequestTeleportLocation; client.OnTeleportLocationRequest -= RequestTeleportLocation;
client.OnTeleportLandmarkRequest -= RequestTeleportLandmark; //client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
//client.OnTeleportHomeRequest -= TeleportClientHome; //client.OnTeleportHomeRequest -= TeleportClientHome;
} }
@ -4576,26 +4637,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Tries to teleport agent to landmark.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="regionHandle"></param>
/// <param name="position"></param>
public void RequestTeleportLandmark(IClientAPI remoteClient, UUID regionID, Vector3 position)
{
GridRegion info = GridService.GetRegionByUUID(UUID.Zero, regionID);
if (info == null)
{
// can't find the region: Tell viewer and abort
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
return;
}
RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark));
}
public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
{ {
if (m_teleportModule != null) if (m_teleportModule != null)
@ -4965,7 +5006,28 @@ namespace OpenSim.Region.Framework.Scenes
// } // }
/// <summary> /// <summary>
/// Get a named prim contained in this scene (will return the first /// Get a group via its UUID
/// </summary>
/// <param name="fullID"></param>
/// <returns>null if no group with that name exists</returns>
public SceneObjectGroup GetSceneObjectGroup(UUID fullID)
{
return m_sceneGraph.GetSceneObjectGroup(fullID);
}
/// <summary>
/// Get a group by name from the scene (will return the first
/// found, if there are more than one prim with the same name)
/// </summary>
/// <param name="name"></param>
/// <returns>null if no group with that name exists</returns>
public SceneObjectGroup GetSceneObjectGroup(string name)
{
return m_sceneGraph.GetSceneObjectGroup(name);
}
/// <summary>
/// Get a prim by name from the scene (will return the first
/// found, if there are more than one prim with the same name) /// found, if there are more than one prim with the same name)
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>

View File

@ -321,23 +321,26 @@ namespace OpenSim.Region.Framework.Scenes
/// This method does not send updates to the client - callers need to handle this themselves. /// This method does not send updates to the client - callers need to handle this themselves.
/// <param name="sceneObject"></param> /// <param name="sceneObject"></param>
/// <param name="attachToBackup"></param> /// <param name="attachToBackup"></param>
/// <param name="pos">Position of the object</param> /// <param name="pos">Position of the object. If null then the position stored in the object is used.</param>
/// <param name="rot">Rotation of the object</param> /// <param name="rot">Rotation of the object. If null then the rotation stored in the object is used.</param>
/// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param> /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param>
/// <returns></returns> /// <returns></returns>
public bool AddNewSceneObject( public bool AddNewSceneObject(
SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
{ {
// we set it's position in world. AddNewSceneObject(sceneObject, true, false);
sceneObject.AbsolutePosition = pos;
if (pos != null)
sceneObject.AbsolutePosition = (Vector3)pos;
if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim)
{ {
sceneObject.ClearPartAttachmentData(); sceneObject.ClearPartAttachmentData();
} }
sceneObject.UpdateGroupRotationR(rot); if (rot != null)
sceneObject.UpdateGroupRotationR((Quaternion)rot);
//group.ApplyPhysics(m_physicalPrim); //group.ApplyPhysics(m_physicalPrim);
if (sceneObject.RootPart.PhysActor != null && sceneObject.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) if (sceneObject.RootPart.PhysActor != null && sceneObject.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero)
{ {
@ -357,6 +360,9 @@ namespace OpenSim.Region.Framework.Scenes
/// Add an object to the scene. This will both update the scene, and send information about the /// Add an object to the scene. This will both update the scene, and send information about the
/// new object to all clients interested in the scene. /// new object to all clients interested in the scene.
/// </summary> /// </summary>
/// <remarks>
/// The object's stored position, rotation and velocity are used.
/// </remarks>
/// <param name="sceneObject"></param> /// <param name="sceneObject"></param>
/// <param name="attachToBackup"> /// <param name="attachToBackup">
/// If true, the object is made persistent into the scene. /// If true, the object is made persistent into the scene.
@ -1005,6 +1011,51 @@ namespace OpenSim.Region.Framework.Scenes
return result; return result;
} }
/// <summary>
/// Get a group in the scene
/// </summary>
/// <param name="fullID">UUID of the group</param>
/// <returns>null if no such group was found</returns>
protected internal SceneObjectGroup GetSceneObjectGroup(UUID fullID)
{
lock (SceneObjectGroupsByFullID)
{
if (SceneObjectGroupsByFullID.ContainsKey(fullID))
return SceneObjectGroupsByFullID[fullID];
}
return null;
}
/// <summary>
/// Get a group by name from the scene (will return the first
/// found, if there are more than one prim with the same name)
/// </summary>
/// <param name="name"></param>
/// <returns>null if the part was not found</returns>
protected internal SceneObjectGroup GetSceneObjectGroup(string name)
{
SceneObjectGroup so = null;
Entities.Find(
delegate(EntityBase entity)
{
if (entity is SceneObjectGroup)
{
if (entity.Name == name)
{
so = (SceneObjectGroup)entity;
return true;
}
}
return false;
}
);
return so;
}
/// <summary> /// <summary>
/// Get a part contained in this scene. /// Get a part contained in this scene.
/// </summary> /// </summary>
@ -1019,7 +1070,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// Get a named prim contained in this scene (will return the first /// Get a prim by name from the scene (will return the first
/// found, if there are more than one prim with the same name) /// found, if there are more than one prim with the same name)
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
@ -1488,7 +1539,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// /// Handle a prim description set request from a viewer.
/// </summary> /// </summary>
/// <param name="primLocalID"></param> /// <param name="primLocalID"></param>
/// <param name="description"></param> /// <param name="description"></param>
@ -1505,8 +1556,17 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Set a click action for the prim.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="primLocalID"></param>
/// <param name="clickAction"></param>
protected internal void PrimClickAction(IClientAPI remoteClient, uint primLocalID, string clickAction) protected internal void PrimClickAction(IClientAPI remoteClient, uint primLocalID, string clickAction)
{ {
// m_log.DebugFormat(
// "[SCENEGRAPH]: User {0} set click action for {1} to {2}", remoteClient.Name, primLocalID, clickAction);
SceneObjectGroup group = GetGroupByPrim(primLocalID); SceneObjectGroup group = GetGroupByPrim(primLocalID);
if (group != null) if (group != null)
{ {

View File

@ -471,6 +471,11 @@ namespace OpenSim.Region.Framework.Scenes
#endregion #endregion
// ~SceneObjectGroup()
// {
// m_log.DebugFormat("[SCENE OBJECT GROUP]: Destructor called for {0}, local id {1}", Name, LocalId);
// }
#region Constructors #region Constructors
//DSG SYNC //DSG SYNC
@ -1380,7 +1385,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
if (HasGroupChanged) if (m_scene.UseBackup && HasGroupChanged)
{ {
// don't backup while it's selected or you're asking for changes mid stream. // don't backup while it's selected or you're asking for changes mid stream.
if (isTimeToPersist() || forcedBackup) if (isTimeToPersist() || forcedBackup)
@ -1489,19 +1494,25 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart part in partList) foreach (SceneObjectPart part in partList)
{ {
SceneObjectPart newPart;
if (part.UUID != m_rootPart.UUID) if (part.UUID != m_rootPart.UUID)
{ {
SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed);
newPart.LinkNum = part.LinkNum; newPart.LinkNum = part.LinkNum;
} }
else
{
newPart = dupe.m_rootPart;
}
// Need to duplicate the physics actor as well // Need to duplicate the physics actor as well
if (part.PhysActor != null && userExposed) if (part.PhysActor != null && userExposed)
{ {
PrimitiveBaseShape pbs = part.Shape; PrimitiveBaseShape pbs = part.Shape;
part.PhysActor newPart.PhysActor
= m_scene.PhysicsScene.AddPrimShape( = m_scene.PhysicsScene.AddPrimShape(
part.LocalId,
string.Format("{0}/{1}", part.Name, part.UUID), string.Format("{0}/{1}", part.Name, part.UUID),
pbs, pbs,
part.AbsolutePosition, part.AbsolutePosition,
@ -1509,9 +1520,8 @@ namespace OpenSim.Region.Framework.Scenes
part.RotationOffset, part.RotationOffset,
part.PhysActor.IsPhysical); part.PhysActor.IsPhysical);
part.PhysActor.LocalID = part.LocalId; newPart.PhysActor.UUID = part.UUID;
part.PhysActor.UUID = part.UUID; newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
part.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
} }
} }
@ -3958,4 +3968,4 @@ namespace OpenSim.Region.Framework.Scenes
#endregion #endregion
} }
} }

View File

@ -157,11 +157,10 @@ namespace OpenSim.Region.Framework.Scenes
public Vector3 StatusSandboxPos; public Vector3 StatusSandboxPos;
// TODO: This needs to be persisted in next XML version update! [XmlIgnore]
public int[] PayPrice = {-2,-2,-2,-2,-2};
public readonly int[] PayPrice = {-2,-2,-2,-2,-2};
[XmlIgnore]
public PhysicsActor PhysActor public PhysicsActor PhysActor
{ {
get { return m_physActor; } get { return m_physActor; }
@ -391,6 +390,13 @@ namespace OpenSim.Region.Framework.Scenes
#endregion Fields #endregion Fields
// ~SceneObjectPart()
// {
// m_log.DebugFormat(
// "[SCENE OBJECT PART]: Destructor called for {0}, local id {1}, parent {2} {3}",
// Name, LocalId, ParentGroup.Name, ParentGroup.LocalId);
// }
#region Constructors #region Constructors
/// <summary> /// <summary>
@ -1640,7 +1646,6 @@ namespace OpenSim.Region.Framework.Scenes
{ {
PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
PhysActor.SOPDescription = this.Description; PhysActor.SOPDescription = this.Description;
PhysActor.LocalID = LocalId;
PhysActor.UUID = UUID; PhysActor.UUID = UUID;
DoPhysicsPropertyUpdate(RigidBody, true); DoPhysicsPropertyUpdate(RigidBody, true);
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
@ -4517,7 +4522,6 @@ namespace OpenSim.Region.Framework.Scenes
pa = PhysActor; pa = PhysActor;
if (pa != null) if (pa != null)
{ {
pa.LocalID = LocalId;
pa.UUID = this.UUID; pa.UUID = this.UUID;
DoPhysicsPropertyUpdate(UsePhysics, true); DoPhysicsPropertyUpdate(UsePhysics, true);
if (m_parentGroup != null) if (m_parentGroup != null)

View File

@ -121,7 +121,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
} }
/// <summary> /// <summary>
/// Serialize a scene object to the original xml format /// Serialize a scene object to the original xml format
/// </summary> /// </summary>
@ -341,6 +340,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl); m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl);
m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation); m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation);
m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
m_SOPXmlProcessors.Add("PayPrice0", ProcessPayPrice0);
m_SOPXmlProcessors.Add("PayPrice1", ProcessPayPrice1);
m_SOPXmlProcessors.Add("PayPrice2", ProcessPayPrice2);
m_SOPXmlProcessors.Add("PayPrice3", ProcessPayPrice3);
m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4);
#endregion #endregion
#region TaskInventoryXmlProcessors initialization #region TaskInventoryXmlProcessors initialization
@ -570,7 +574,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
{ {
obj.Shape = ReadShape(reader, "Shape"); bool errors = false;
obj.Shape = ReadShape(reader, "Shape", out errors);
if (errors)
m_log.DebugFormat(
"[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors. Please see earlier log entries.",
obj.Name, obj.UUID);
} }
private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
@ -704,6 +714,31 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
obj.ParticleSystem = Convert.FromBase64String(reader.ReadElementContentAsString("ParticleSystem", String.Empty)); obj.ParticleSystem = Convert.FromBase64String(reader.ReadElementContentAsString("ParticleSystem", String.Empty));
} }
private static void ProcessPayPrice0(SceneObjectPart obj, XmlTextReader reader)
{
obj.PayPrice[0] = (int)reader.ReadElementContentAsInt("PayPrice0", String.Empty);
}
private static void ProcessPayPrice1(SceneObjectPart obj, XmlTextReader reader)
{
obj.PayPrice[1] = (int)reader.ReadElementContentAsInt("PayPrice1", String.Empty);
}
private static void ProcessPayPrice2(SceneObjectPart obj, XmlTextReader reader)
{
obj.PayPrice[2] = (int)reader.ReadElementContentAsInt("PayPrice2", String.Empty);
}
private static void ProcessPayPrice3(SceneObjectPart obj, XmlTextReader reader)
{
obj.PayPrice[3] = (int)reader.ReadElementContentAsInt("PayPrice3", String.Empty);
}
private static void ProcessPayPrice4(SceneObjectPart obj, XmlTextReader reader)
{
obj.PayPrice[4] = (int)reader.ReadElementContentAsInt("PayPrice4", String.Empty);
}
#endregion #endregion
#region TaskInventoryXmlProcessors #region TaskInventoryXmlProcessors
@ -1075,7 +1110,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
shp.Media = PrimitiveBaseShape.MediaList.FromXml(value); shp.Media = PrimitiveBaseShape.MediaList.FromXml(value);
} }
#endregion #endregion
////////// Write ///////// ////////// Write /////////
@ -1142,7 +1176,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture)); writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture));
writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture)); writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture));
writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture)); writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture));
writer.WriteElementString("A", sop.Color.G.ToString(Utils.EnUsCulture)); writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture));
writer.WriteEndElement(); writer.WriteEndElement();
writer.WriteElementString("Text", sop.Text); writer.WriteElementString("Text", sop.Text);
@ -1181,6 +1215,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
WriteBytes(writer, "TextureAnimation", sop.TextureAnimation); WriteBytes(writer, "TextureAnimation", sop.TextureAnimation);
WriteBytes(writer, "ParticleSystem", sop.ParticleSystem); WriteBytes(writer, "ParticleSystem", sop.ParticleSystem);
writer.WriteElementString("PayPrice0", sop.PayPrice[0].ToString());
writer.WriteElementString("PayPrice1", sop.PayPrice[1].ToString());
writer.WriteElementString("PayPrice2", sop.PayPrice[2].ToString());
writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString());
writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString());
writer.WriteEndElement(); writer.WriteEndElement();
} }
@ -1448,7 +1487,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing {0}: {1}", nodeName, e); m_log.DebugFormat(
"[SceneObjectSerializer]: exception while parsing {0} in object {1} {2}: {3}{4}",
obj.Name, obj.UUID, nodeName, e.Message, e.StackTrace);
if (reader.NodeType == XmlNodeType.EndElement) if (reader.NodeType == XmlNodeType.EndElement)
reader.Read(); reader.Read();
} }
@ -1508,10 +1549,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
return tinv; return tinv;
} }
/// <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>
//DSG SYNC: make it public to be called outside //DSG SYNC: make it public to be called outside
//static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name) //static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name) public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
{ {
errors = false;
PrimitiveBaseShape shape = new PrimitiveBaseShape(); PrimitiveBaseShape shape = new PrimitiveBaseShape();
if (reader.IsEmptyElement) if (reader.IsEmptyElement)
@ -1536,7 +1586,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing Shape {0}: {1}", nodeName, e); errors = true;
m_log.DebugFormat(
"[SceneObjectSerializer]: exception while parsing Shape property {0}: {1}{2}",
nodeName, e.Message, e.StackTrace);
if (reader.NodeType == XmlNodeType.EndElement) if (reader.NodeType == XmlNodeType.EndElement)
reader.Read(); reader.Read();
} }

View File

@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {

View File

@ -37,7 +37,6 @@ using OpenSim.Framework;
using OpenSim.Framework.Communications; using OpenSim.Framework.Communications;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {

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