Merge branch 'master' of git://opensimulator.org/git/opensim

dsg
Dan Lake 2011-03-29 14:58:23 -07:00
commit 396ea3ba65
162 changed files with 4284 additions and 3828 deletions

View File

@ -28,7 +28,7 @@ people that make the day to day of OpenSim happen.
* Diva (Crista Lopes, University of California, Irvine) * Diva (Crista Lopes, University of California, Irvine)
* nlin (3Di) * nlin (3Di)
* Arthur Rodrigo S Valadares (IBM) * Arthur Rodrigo S Valadares (IBM)
* BlueWall (James Hughes)
= Past Open Sim Developers = = Past Open Sim Developers =
These folks are alumns of the OpenSim core group, but are now These folks are alumns of the OpenSim core group, but are now
@ -117,6 +117,7 @@ what it is today.
* SachaMagne * SachaMagne
* Salahzar Stenvaag * Salahzar Stenvaag
* sempuki * sempuki
* SignpostMarv
* Snoopy * Snoopy
* Strawberry Fride * Strawberry Fride
* tglion * tglion

View File

@ -68,7 +68,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
public void Initialise() public void Initialise()
{ {
m_log.Error("[LOADREGIONS]: " + Name + " cannot be default-initialized!"); m_log.Error("[LOAD REGIONS PLUGIN]: " + Name + " cannot be default-initialized!");
throw new PluginNotInitialisedException(Name); throw new PluginNotInitialisedException(Name);
} }
@ -85,46 +85,46 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
IRegionLoader regionLoader; IRegionLoader regionLoader;
if (m_openSim.ConfigSource.Source.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem") if (m_openSim.ConfigSource.Source.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
{ {
m_log.Info("[LOADREGIONS]: Loading region configurations from filesystem"); m_log.Info("[LOAD REGIONS PLUGIN]: Loading region configurations from filesystem");
regionLoader = new RegionLoaderFileSystem(); regionLoader = new RegionLoaderFileSystem();
} }
else else
{ {
m_log.Info("[LOADREGIONSPLUGIN]: Loading region configurations from web"); m_log.Info("[LOAD REGIONS PLUGIN]: Loading region configurations from web");
regionLoader = new RegionLoaderWebServer(); regionLoader = new RegionLoaderWebServer();
} }
m_log.Info("[LOADREGIONSPLUGIN]: Loading region configurations...");
regionLoader.SetIniConfigSource(m_openSim.ConfigSource.Source); regionLoader.SetIniConfigSource(m_openSim.ConfigSource.Source);
RegionInfo[] regionsToLoad = regionLoader.LoadRegions(); RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
m_log.Info("[LOADREGIONSPLUGIN]: Loading specific shared modules..."); m_log.Info("[LOAD REGIONS PLUGIN]: Loading specific shared modules...");
m_log.Info("[LOADREGIONSPLUGIN]: DynamicTextureModule..."); m_log.Info("[LOAD REGIONS PLUGIN]: DynamicTextureModule...");
m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule()); m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule());
m_log.Info("[LOADREGIONSPLUGIN]: LoadImageURLModule..."); m_log.Info("[LOAD REGIONS PLUGIN]: LoadImageURLModule...");
m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule()); m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule());
m_log.Info("[LOADREGIONSPLUGIN]: XMLRPCModule..."); m_log.Info("[LOAD REGIONS PLUGIN]: XMLRPCModule...");
m_openSim.ModuleLoader.LoadDefaultSharedModule(new XMLRPCModule()); m_openSim.ModuleLoader.LoadDefaultSharedModule(new XMLRPCModule());
// m_log.Info("[LOADREGIONSPLUGIN]: AssetTransactionModule..."); // m_log.Info("[LOADREGIONSPLUGIN]: AssetTransactionModule...");
// m_openSim.ModuleLoader.LoadDefaultSharedModule(new AssetTransactionModule()); // m_openSim.ModuleLoader.LoadDefaultSharedModule(new AssetTransactionModule());
m_log.Info("[LOADREGIONSPLUGIN]: Done."); m_log.Info("[LOAD REGIONS PLUGIN]: Done.");
if (!CheckRegionsForSanity(regionsToLoad)) if (!CheckRegionsForSanity(regionsToLoad))
{ {
m_log.Error("[LOADREGIONS]: Halting startup due to conflicts in region configurations"); m_log.Error("[LOAD REGIONS PLUGIN]: Halting startup due to conflicts in region configurations");
Environment.Exit(1); Environment.Exit(1);
} }
for (int i = 0; i < regionsToLoad.Length; i++) for (int i = 0; i < regionsToLoad.Length; i++)
{ {
IScene scene; IScene scene;
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + m_log.Debug("[LOAD REGIONS PLUGIN]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
Thread.CurrentThread.ManagedThreadId.ToString() + Thread.CurrentThread.ManagedThreadId.ToString() +
")"); ")");
m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]); m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
m_openSim.CreateRegion(regionsToLoad[i], true, out scene); m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
regionsToLoad[i].EstateSettings.Save(); regionsToLoad[i].EstateSettings.Save();
if (scene != null) if (scene != null)
{ {
m_newRegionCreatedHandler = OnNewRegionCreated; m_newRegionCreatedHandler = OnNewRegionCreated;
@ -162,7 +162,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
if (regions[i].RegionID == regions[j].RegionID) if (regions[i].RegionID == regions[j].RegionID)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[LOADREGIONS]: Regions {0} and {1} have the same UUID {2}", "[LOAD REGIONS PLUGIN]: Regions {0} and {1} have the same UUID {2}",
regions[i].RegionName, regions[j].RegionName, regions[i].RegionID); regions[i].RegionName, regions[j].RegionName, regions[i].RegionID);
return false; return false;
} }
@ -170,14 +170,14 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
regions[i].RegionLocX == regions[j].RegionLocX && regions[i].RegionLocY == regions[j].RegionLocY) regions[i].RegionLocX == regions[j].RegionLocX && regions[i].RegionLocY == regions[j].RegionLocY)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[LOADREGIONS]: Regions {0} and {1} have the same grid location ({2}, {3})", "[LOAD REGIONS PLUGIN]: Regions {0} and {1} have the same grid location ({2}, {3})",
regions[i].RegionName, regions[j].RegionName, regions[i].RegionLocX, regions[i].RegionLocY); regions[i].RegionName, regions[j].RegionName, regions[i].RegionLocX, regions[i].RegionLocY);
return false; return false;
} }
else if (regions[i].InternalEndPoint.Port == regions[j].InternalEndPoint.Port) else if (regions[i].InternalEndPoint.Port == regions[j].InternalEndPoint.Port)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[LOADREGIONS]: Regions {0} and {1} have the same internal IP port {2}", "[LOAD REGIONS PLUGIN]: Regions {0} and {1} have the same internal IP port {2}",
regions[i].RegionName, regions[j].RegionName, regions[i].InternalEndPoint.Port); regions[i].RegionName, regions[j].RegionName, regions[i].InternalEndPoint.Port);
return false; return false;
} }

View File

@ -44,7 +44,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// private static readonly int PARM_PATH = 1; // private static readonly int PARM_PATH = 1;
private bool enabled = false; // private bool enabled = false;
private string qPrefix = "appearance"; private string qPrefix = "appearance";
/// <summary> /// <summary>
@ -74,7 +74,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// Activate if everything went OK // Activate if everything went OK
enabled = true; // enabled = true;
Rest.Log.InfoFormat("{0} User appearance services initialization complete", MsgId); Rest.Log.InfoFormat("{0} User appearance services initialization complete", MsgId);
} }
@ -95,7 +95,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public void Close() public void Close()
{ {
enabled = false; // enabled = false;
Rest.Log.InfoFormat("{0} User appearance services closing down", MsgId); Rest.Log.InfoFormat("{0} User appearance services closing down", MsgId);
} }

View File

@ -46,12 +46,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public class RestInventoryServices : IRest public class RestInventoryServices : IRest
{ {
// private static readonly int PARM_USERID = 0; // private static readonly int PARM_USERID = 0;
private static readonly int PARM_PATH = 1; // private static readonly int PARM_PATH = 1;
// private bool enabled = false; // private bool enabled = false;
private string qPrefix = "inventory"; private string qPrefix = "inventory";
private static readonly string PRIVATE_ROOT_NAME = "My Inventory"; // private static readonly string PRIVATE_ROOT_NAME = "My Inventory";
/// <summary> /// <summary>
/// The constructor makes sure that the service prefix is absolute /// The constructor makes sure that the service prefix is absolute
@ -2129,17 +2129,17 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
} }
catch (DllNotFoundException) catch (DllNotFoundException)
{ {
Rest.Log.ErrorFormat("OpenJpeg is not installed correctly on this system. Asset Data is emtpy for {0}", ic.Item.Name); Rest.Log.ErrorFormat("OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", ic.Item.Name);
ic.Asset.Data = new Byte[0]; ic.Asset.Data = new Byte[0];
} }
catch (IndexOutOfRangeException) catch (IndexOutOfRangeException)
{ {
Rest.Log.ErrorFormat("OpenJpeg was unable to encode this. Asset Data is emtpy for {0}", ic.Item.Name); Rest.Log.ErrorFormat("OpenJpeg was unable to encode this. Asset Data is empty for {0}", ic.Item.Name);
ic.Asset.Data = new Byte[0]; ic.Asset.Data = new Byte[0];
} }
catch (Exception) catch (Exception)
{ {
Rest.Log.ErrorFormat("OpenJpeg was unable to encode this. Asset Data is emtpy for {0}", ic.Item.Name); Rest.Log.ErrorFormat("OpenJpeg was unable to encode this. Asset Data is empty for {0}", ic.Item.Name);
ic.Asset.Data = new Byte[0]; ic.Asset.Data = new Byte[0];
} }
} }

View File

@ -350,26 +350,43 @@ namespace OpenSim.Data.MSSQL
public EstateSettings LoadEstateSettings(int estateID) public EstateSettings LoadEstateSettings(int estateID)
{ {
// TODO: Implementation!
return new EstateSettings(); return new EstateSettings();
} }
public List<EstateSettings> LoadEstateSettingsAll()
{
// TODO: Implementation!
return new List<EstateSettings>();
}
public List<int> GetEstates(string search) public List<int> GetEstates(string search)
{ {
// TODO: Implementation!
return new List<int>();
}
public List<int> GetEstatesAll()
{
// TODO: Implementation!
return new List<int>(); return new List<int>();
} }
public bool LinkRegion(UUID regionID, int estateID) public bool LinkRegion(UUID regionID, int estateID)
{ {
// TODO: Implementation!
return false; return false;
} }
public List<UUID> GetRegions(int estateID) public List<UUID> GetRegions(int estateID)
{ {
// TODO: Implementation!
return new List<UUID>(); return new List<UUID>();
} }
public bool DeleteEstate(int estateID) public bool DeleteEstate(int estateID)
{ {
// TODO: Implementation!
return false; return false;
} }
#endregion #endregion

View File

@ -47,6 +47,11 @@ namespace OpenSim.Data.MySQL
private string m_connectionString; private string m_connectionString;
private object m_dbLock = new object(); private object m_dbLock = new object();
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
#region IPlugin Members #region IPlugin Members
public override string Version { get { return "1.0.0.0"; } } public override string Version { get { return "1.0.0.0"; } }
@ -66,13 +71,10 @@ namespace OpenSim.Data.MySQL
{ {
m_connectionString = connect; m_connectionString = connect;
// This actually does the roll forward assembly stuff
Assembly assem = GetType().Assembly;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, assem, "AssetStore"); Migration m = new Migration(dbcon, Assembly, "AssetStore");
m.Update(); m.Update();
} }
} }

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Data; using System.Data;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
@ -42,6 +43,11 @@ namespace OpenSim.Data.MySQL
private int m_LastExpire; private int m_LastExpire;
// private string m_connectionString; // private string m_connectionString;
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
public MySqlAuthenticationData(string connectionString, string realm) public MySqlAuthenticationData(string connectionString, string realm)
: base(connectionString) : base(connectionString)
{ {
@ -51,7 +57,7 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, GetType().Assembly, "AuthStore"); Migration m = new Migration(dbcon, Assembly, "AuthStore");
m.Update(); m.Update();
} }
} }

View File

@ -54,6 +54,11 @@ namespace OpenSim.Data.MySQL
private Dictionary<string, FieldInfo> m_FieldMap = private Dictionary<string, FieldInfo> m_FieldMap =
new Dictionary<string, FieldInfo>(); new Dictionary<string, FieldInfo>();
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
public MySQLEstateStore() public MySQLEstateStore()
{ {
} }
@ -82,8 +87,7 @@ namespace OpenSim.Data.MySQL
{ {
dbcon.Open(); dbcon.Open();
Assembly assem = GetType().Assembly; Migration m = new Migration(dbcon, Assembly, "EstateStore");
Migration m = new Migration(dbcon, assem, "EstateStore");
m.Update(); m.Update();
Type t = typeof(EstateSettings); Type t = typeof(EstateSettings);
@ -409,6 +413,46 @@ namespace OpenSim.Data.MySQL
return DoLoad(cmd, UUID.Zero, false); return DoLoad(cmd, UUID.Zero, false);
} }
} }
public List<EstateSettings> LoadEstateSettingsAll()
{
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
List<int> allEstateIds = GetEstatesAll();
foreach (int estateId in allEstateIds)
allEstateSettings.Add(LoadEstateSettings(estateId));
return allEstateSettings;
}
public List<int> GetEstatesAll()
{
List<int> result = new List<int>();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select estateID from estate_settings";
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(Convert.ToInt32(reader["EstateID"]));
}
reader.Close();
}
}
dbcon.Close();
}
return result;
}
public List<int> GetEstates(string search) public List<int> GetEstates(string search)
{ {

View File

@ -46,6 +46,11 @@ namespace OpenSim.Data.MySQL
protected string m_Realm; protected string m_Realm;
protected FieldInfo m_DataField = null; protected FieldInfo m_DataField = null;
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
public MySQLGenericTableHandler(string connectionString, public MySQLGenericTableHandler(string connectionString,
string realm, string storeName) : base(connectionString) string realm, string storeName) : base(connectionString)
{ {
@ -57,7 +62,7 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, GetType().Assembly, storeName); Migration m = new Migration(dbcon, Assembly, storeName);
m.Update(); m.Update();
} }
} }

View File

@ -29,6 +29,8 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Reflection;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Data; using OpenSim.Data;
@ -42,6 +44,11 @@ namespace OpenSim.Data.MySQL
private List<string> m_ColumnNames; private List<string> m_ColumnNames;
//private string m_connectionString; //private string m_connectionString;
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
public MySqlRegionData(string connectionString, string realm) public MySqlRegionData(string connectionString, string realm)
: base(connectionString) : base(connectionString)
{ {
@ -51,7 +58,7 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
Migration m = new Migration(dbcon, GetType().Assembly, "GridStore"); Migration m = new Migration(dbcon, Assembly, "GridStore");
m.Update(); m.Update();
} }
} }

View File

@ -52,6 +52,11 @@ namespace OpenSim.Data.MySQL
private string m_connectionString; private string m_connectionString;
private object m_dbLock = new object(); private object m_dbLock = new object();
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
public MySQLSimulationData() public MySQLSimulationData()
{ {
} }
@ -71,8 +76,7 @@ namespace OpenSim.Data.MySQL
// Apply new Migrations // Apply new Migrations
// //
Assembly assem = GetType().Assembly; Migration m = new Migration(dbcon, Assembly, "RegionStore");
Migration m = new Migration(dbcon, assem, "RegionStore");
m.Update(); m.Update();
// Clean dropped attachments // Clean dropped attachments

View File

@ -51,27 +51,55 @@ namespace OpenSim.Data.Null
//Console.WriteLine("[XXX] NullRegionData constructor"); //Console.WriteLine("[XXX] NullRegionData constructor");
} }
private delegate bool Matcher(string value);
public List<RegionData> Get(string regionName, UUID scopeID) public List<RegionData> Get(string regionName, UUID scopeID)
{ {
if (Instance != this) if (Instance != this)
return Instance.Get(regionName, scopeID); return Instance.Get(regionName, scopeID);
string cleanName = regionName.ToLower();
// Handle SQL wildcards
const string wildcard = "%";
bool wildcardPrefix = false;
bool wildcardSuffix = false;
if (cleanName.Equals(wildcard))
{
wildcardPrefix = wildcardSuffix = true;
cleanName = string.Empty;
}
else
{
if (cleanName.StartsWith(wildcard))
{
wildcardPrefix = true;
cleanName = cleanName.Substring(1);
}
if (regionName.EndsWith(wildcard))
{
wildcardSuffix = true;
cleanName = cleanName.Remove(cleanName.Length - 1);
}
}
Matcher queryMatch;
if (wildcardPrefix && wildcardSuffix)
queryMatch = delegate(string s) { return s.Contains(cleanName); };
else if (wildcardSuffix)
queryMatch = delegate(string s) { return s.StartsWith(cleanName); };
else if (wildcardPrefix)
queryMatch = delegate(string s) { return s.EndsWith(cleanName); };
else
queryMatch = delegate(string s) { return s.Equals(cleanName); };
// Find region data
List<RegionData> ret = new List<RegionData>(); List<RegionData> ret = new List<RegionData>();
foreach (RegionData r in m_regionData.Values) foreach (RegionData r in m_regionData.Values)
{ {
if (regionName.Contains("%")) m_log.DebugFormat("[NULL REGION DATA]: comparing {0} to {1}", cleanName, r.RegionName.ToLower());
{ if (queryMatch(r.RegionName.ToLower()))
string cleanname = regionName.Replace("%", "");
m_log.DebugFormat("[NULL REGION DATA]: comparing {0} to {1}", cleanname.ToLower(), r.RegionName.ToLower());
if (r.RegionName.ToLower().Contains(cleanname.ToLower()))
ret.Add(r); ret.Add(r);
}
else
{
if (r.RegionName.ToLower() == regionName.ToLower())
ret.Add(r);
}
} }
if (ret.Count > 0) if (ret.Count > 0)

View File

@ -28,6 +28,9 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Text;
using log4net;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Data; using OpenSim.Data;
@ -36,12 +39,17 @@ namespace OpenSim.Data.Null
{ {
public class NullUserAccountData : IUserAccountData public class NullUserAccountData : IUserAccountData
{ {
private static Dictionary<UUID, UserAccountData> m_DataByUUID = new Dictionary<UUID, UserAccountData>(); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<string, UserAccountData> m_DataByName = new Dictionary<string, UserAccountData>();
private static Dictionary<string, UserAccountData> m_DataByEmail = new Dictionary<string, UserAccountData>(); private Dictionary<UUID, UserAccountData> m_DataByUUID = new Dictionary<UUID, UserAccountData>();
private Dictionary<string, UserAccountData> m_DataByName = new Dictionary<string, UserAccountData>();
private Dictionary<string, UserAccountData> m_DataByEmail = new Dictionary<string, UserAccountData>();
public NullUserAccountData(string connectionString, string realm) public NullUserAccountData(string connectionString, string realm)
{ {
// m_log.DebugFormat(
// "[NULL USER ACCOUNT DATA]: Initializing new NullUserAccountData with connectionString [{0}], realm [{1}]",
// connectionString, realm);
} }
/// <summary> /// <summary>
@ -54,6 +62,15 @@ namespace OpenSim.Data.Null
/// <returns></returns> /// <returns></returns>
public UserAccountData[] Get(string[] fields, string[] values) public UserAccountData[] Get(string[] fields, string[] values)
{ {
// if (m_log.IsDebugEnabled)
// {
// m_log.DebugFormat(
// "[NULL USER ACCOUNT DATA]: Called Get with fields [{0}], values [{1}]",
// string.Join(", ", fields), string.Join(", ", values));
// }
UserAccountData[] userAccounts = new UserAccountData[0];
List<string> fieldsLst = new List<string>(fields); List<string> fieldsLst = new List<string>(fields);
if (fieldsLst.Contains("PrincipalID")) if (fieldsLst.Contains("PrincipalID"))
{ {
@ -61,41 +78,61 @@ namespace OpenSim.Data.Null
UUID id = UUID.Zero; UUID id = UUID.Zero;
if (UUID.TryParse(values[i], out id)) if (UUID.TryParse(values[i], out id))
if (m_DataByUUID.ContainsKey(id)) if (m_DataByUUID.ContainsKey(id))
return new UserAccountData[] { m_DataByUUID[id] }; userAccounts = new UserAccountData[] { m_DataByUUID[id] };
} }
if (fieldsLst.Contains("FirstName") && fieldsLst.Contains("LastName")) else if (fieldsLst.Contains("FirstName") && fieldsLst.Contains("LastName"))
{ {
int findex = fieldsLst.IndexOf("FirstName"); int findex = fieldsLst.IndexOf("FirstName");
int lindex = fieldsLst.IndexOf("LastName"); int lindex = fieldsLst.IndexOf("LastName");
if (m_DataByName.ContainsKey(values[findex] + " " + values[lindex])) if (m_DataByName.ContainsKey(values[findex] + " " + values[lindex]))
return new UserAccountData[] { m_DataByName[values[findex] + " " + values[lindex]] }; {
} userAccounts = new UserAccountData[] { m_DataByName[values[findex] + " " + values[lindex]] };
if (fieldsLst.Contains("Email")) }
}
else if (fieldsLst.Contains("Email"))
{ {
int i = fieldsLst.IndexOf("Email"); int i = fieldsLst.IndexOf("Email");
if (m_DataByEmail.ContainsKey(values[i])) if (m_DataByEmail.ContainsKey(values[i]))
return new UserAccountData[] { m_DataByEmail[values[i]] }; userAccounts = new UserAccountData[] { m_DataByEmail[values[i]] };
} }
// Fail // if (m_log.IsDebugEnabled)
return new UserAccountData[0]; // {
// StringBuilder sb = new StringBuilder();
// foreach (UserAccountData uad in userAccounts)
// sb.AppendFormat("({0} {1} {2}) ", uad.FirstName, uad.LastName, uad.PrincipalID);
//
// m_log.DebugFormat(
// "[NULL USER ACCOUNT DATA]: Returning {0} user accounts out of {1}: [{2}]", userAccounts.Length, m_DataByName.Count, sb);
// }
return userAccounts;
} }
public bool Store(UserAccountData data) public bool Store(UserAccountData data)
{ {
if (data == null) if (data == null)
return false; return false;
m_log.DebugFormat(
"[NULL USER ACCOUNT DATA]: Storing user account {0} {1} {2} {3}",
data.FirstName, data.LastName, data.PrincipalID, this.GetHashCode());
m_DataByUUID[data.PrincipalID] = data; m_DataByUUID[data.PrincipalID] = data;
m_DataByName[data.FirstName + " " + data.LastName] = data; m_DataByName[data.FirstName + " " + data.LastName] = data;
if (data.Data.ContainsKey("Email") && data.Data["Email"] != null && data.Data["Email"] != string.Empty) if (data.Data.ContainsKey("Email") && data.Data["Email"] != null && data.Data["Email"] != string.Empty)
m_DataByEmail[data.Data["Email"]] = data; m_DataByEmail[data.Data["Email"]] = data;
// m_log.DebugFormat("m_DataByUUID count is {0}, m_DataByName count is {1}", m_DataByUUID.Count, m_DataByName.Count);
return true; return true;
} }
public UserAccountData[] GetUsers(UUID scopeID, string query) public UserAccountData[] GetUsers(UUID scopeID, string query)
{ {
// m_log.DebugFormat(
// "[NULL USER ACCOUNT DATA]: Called GetUsers with scope [{0}], query [{1}]", scopeID, query);
string[] words = query.Split(new char[] { ' ' }); string[] words = query.Split(new char[] { ' ' });
for (int i = 0; i < words.Length; i++) for (int i = 0; i < words.Length; i++)

View File

@ -357,6 +357,17 @@ namespace OpenSim.Data.SQLite
return DoLoad(cmd, UUID.Zero, false); return DoLoad(cmd, UUID.Zero, false);
} }
public List<EstateSettings> LoadEstateSettingsAll()
{
List<EstateSettings> estateSettings = new List<EstateSettings>();
List<int> estateIds = GetEstatesAll();
foreach (int estateId in estateIds)
estateSettings.Add(LoadEstateSettings(estateId));
return estateSettings;
}
public List<int> GetEstates(string search) public List<int> GetEstates(string search)
{ {
@ -379,6 +390,27 @@ namespace OpenSim.Data.SQLite
return result; return result;
} }
public List<int> GetEstatesAll()
{
List<int> result = new List<int>();
string sql = "select EstateID from estate_settings";
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
cmd.CommandText = sql;
IDataReader r = cmd.ExecuteReader();
while (r.Read())
{
result.Add(Convert.ToInt32(r["EstateID"]));
}
r.Close();
return result;
}
public bool LinkRegion(UUID regionID, int estateID) public bool LinkRegion(UUID regionID, int estateID)
{ {

View File

@ -669,10 +669,6 @@ namespace OpenSim.Data.SQLite
} }
} }
/// <summary>
///
/// </summary>
/// <param name="globalID"></param>
public void RemoveLandObject(UUID globalID) public void RemoveLandObject(UUID globalID)
{ {
lock (ds) lock (ds)
@ -698,7 +694,6 @@ namespace OpenSim.Data.SQLite
if (landRow != null) if (landRow != null)
{ {
landRow.Delete(); landRow.Delete();
land.Rows.Remove(landRow);
} }
List<DataRow> rowsToDelete = new List<DataRow>(); List<DataRow> rowsToDelete = new List<DataRow>();
foreach (DataRow rowToCheck in landaccesslist.Rows) foreach (DataRow rowToCheck in landaccesslist.Rows)
@ -709,7 +704,6 @@ namespace OpenSim.Data.SQLite
for (int iter = 0; iter < rowsToDelete.Count; iter++) for (int iter = 0; iter < rowsToDelete.Count; iter++)
{ {
rowsToDelete[iter].Delete(); rowsToDelete[iter].Delete();
landaccesslist.Rows.Remove(rowsToDelete[iter]);
} }
} }
Commit(); Commit();

View File

@ -100,6 +100,17 @@ namespace OpenSim.Data.SQLiteLegacy
return DoLoad(cmd, regionID, create); return DoLoad(cmd, regionID, create);
} }
public List<EstateSettings> LoadEstateSettingsAll()
{
List<EstateSettings> estateSettings = new List<EstateSettings>();
List<int> estateIds = GetEstatesAll();
foreach (int estateId in estateIds)
estateSettings.Add(LoadEstateSettings(estateId));
return estateSettings;
}
private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create) private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create)
{ {
@ -369,6 +380,28 @@ namespace OpenSim.Data.SQLiteLegacy
return result; return result;
} }
public List<int> GetEstatesAll()
{
List<int> result = new List<int>();
string sql = "select EstateID from estate_settings";
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
cmd.CommandText = sql;
IDataReader r = cmd.ExecuteReader();
while (r.Read())
{
result.Add(Convert.ToInt32(r["EstateID"]));
}
r.Close();
return result;
}
public bool LinkRegion(UUID regionID, int estateID) public bool LinkRegion(UUID regionID, int estateID)
{ {
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();

View File

@ -32,13 +32,10 @@ using NUnit.Framework;
using NUnit.Framework.Constraints; using NUnit.Framework.Constraints;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Tests.Common;
using System.Data.Common; using System.Data.Common;
using log4net; using log4net;
#if !NUNIT25
using NUnit.Framework.SyntaxHelpers;
#endif
// DBMS-specific: // DBMS-specific:
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using OpenSim.Data.MySQL; using OpenSim.Data.MySQL;
@ -51,15 +48,6 @@ using OpenSim.Data.SQLite;
namespace OpenSim.Data.Tests namespace OpenSim.Data.Tests
{ {
#if NUNIT25
[TestFixture(typeof(MySqlConnection), typeof(MySQLAssetData), Description="Basic Asset store tests (MySQL)")]
[TestFixture(typeof(SqlConnection), typeof(MSSQLAssetData), Description = "Basic Asset store tests (MS SQL Server)")]
[TestFixture(typeof(SqliteConnection), typeof(SQLiteAssetData), Description = "Basic Asset store tests (SQLite)")]
#else
[TestFixture(Description = "Asset store tests (SQLite)")] [TestFixture(Description = "Asset store tests (SQLite)")]
public class SQLiteAssetTests : AssetTests<SqliteConnection, SQLiteAssetData> public class SQLiteAssetTests : AssetTests<SqliteConnection, SQLiteAssetData>
{ {
@ -75,9 +63,6 @@ namespace OpenSim.Data.Tests
{ {
} }
#endif
public class AssetTests<TConn, TAssetData> : BasicDataServiceTest<TConn, TAssetData> public class AssetTests<TConn, TAssetData> : BasicDataServiceTest<TConn, TAssetData>
where TConn : DbConnection, new() where TConn : DbConnection, new()
where TAssetData : AssetDataBase, new() where TAssetData : AssetDataBase, new()
@ -121,6 +106,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T001_LoadEmpty() public void T001_LoadEmpty()
{ {
TestHelper.InMethod();
Assert.That(m_db.ExistsAsset(uuid1), Is.False); Assert.That(m_db.ExistsAsset(uuid1), Is.False);
Assert.That(m_db.ExistsAsset(uuid2), Is.False); Assert.That(m_db.ExistsAsset(uuid2), Is.False);
Assert.That(m_db.ExistsAsset(uuid3), Is.False); Assert.That(m_db.ExistsAsset(uuid3), Is.False);
@ -129,6 +116,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T010_StoreReadVerifyAssets() public void T010_StoreReadVerifyAssets()
{ {
TestHelper.InMethod();
AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, critter1.ToString()); AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, critter1.ToString());
AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture, critter2.ToString()); AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture, critter2.ToString());
AssetBase a3 = new AssetBase(uuid3, "asset three", (sbyte)AssetType.Texture, critter3.ToString()); AssetBase a3 = new AssetBase(uuid3, "asset three", (sbyte)AssetType.Texture, critter3.ToString());
@ -194,6 +183,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T020_CheckForWeirdCreatorID() public void T020_CheckForWeirdCreatorID()
{ {
TestHelper.InMethod();
// It is expected that eventually the CreatorID might be an arbitrary string (an URI) // It is expected that eventually the CreatorID might be an arbitrary string (an URI)
// rather than a valid UUID (?). This test is to make sure that the database layer does not // rather than a valid UUID (?). This test is to make sure that the database layer does not
// attempt to convert CreatorID to GUID, but just passes it both ways as a string. // attempt to convert CreatorID to GUID, but just passes it both ways as a string.
@ -218,4 +209,4 @@ namespace OpenSim.Data.Tests
Assert.That(a3a, Constraints.PropertyCompareConstraint(a3)); Assert.That(a3a, Constraints.PropertyCompareConstraint(a3));
} }
} }
} }

View File

@ -28,10 +28,10 @@
using System; using System;
using log4net.Config; using log4net.Config;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Tests.Common;
using System.Text; using System.Text;
using log4net; using log4net;
using System.Reflection; using System.Reflection;
@ -49,15 +49,6 @@ using OpenSim.Data.SQLite;
namespace OpenSim.Data.Tests namespace OpenSim.Data.Tests
{ {
#if NUNIT25
[TestFixture(typeof(MySqlConnection), typeof(MySQLEstateStore), Description = "Estate store tests (MySQL)")]
[TestFixture(typeof(SqlConnection), typeof(MSSQLEstateStore), Description = "Estate store tests (MS SQL Server)")]
[TestFixture(typeof(SqliteConnection), typeof(SQLiteEstateStore), Description = "Estate store tests (SQLite)")]
#else
[TestFixture(Description = "Estate store tests (SQLite)")] [TestFixture(Description = "Estate store tests (SQLite)")]
public class SQLiteEstateTests : EstateTests<SqliteConnection, SQLiteEstateStore> public class SQLiteEstateTests : EstateTests<SqliteConnection, SQLiteEstateStore>
{ {
@ -73,8 +64,6 @@ namespace OpenSim.Data.Tests
{ {
} }
#endif
public class EstateTests<TConn, TEstateStore> : BasicDataServiceTest<TConn, TEstateStore> public class EstateTests<TConn, TEstateStore> : BasicDataServiceTest<TConn, TEstateStore>
where TConn : DbConnection, new() where TConn : DbConnection, new()
where TEstateStore : class, IEstateDataStore, new() where TEstateStore : class, IEstateDataStore, new()
@ -118,6 +107,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T010_EstateSettingsSimpleStorage_MinimumParameterSet() public void T010_EstateSettingsSimpleStorage_MinimumParameterSet()
{ {
TestHelper.InMethod();
EstateSettingsSimpleStorage( EstateSettingsSimpleStorage(
REGION_ID, REGION_ID,
DataTestUtil.STRING_MIN, DataTestUtil.STRING_MIN,
@ -149,6 +140,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T011_EstateSettingsSimpleStorage_MaximumParameterSet() public void T011_EstateSettingsSimpleStorage_MaximumParameterSet()
{ {
TestHelper.InMethod();
EstateSettingsSimpleStorage( EstateSettingsSimpleStorage(
REGION_ID, REGION_ID,
DataTestUtil.STRING_MAX(64), DataTestUtil.STRING_MAX(64),
@ -180,6 +173,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T012_EstateSettingsSimpleStorage_AccurateParameterSet() public void T012_EstateSettingsSimpleStorage_AccurateParameterSet()
{ {
TestHelper.InMethod();
EstateSettingsSimpleStorage( EstateSettingsSimpleStorage(
REGION_ID, REGION_ID,
DataTestUtil.STRING_MAX(1), DataTestUtil.STRING_MAX(1),
@ -211,6 +206,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T012_EstateSettingsRandomStorage() public void T012_EstateSettingsRandomStorage()
{ {
TestHelper.InMethod();
// Letting estate store generate rows to database for us // Letting estate store generate rows to database for us
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
new PropertyScrambler<EstateSettings>() new PropertyScrambler<EstateSettings>()
@ -230,6 +227,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T020_EstateSettingsManagerList() public void T020_EstateSettingsManagerList()
{ {
TestHelper.InMethod();
// Letting estate store generate rows to database for us // Letting estate store generate rows to database for us
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
@ -249,6 +248,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T021_EstateSettingsUserList() public void T021_EstateSettingsUserList()
{ {
TestHelper.InMethod();
// Letting estate store generate rows to database for us // Letting estate store generate rows to database for us
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
@ -268,6 +269,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T022_EstateSettingsGroupList() public void T022_EstateSettingsGroupList()
{ {
TestHelper.InMethod();
// Letting estate store generate rows to database for us // Letting estate store generate rows to database for us
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
@ -287,6 +290,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T022_EstateSettingsBanList() public void T022_EstateSettingsBanList()
{ {
TestHelper.InMethod();
// Letting estate store generate rows to database for us // Letting estate store generate rows to database for us
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
@ -520,6 +525,5 @@ namespace OpenSim.Data.Tests
} }
#endregion #endregion
} }
} }

View File

@ -25,14 +25,12 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
// #define NUNIT25
using System; using System;
using log4net.Config; using log4net.Config;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Tests.Common;
using log4net; using log4net;
using System.Reflection; using System.Reflection;
using System.Data.Common; using System.Data.Common;
@ -49,14 +47,6 @@ using OpenSim.Data.SQLite;
namespace OpenSim.Data.Tests namespace OpenSim.Data.Tests
{ {
#if NUNIT25
[TestFixture(typeof(SqliteConnection), typeof(SQLiteInventoryStore), Description = "Inventory store tests (SQLite)")]
[TestFixture(typeof(MySqlConnection), typeof(MySQLInventoryData), Description = "Inventory store tests (MySQL)")]
[TestFixture(typeof(SqlConnection), typeof(MSSQLInventoryData), Description = "Inventory store tests (MS SQL Server)")]
#else
[TestFixture(Description = "Inventory store tests (SQLite)")] [TestFixture(Description = "Inventory store tests (SQLite)")]
public class SQLiteInventoryTests : InventoryTests<SqliteConnection, SQLiteInventoryStore> public class SQLiteInventoryTests : InventoryTests<SqliteConnection, SQLiteInventoryStore>
{ {
@ -71,7 +61,6 @@ namespace OpenSim.Data.Tests
public class MSSQLInventoryTests : InventoryTests<SqlConnection, MSSQLInventoryData> public class MSSQLInventoryTests : InventoryTests<SqlConnection, MSSQLInventoryData>
{ {
} }
#endif
public class InventoryTests<TConn, TInvStore> : BasicDataServiceTest<TConn, TInvStore> public class InventoryTests<TConn, TInvStore> : BasicDataServiceTest<TConn, TInvStore>
where TConn : DbConnection, new() where TConn : DbConnection, new()
@ -125,6 +114,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T001_LoadEmpty() public void T001_LoadEmpty()
{ {
TestHelper.InMethod();
Assert.That(db.getInventoryFolder(zero), Is.Null); Assert.That(db.getInventoryFolder(zero), Is.Null);
Assert.That(db.getInventoryFolder(folder1), Is.Null); Assert.That(db.getInventoryFolder(folder1), Is.Null);
Assert.That(db.getInventoryFolder(folder2), Is.Null); Assert.That(db.getInventoryFolder(folder2), Is.Null);
@ -143,6 +134,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T010_FolderNonParent() public void T010_FolderNonParent()
{ {
TestHelper.InMethod();
InventoryFolderBase f1 = NewFolder(folder2, folder1, owner1, name2); InventoryFolderBase f1 = NewFolder(folder2, folder1, owner1, name2);
// the folder will go in // the folder will go in
db.addInventoryFolder(f1); db.addInventoryFolder(f1);
@ -153,6 +146,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T011_FolderCreate() public void T011_FolderCreate()
{ {
TestHelper.InMethod();
InventoryFolderBase f1 = NewFolder(folder1, zero, owner1, name1); InventoryFolderBase f1 = NewFolder(folder1, zero, owner1, name1);
// TODO: this is probably wrong behavior, but is what we have // TODO: this is probably wrong behavior, but is what we have
// db.updateInventoryFolder(f1); // db.updateInventoryFolder(f1);
@ -165,7 +160,7 @@ namespace OpenSim.Data.Tests
db.addInventoryFolder(f1); db.addInventoryFolder(f1);
InventoryFolderBase f1a = db.getUserRootFolder(owner1); InventoryFolderBase f1a = db.getUserRootFolder(owner1);
Assert.That(folder1, Is.EqualTo(f1a.ID), "Assert.That(folder1, Is.EqualTo(f1a.ID))"); Assert.That(folder1, Is.EqualTo(f1a.ID), "Assert.That(folder1, Is.EqualTo(f1a.ID))");
Assert.That(name1, Text.Matches(f1a.Name), "Assert.That(name1, Text.Matches(f1a.Name))"); Assert.That(name1, Is.StringMatching(f1a.Name), "Assert.That(name1, Text.Matches(f1a.Name))");
} }
// we now have the following tree // we now have the following tree
@ -176,6 +171,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T012_FolderList() public void T012_FolderList()
{ {
TestHelper.InMethod();
InventoryFolderBase f2 = NewFolder(folder3, folder1, owner1, name3); InventoryFolderBase f2 = NewFolder(folder3, folder1, owner1, name3);
db.addInventoryFolder(f2); db.addInventoryFolder(f2);
@ -190,6 +187,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T013_FolderHierarchy() public void T013_FolderHierarchy()
{ {
TestHelper.InMethod();
int n = db.getFolderHierarchy(zero).Count; // (for dbg - easier to see what's returned) int n = db.getFolderHierarchy(zero).Count; // (for dbg - easier to see what's returned)
Assert.That(n, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))"); Assert.That(n, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))");
n = db.getFolderHierarchy(folder1).Count; n = db.getFolderHierarchy(folder1).Count;
@ -203,6 +202,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T014_MoveFolder() public void T014_MoveFolder()
{ {
TestHelper.InMethod();
InventoryFolderBase f2 = db.getInventoryFolder(folder2); InventoryFolderBase f2 = db.getInventoryFolder(folder2);
f2.ParentID = folder3; f2.ParentID = folder3;
db.moveInventoryFolder(f2); db.moveInventoryFolder(f2);
@ -217,6 +218,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T015_FolderHierarchy() public void T015_FolderHierarchy()
{ {
TestHelper.InMethod();
Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))"); Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))");
Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2), "Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2))"); Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2), "Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2))");
Assert.That(db.getFolderHierarchy(folder2).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(folder2).Count, Is.EqualTo(0))"); Assert.That(db.getFolderHierarchy(folder2).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(folder2).Count, Is.EqualTo(0))");
@ -228,6 +231,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T100_NoItems() public void T100_NoItems()
{ {
TestHelper.InMethod();
Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0))"); Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0))");
Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0))"); Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0))");
Assert.That(db.getInventoryInFolder(folder2).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder2).Count, Is.EqualTo(0))"); Assert.That(db.getInventoryInFolder(folder2).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder2).Count, Is.EqualTo(0))");
@ -240,6 +245,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T101_CreatItems() public void T101_CreatItems()
{ {
TestHelper.InMethod();
db.addInventoryItem(NewItem(item1, folder3, owner1, iname1, asset1)); db.addInventoryItem(NewItem(item1, folder3, owner1, iname1, asset1));
db.addInventoryItem(NewItem(item2, folder3, owner1, iname2, asset2)); db.addInventoryItem(NewItem(item2, folder3, owner1, iname2, asset2));
db.addInventoryItem(NewItem(item3, folder3, owner1, iname3, asset3)); db.addInventoryItem(NewItem(item3, folder3, owner1, iname3, asset3));
@ -249,6 +256,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T102_CompareItems() public void T102_CompareItems()
{ {
TestHelper.InMethod();
InventoryItemBase i1 = db.getInventoryItem(item1); InventoryItemBase i1 = db.getInventoryItem(item1);
InventoryItemBase i2 = db.getInventoryItem(item2); InventoryItemBase i2 = db.getInventoryItem(item2);
InventoryItemBase i3 = db.getInventoryItem(item3); InventoryItemBase i3 = db.getInventoryItem(item3);
@ -266,6 +275,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T103_UpdateItem() public void T103_UpdateItem()
{ {
TestHelper.InMethod();
// TODO: probably shouldn't have the ability to have an // TODO: probably shouldn't have the ability to have an
// owner of an item in a folder not owned by the user // owner of an item in a folder not owned by the user
@ -284,6 +295,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T104_RandomUpdateItem() public void T104_RandomUpdateItem()
{ {
TestHelper.InMethod();
PropertyScrambler<InventoryFolderBase> folderScrambler = PropertyScrambler<InventoryFolderBase> folderScrambler =
new PropertyScrambler<InventoryFolderBase>() new PropertyScrambler<InventoryFolderBase>()
.DontScramble(x => x.Owner) .DontScramble(x => x.Owner)
@ -341,6 +354,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T999_StillNull() public void T999_StillNull()
{ {
TestHelper.InMethod();
// After all tests are run, these should still return no results // After all tests are run, these should still return no results
Assert.That(db.getInventoryFolder(zero), Is.Null); Assert.That(db.getInventoryFolder(zero), Is.Null);
Assert.That(db.getInventoryItem(zero), Is.Null); Assert.That(db.getInventoryItem(zero), Is.Null);

View File

@ -34,7 +34,6 @@ using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.Constraints; using NUnit.Framework.Constraints;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;

View File

@ -32,13 +32,11 @@ using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
namespace OpenSim.Data.Tests namespace OpenSim.Data.Tests
{ {
//This is generic so that the lambda expressions will work right in IDEs. //This is generic so that the lambda expressions will work right in IDEs.
public class PropertyScrambler<T> public class PropertyScrambler<T>
{ {

View File

@ -31,11 +31,11 @@ using System.Drawing;
using System.Text; using System.Text;
using log4net.Config; using log4net.Config;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using log4net; using log4net;
using System.Reflection; using System.Reflection;
using System.Data.Common; using System.Data.Common;
@ -52,14 +52,6 @@ using OpenSim.Data.SQLite;
namespace OpenSim.Data.Tests namespace OpenSim.Data.Tests
{ {
#if NUNIT25
[TestFixture(typeof(SqliteConnection), typeof(SQLiteRegionData), Description = "Region store tests (SQLite)")]
[TestFixture(typeof(MySqlConnection), typeof(MySqlRegionData), Description = "Region store tests (MySQL)")]
[TestFixture(typeof(SqlConnection), typeof(MSSQLRegionData), Description = "Region store tests (MS SQL Server)")]
#else
[TestFixture(Description = "Region store tests (SQLite)")] [TestFixture(Description = "Region store tests (SQLite)")]
public class SQLiteRegionTests : RegionTests<SqliteConnection, SQLiteSimulationData> public class SQLiteRegionTests : RegionTests<SqliteConnection, SQLiteSimulationData>
{ {
@ -75,8 +67,6 @@ namespace OpenSim.Data.Tests
{ {
} }
#endif
public class RegionTests<TConn, TRegStore> : BasicDataServiceTest<TConn, TRegStore> public class RegionTests<TConn, TRegStore> : BasicDataServiceTest<TConn, TRegStore>
where TConn : DbConnection, new() where TConn : DbConnection, new()
where TRegStore : class, ISimulationDataStore, new() where TRegStore : class, ISimulationDataStore, new()
@ -131,15 +121,18 @@ namespace OpenSim.Data.Tests
string[] reg_tables = new string[] { string[] reg_tables = new string[] {
"prims", "primshapes", "primitems", "terrain", "land", "landaccesslist", "regionban", "regionsettings" "prims", "primshapes", "primitems", "terrain", "land", "landaccesslist", "regionban", "regionsettings"
}; };
if (m_rebuildDB) if (m_rebuildDB)
{ {
DropTables(reg_tables); DropTables(reg_tables);
ResetMigrations("RegionStore"); ResetMigrations("RegionStore");
}else }
else
{
ClearTables(reg_tables); ClearTables(reg_tables);
}
} }
// Test Plan // Test Plan
// Prims // Prims
// - empty test - 001 // - empty test - 001
@ -158,6 +151,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T001_LoadEmpty() public void T001_LoadEmpty()
{ {
TestHelper.InMethod();
List<SceneObjectGroup> objs = db.LoadObjects(region1); List<SceneObjectGroup> objs = db.LoadObjects(region1);
List<SceneObjectGroup> objs3 = db.LoadObjects(region3); List<SceneObjectGroup> objs3 = db.LoadObjects(region3);
List<LandData> land = db.LoadLandObjects(region1); List<LandData> land = db.LoadLandObjects(region1);
@ -174,6 +169,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T010_StoreSimpleObject() public void T010_StoreSimpleObject()
{ {
TestHelper.InMethod();
SceneObjectGroup sog = NewSOG("object1", prim1, region1); SceneObjectGroup sog = NewSOG("object1", prim1, region1);
SceneObjectGroup sog2 = NewSOG("object2", prim2, region1); SceneObjectGroup sog2 = NewSOG("object2", prim2, region1);
@ -207,6 +204,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T011_ObjectNames() public void T011_ObjectNames()
{ {
TestHelper.InMethod();
List<SceneObjectGroup> objs = db.LoadObjects(region1); List<SceneObjectGroup> objs = db.LoadObjects(region1);
foreach (SceneObjectGroup sog in objs) foreach (SceneObjectGroup sog in objs)
{ {
@ -219,6 +218,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T012_SceneParts() public void T012_SceneParts()
{ {
TestHelper.InMethod();
UUID tmp0 = UUID.Random(); UUID tmp0 = UUID.Random();
UUID tmp1 = UUID.Random(); UUID tmp1 = UUID.Random();
UUID tmp2 = UUID.Random(); UUID tmp2 = UUID.Random();
@ -252,6 +253,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T013_DatabasePersistency() public void T013_DatabasePersistency()
{ {
TestHelper.InMethod();
// Sets all ScenePart parameters, stores and retrieves them, then check for consistency with initial data // Sets all ScenePart parameters, stores and retrieves them, then check for consistency with initial data
// The commented Asserts are the ones that are unchangeable (when storing on the database, their "Set" values are ignored // The commented Asserts are the ones that are unchangeable (when storing on the database, their "Set" values are ignored
// The ObjectFlags is an exception, if it is entered incorrectly, the object IS REJECTED on the database silently. // The ObjectFlags is an exception, if it is entered incorrectly, the object IS REJECTED on the database silently.
@ -427,6 +430,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T014_UpdateObject() public void T014_UpdateObject()
{ {
TestHelper.InMethod();
string text1 = "object1 text"; string text1 = "object1 text";
SceneObjectGroup sog = FindSOG("object1", region1); SceneObjectGroup sog = FindSOG("object1", region1);
sog.RootPart.Text = text1; sog.RootPart.Text = text1;
@ -528,15 +533,20 @@ namespace OpenSim.Data.Tests
Assert.That(clickaction,Is.EqualTo(p.ClickAction), "Assert.That(clickaction,Is.EqualTo(p.ClickAction))"); Assert.That(clickaction,Is.EqualTo(p.ClickAction), "Assert.That(clickaction,Is.EqualTo(p.ClickAction))");
Assert.That(scale,Is.EqualTo(p.Scale), "Assert.That(scale,Is.EqualTo(p.Scale))"); Assert.That(scale,Is.EqualTo(p.Scale), "Assert.That(scale,Is.EqualTo(p.Scale))");
} }
/// <summary>
/// Test storage and retrieval of a scene object with a large number of parts.
/// </summary>
[Test] [Test]
public void T015_LargeSceneObjects() public void T015_LargeSceneObjects()
{ {
TestHelper.InMethod();
UUID id = UUID.Random(); UUID id = UUID.Random();
Dictionary<UUID, SceneObjectPart> mydic = new Dictionary<UUID, SceneObjectPart>(); Dictionary<UUID, SceneObjectPart> mydic = new Dictionary<UUID, SceneObjectPart>();
SceneObjectGroup sog = NewSOG("Test SOG", id, region4); SceneObjectGroup sog = NewSOG("Test SOG", id, region4);
mydic.Add(sog.RootPart.UUID,sog.RootPart); mydic.Add(sog.RootPart.UUID,sog.RootPart);
for (int i=0;i<30;i++) for (int i = 0; i < 30; i++)
{ {
UUID tmp = UUID.Random(); UUID tmp = UUID.Random();
SceneObjectPart sop = NewSOP(("Test SOP " + i.ToString()),tmp); SceneObjectPart sop = NewSOP(("Test SOP " + i.ToString()),tmp);
@ -555,13 +565,14 @@ namespace OpenSim.Data.Tests
sop.Acceleration = accel; sop.Acceleration = accel;
mydic.Add(tmp,sop); mydic.Add(tmp,sop);
sog.AddPart(sop); sog.AddPart(sop);
db.StoreObject(sog, region4);
} }
db.StoreObject(sog, region4);
SceneObjectGroup retsog = FindSOG("Test SOG", region4); SceneObjectGroup retsog = FindSOG("Test SOG", region4);
SceneObjectPart[] parts = retsog.Parts; SceneObjectPart[] parts = retsog.Parts;
for (int i=0;i<30;i++) for (int i = 0; i < 30; i++)
{ {
SceneObjectPart cursop = mydic[parts[i].UUID]; SceneObjectPart cursop = mydic[parts[i].UUID];
Assert.That(cursop.GroupPosition,Is.EqualTo(parts[i].GroupPosition), "Assert.That(cursop.GroupPosition,Is.EqualTo(parts[i].GroupPosition))"); Assert.That(cursop.GroupPosition,Is.EqualTo(parts[i].GroupPosition), "Assert.That(cursop.GroupPosition,Is.EqualTo(parts[i].GroupPosition))");
@ -576,6 +587,8 @@ namespace OpenSim.Data.Tests
//[Test] //[Test]
public void T016_RandomSogWithSceneParts() public void T016_RandomSogWithSceneParts()
{ {
TestHelper.InMethod();
PropertyScrambler<SceneObjectPart> scrambler = PropertyScrambler<SceneObjectPart> scrambler =
new PropertyScrambler<SceneObjectPart>() new PropertyScrambler<SceneObjectPart>()
.DontScramble(x => x.UUID); .DontScramble(x => x.UUID);
@ -642,15 +655,16 @@ namespace OpenSim.Data.Tests
return sog; return sog;
} }
// NOTE: it is a bad practice to rely on some of the previous tests having been run before. // NOTE: it is a bad practice to rely on some of the previous tests having been run before.
// If the tests are run manually, one at a time, each starts with full class init (DB cleared). // If the tests are run manually, one at a time, each starts with full class init (DB cleared).
// Even when all tests are run, NUnit 2.5+ no longer guarantee a specific test order. // Even when all tests are run, NUnit 2.5+ no longer guarantee a specific test order.
// We shouldn't expect to find anything in the DB if we haven't put it there *in the same test*! // We shouldn't expect to find anything in the DB if we haven't put it there *in the same test*!
[Test] [Test]
public void T020_PrimInventoryEmpty() public void T020_PrimInventoryEmpty()
{ {
TestHelper.InMethod();
SceneObjectGroup sog = GetMySOG("object1"); SceneObjectGroup sog = GetMySOG("object1");
TaskInventoryItem t = sog.GetInventoryItem(sog.RootPart.LocalId, item1); TaskInventoryItem t = sog.GetInventoryItem(sog.RootPart.LocalId, item1);
Assert.That(t, Is.Null); Assert.That(t, Is.Null);
@ -670,10 +684,11 @@ namespace OpenSim.Data.Tests
db.StorePrimInventory(sog.RootPart.UUID, list); db.StorePrimInventory(sog.RootPart.UUID, list);
} }
[Test] [Test]
public void T021_PrimInventoryBasic() public void T021_PrimInventoryBasic()
{ {
TestHelper.InMethod();
SceneObjectGroup sog = GetMySOG("object1"); SceneObjectGroup sog = GetMySOG("object1");
InventoryItemBase i = NewItem(item1, zero, zero, itemname1, zero); InventoryItemBase i = NewItem(item1, zero, zero, itemname1, zero);
@ -701,20 +716,19 @@ namespace OpenSim.Data.Tests
Assert.That(t2.Name, Is.EqualTo("My New Name"), "Assert.That(t.Name, Is.EqualTo(\"My New Name\"))"); Assert.That(t2.Name, Is.EqualTo("My New Name"), "Assert.That(t.Name, Is.EqualTo(\"My New Name\"))");
// Removing inventory // Removing inventory
List<TaskInventoryItem> list = new List<TaskInventoryItem>(); List<TaskInventoryItem> list = new List<TaskInventoryItem>();
db.StorePrimInventory(prim1, list); db.StorePrimInventory(prim1, list);
sog = FindSOG("object1", region1); sog = FindSOG("object1", region1);
t = sog.GetInventoryItem(sog.RootPart.LocalId, item1); t = sog.GetInventoryItem(sog.RootPart.LocalId, item1);
Assert.That(t, Is.Null); Assert.That(t, Is.Null);
} }
[Test] [Test]
public void T025_PrimInventoryPersistency() public void T025_PrimInventoryPersistency()
{ {
TestHelper.InMethod();
InventoryItemBase i = new InventoryItemBase(); InventoryItemBase i = new InventoryItemBase();
UUID id = UUID.Random(); UUID id = UUID.Random();
i.ID = id; i.ID = id;
@ -786,6 +800,8 @@ namespace OpenSim.Data.Tests
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void T026_PrimInventoryMany() public void T026_PrimInventoryMany()
{ {
TestHelper.InMethod();
UUID i1,i2,i3,i4; UUID i1,i2,i3,i4;
i1 = UUID.Random(); i1 = UUID.Random();
i2 = UUID.Random(); i2 = UUID.Random();
@ -816,15 +832,18 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T052_RemoveObject() public void T052_RemoveObject()
{ {
TestHelper.InMethod();
db.RemoveObject(prim1, region1); db.RemoveObject(prim1, region1);
SceneObjectGroup sog = FindSOG("object1", region1); SceneObjectGroup sog = FindSOG("object1", region1);
Assert.That(sog, Is.Null); Assert.That(sog, Is.Null);
} }
[Test] [Test]
public void T100_DefaultRegionInfo() public void T100_DefaultRegionInfo()
{ {
TestHelper.InMethod();
RegionSettings r1 = db.LoadRegionSettings(region1); RegionSettings r1 = db.LoadRegionSettings(region1);
Assert.That(r1.RegionUUID, Is.EqualTo(region1), "Assert.That(r1.RegionUUID, Is.EqualTo(region1))"); Assert.That(r1.RegionUUID, Is.EqualTo(region1), "Assert.That(r1.RegionUUID, Is.EqualTo(region1))");
@ -835,6 +854,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T101_UpdateRegionInfo() public void T101_UpdateRegionInfo()
{ {
TestHelper.InMethod();
int agentlimit = random.Next(); int agentlimit = random.Next();
double objectbonus = random.Next(); double objectbonus = random.Next();
int maturity = random.Next(); int maturity = random.Next();
@ -933,13 +954,14 @@ namespace OpenSim.Data.Tests
//Assert.That(r1a.TerrainImageID,Is.EqualTo(terimgid), "Assert.That(r1a.TerrainImageID,Is.EqualTo(terimgid))"); //Assert.That(r1a.TerrainImageID,Is.EqualTo(terimgid), "Assert.That(r1a.TerrainImageID,Is.EqualTo(terimgid))");
Assert.That(r1a.FixedSun,Is.True); Assert.That(r1a.FixedSun,Is.True);
Assert.That(r1a.SunPosition, Is.EqualTo(sunpos), "Assert.That(r1a.SunPosition, Is.EqualTo(sunpos))"); Assert.That(r1a.SunPosition, Is.EqualTo(sunpos), "Assert.That(r1a.SunPosition, Is.EqualTo(sunpos))");
Assert.That(r1a.Covenant, Is.EqualTo(cov), "Assert.That(r1a.Covenant, Is.EqualTo(cov))"); Assert.That(r1a.Covenant, Is.EqualTo(cov), "Assert.That(r1a.Covenant, Is.EqualTo(cov))");
} }
[Test] [Test]
public void T300_NoTerrain() public void T300_NoTerrain()
{ {
TestHelper.InMethod();
Assert.That(db.LoadTerrain(zero), Is.Null); Assert.That(db.LoadTerrain(zero), Is.Null);
Assert.That(db.LoadTerrain(region1), Is.Null); Assert.That(db.LoadTerrain(region1), Is.Null);
Assert.That(db.LoadTerrain(region2), Is.Null); Assert.That(db.LoadTerrain(region2), Is.Null);
@ -949,6 +971,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T301_CreateTerrain() public void T301_CreateTerrain()
{ {
TestHelper.InMethod();
double[,] t1 = GenTerrain(height1); double[,] t1 = GenTerrain(height1);
db.StoreTerrain(t1, region1); db.StoreTerrain(t1, region1);
@ -961,6 +985,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T302_FetchTerrain() public void T302_FetchTerrain()
{ {
TestHelper.InMethod();
double[,] baseterrain1 = GenTerrain(height1); double[,] baseterrain1 = GenTerrain(height1);
double[,] baseterrain2 = GenTerrain(height2); double[,] baseterrain2 = GenTerrain(height2);
double[,] t1 = db.LoadTerrain(region1); double[,] t1 = db.LoadTerrain(region1);
@ -971,6 +997,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T303_UpdateTerrain() public void T303_UpdateTerrain()
{ {
TestHelper.InMethod();
double[,] baseterrain1 = GenTerrain(height1); double[,] baseterrain1 = GenTerrain(height1);
double[,] baseterrain2 = GenTerrain(height2); double[,] baseterrain2 = GenTerrain(height2);
db.StoreTerrain(baseterrain2, region1); db.StoreTerrain(baseterrain2, region1);
@ -983,6 +1011,8 @@ namespace OpenSim.Data.Tests
[Test] [Test]
public void T400_EmptyLand() public void T400_EmptyLand()
{ {
TestHelper.InMethod();
Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0))"); Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0))");
Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0))"); Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0))");
Assert.That(db.LoadLandObjects(region2).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region2).Count, Is.EqualTo(0))"); Assert.That(db.LoadLandObjects(region2).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region2).Count, Is.EqualTo(0))");
@ -1018,25 +1048,12 @@ namespace OpenSim.Data.Tests
return true; return true;
} }
private SceneObjectGroup FindSOG(string name, UUID r) private SceneObjectGroup FindSOG(string name, UUID r)
{ {
List<SceneObjectGroup> objs = db.LoadObjects(r); List<SceneObjectGroup> objs = db.LoadObjects(r);
foreach (SceneObjectGroup sog in objs) foreach (SceneObjectGroup sog in objs)
{ if (sog.Name == name)
SceneObjectPart p = sog.RootPart;
if (p.Name == name) {
RegionInfo regionInfo = new RegionInfo();
regionInfo.RegionID = r;
regionInfo.RegionLocX = 0;
regionInfo.RegionLocY = 0;
Scene scene = new Scene(regionInfo);
sog.SetScene(scene);
return sog; return sog;
}
}
return null; return null;
} }

View File

@ -220,6 +220,8 @@ namespace OpenSim.Framework
args["packed_appearance"] = appmap; args["packed_appearance"] = appmap;
} }
// Old, bad way. Keeping it fow now for backwards compatibility
// OBSOLETE -- soon to be deleted
if (ServiceURLs != null && ServiceURLs.Count > 0) if (ServiceURLs != null && ServiceURLs.Count > 0)
{ {
OSDArray urls = new OSDArray(ServiceURLs.Count * 2); OSDArray urls = new OSDArray(ServiceURLs.Count * 2);
@ -232,6 +234,19 @@ namespace OpenSim.Framework
args["service_urls"] = urls; args["service_urls"] = urls;
} }
// again, this time the right way
if (ServiceURLs != null && ServiceURLs.Count > 0)
{
OSDMap urls = new OSDMap();
foreach (KeyValuePair<string, object> kvp in ServiceURLs)
{
//System.Console.WriteLine("XXX " + kvp.Key + "=" + kvp.Value);
urls[kvp.Key] = OSD.FromString((kvp.Value == null) ? string.Empty : kvp.Value.ToString());
}
args["serviceurls"] = urls;
}
return args; return args;
} }
@ -327,7 +342,20 @@ namespace OpenSim.Framework
} }
ServiceURLs = new Dictionary<string, object>(); ServiceURLs = new Dictionary<string, object>();
if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array) // Try parse the new way, OSDMap
if (args.ContainsKey("serviceurls") && args["serviceurls"] != null && (args["serviceurls"]).Type == OSDType.Map)
{
OSDMap urls = (OSDMap)(args["serviceurls"]);
foreach (KeyValuePair<String, OSD> kvp in urls)
{
ServiceURLs[kvp.Key] = kvp.Value.AsString();
//System.Console.WriteLine("XXX " + kvp.Key + "=" + ServiceURLs[kvp.Key]);
}
}
// else try the old way, OSDArray
// OBSOLETE -- soon to be deleted
else if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array)
{ {
OSDArray urls = (OSDArray)(args["service_urls"]); OSDArray urls = (OSDArray)(args["service_urls"]);
for (int i = 0; i < urls.Count / 2; i++) for (int i = 0; i < urls.Count / 2; i++)

View File

@ -181,7 +181,6 @@ namespace OpenSim.Framework.Capabilities
RegisterRegionServiceHandlers(capsBase); RegisterRegionServiceHandlers(capsBase);
RegisterInventoryServiceHandlers(capsBase); RegisterInventoryServiceHandlers(capsBase);
} }
public void RegisterRegionServiceHandlers(string capsBase) public void RegisterRegionServiceHandlers(string capsBase)

View File

@ -88,8 +88,8 @@ namespace OpenSim.Framework.Capabilities
/// handler to be removed</param> /// handler to be removed</param>
public void Remove(string capsName) public void Remove(string capsName)
{ {
// This line must be here, or caps will break!
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path); m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName); m_capsHandlers.Remove(capsName);
} }

View File

@ -250,7 +250,7 @@ namespace OpenSim.Framework
{ {
get get
{ {
//m_log.DebugFormat("[SHAPE]: get m_textureEntry length {0}", m_textureEntry.Length); // m_log.DebugFormat("[SHAPE]: get m_textureEntry length {0}", m_textureEntry.Length);
try { return new Primitive.TextureEntry(m_textureEntry, 0, m_textureEntry.Length); } try { return new Primitive.TextureEntry(m_textureEntry, 0, m_textureEntry.Length); }
catch { } catch { }

View File

@ -25,15 +25,19 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using log4net;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection;
using Nini.Config; using Nini.Config;
namespace OpenSim.Framework.RegionLoader.Filesystem namespace OpenSim.Framework.RegionLoader.Filesystem
{ {
public class RegionLoaderFileSystem : IRegionLoader public class RegionLoaderFileSystem : IRegionLoader
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IConfigSource m_configSource; private IConfigSource m_configSource;
public void SetIniConfigSource(IConfigSource configSource) public void SetIniConfigSource(IConfigSource configSource)
@ -63,36 +67,48 @@ namespace OpenSim.Framework.RegionLoader.Filesystem
string[] configFiles = Directory.GetFiles(regionConfigPath, "*.xml"); string[] configFiles = Directory.GetFiles(regionConfigPath, "*.xml");
string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini"); string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
// Create an empty Regions.ini if there are no existing config files.
if (configFiles.Length == 0 && iniFiles.Length == 0) if (configFiles.Length == 0 && iniFiles.Length == 0)
{ {
new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource); new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource);
iniFiles = Directory.GetFiles(regionConfigPath, "*.ini"); iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
} }
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config files from {0}", regionConfigPath);
List<RegionInfo> regionInfos = new List<RegionInfo>(); List<RegionInfo> regionInfos = new List<RegionInfo>();
int i = 0; int i = 0;
foreach (string file in iniFiles) foreach (string file in iniFiles)
{ {
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config file {0}", file);
IConfigSource source = new IniConfigSource(file); IConfigSource source = new IniConfigSource(file);
foreach (IConfig config in source.Configs) foreach (IConfig config in source.Configs)
{ {
//m_log.Info("[REGIONLOADERFILESYSTEM]: Creating RegionInfo for " + config.Name);
RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource, config.Name); RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource, config.Name);
regionInfos.Add(regionInfo); regionInfos.Add(regionInfo);
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loaded config for region {0}", regionInfo.RegionName);
i++; i++;
} }
} }
foreach (string file in configFiles) foreach (string file in configFiles)
{ {
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config file {0}", file);
RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource); RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource);
regionInfos.Add(regionInfo); regionInfos.Add(regionInfo);
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loaded config for region {0}", regionInfo.RegionName);
i++; i++;
} }
return regionInfos.ToArray(); return regionInfos.ToArray();
} }
} }
} }

View File

@ -66,9 +66,9 @@ namespace OpenSim.Framework.RegionLoader.Web
{ {
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url); HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
webRequest.Timeout = 30000; //30 Second Timeout webRequest.Timeout = 30000; //30 Second Timeout
m_log.Debug("[WEBLOADER]: Sending Download Request..."); m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse(); HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
m_log.Debug("[WEBLOADER]: Downloading Region Information From Remote Server..."); m_log.Debug("[WEBLOADER]: Downloading region information...");
StreamReader reader = new StreamReader(webResponse.GetResponseStream()); StreamReader reader = new StreamReader(webResponse.GetResponseStream());
string xmlSource = String.Empty; string xmlSource = String.Empty;
string tempStr = reader.ReadLine(); string tempStr = reader.ReadLine();

View File

@ -66,6 +66,8 @@ namespace OpenSim.Framework.Serialization
UserAccount account = userService.GetUserAccount(UUID.Zero, userId); UserAccount account = userService.GetUserAccount(UUID.Zero, userId);
if (account != null) if (account != null)
return MakeOspa(account.FirstName, account.LastName); return MakeOspa(account.FirstName, account.LastName);
// else
// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId);
return null; return null;
} }
@ -77,6 +79,8 @@ namespace OpenSim.Framework.Serialization
/// <returns></returns> /// <returns></returns>
public static string MakeOspa(string firstName, string lastName) public static string MakeOspa(string firstName, string lastName)
{ {
// m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName);
return return
OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName; OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
} }
@ -97,7 +101,10 @@ namespace OpenSim.Framework.Serialization
public static UUID ResolveOspa(string ospa, IUserAccountService userService) public static UUID ResolveOspa(string ospa, IUserAccountService userService)
{ {
if (!ospa.StartsWith(OSPA_PREFIX)) if (!ospa.StartsWith(OSPA_PREFIX))
return UUID.Zero; {
// m_log.DebugFormat("[OSP RESOLVER]: ResolveOspa() got unrecognized format [{0}]", ospa);
return UUID.Zero;
}
// m_log.DebugFormat("[OSP RESOLVER]: Resolving {0}", ospa); // m_log.DebugFormat("[OSP RESOLVER]: Resolving {0}", ospa);
@ -161,7 +168,17 @@ namespace OpenSim.Framework.Serialization
UserAccount account = userService.GetUserAccount(UUID.Zero, firstName, lastName); UserAccount account = userService.GetUserAccount(UUID.Zero, firstName, lastName);
if (account != null) if (account != null)
{
// m_log.DebugFormat(
// "[OSP RESOLVER]: Found user account with uuid {0} for {1} {2}",
// account.PrincipalID, firstName, lastName);
return account.PrincipalID; return account.PrincipalID;
}
// else
// {
// m_log.DebugFormat("[OSP RESOLVER]: No resolved OSPA user account for {0}", name);
// }
// XXX: Disable temporary user profile creation for now as implementation is incomplete - justincc // XXX: Disable temporary user profile creation for now as implementation is incomplete - justincc
/* /*

View File

@ -303,7 +303,7 @@ namespace OpenSim.Framework.Serialization.External
writer.WriteStartElement("GroupOwned"); writer.WriteStartElement("GroupOwned");
writer.WriteString(inventoryItem.GroupOwned.ToString()); writer.WriteString(inventoryItem.GroupOwned.ToString());
writer.WriteEndElement(); writer.WriteEndElement();
if (inventoryItem.CreatorData != null && inventoryItem.CreatorData != string.Empty) if (options.ContainsKey("creators") && inventoryItem.CreatorData != null && inventoryItem.CreatorData != string.Empty)
writer.WriteElementString("CreatorData", inventoryItem.CreatorData); writer.WriteElementString("CreatorData", inventoryItem.CreatorData);
else if (options.ContainsKey("profile")) else if (options.ContainsKey("profile"))
{ {

View File

@ -319,18 +319,21 @@ namespace OpenSim.Framework.Servers
return; return;
} }
string rawLevel = cmd[3]; if (cmd.Length > 3)
{
ILoggerRepository repository = LogManager.GetRepository(); string rawLevel = cmd[3];
Level consoleLevel = repository.LevelMap[rawLevel];
ILoggerRepository repository = LogManager.GetRepository();
if (consoleLevel != null) Level consoleLevel = repository.LevelMap[rawLevel];
m_consoleAppender.Threshold = consoleLevel;
else if (consoleLevel != null)
Notice( m_consoleAppender.Threshold = consoleLevel;
String.Format( else
"{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF", Notice(
rawLevel)); String.Format(
"{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
rawLevel));
}
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
} }

View File

@ -143,6 +143,11 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
public List<string> GetStreamHandlerKeys()
{
return new List<string>(m_streamHandlers.Keys);
}
private static string GetHandlerKey(string httpMethod, string path) private static string GetHandlerKey(string httpMethod, string path)
{ {
return httpMethod + ":" + path; return httpMethod + ":" + path;
@ -179,6 +184,11 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
} }
public List<string> GetXmlRpcHandlerKeys()
{
return new List<string>(m_rpcHandlers.Keys);
}
public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler) public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler)
{ {
//m_log.DebugFormat("[BASE HTTP SERVER]: Registering {0}", methodName); //m_log.DebugFormat("[BASE HTTP SERVER]: Registering {0}", methodName);
@ -196,6 +206,12 @@ namespace OpenSim.Framework.Servers.HttpServer
return false; return false;
} }
public List<string> GetHTTPHandlerKeys()
{
return new List<string>(m_HTTPHandlers.Keys);
}
public bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args) public bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args)
{ {
bool pollHandlerResult = false; bool pollHandlerResult = false;
@ -214,6 +230,12 @@ namespace OpenSim.Framework.Servers.HttpServer
return false; return false;
} }
public List<string> GetPollServiceHandlerKeys()
{
return new List<string>(m_pollHandlers.Keys);
}
// Note that the agent string is provided simply to differentiate // Note that the agent string is provided simply to differentiate
// the handlers - it is NOT required to be an actual agent header // the handlers - it is NOT required to be an actual agent header
// value. // value.
@ -232,6 +254,11 @@ namespace OpenSim.Framework.Servers.HttpServer
return false; return false;
} }
public List<string> GetAgentHandlerKeys()
{
return new List<string>(m_agentHandlers.Keys);
}
public bool AddLLSDHandler(string path, LLSDMethod handler) public bool AddLLSDHandler(string path, LLSDMethod handler)
{ {
lock (m_llsdHandlers) lock (m_llsdHandlers)
@ -245,6 +272,11 @@ namespace OpenSim.Framework.Servers.HttpServer
return false; return false;
} }
public List<string> GetLLSDHandlerKeys()
{
return new List<string>(m_llsdHandlers.Keys);
}
public bool SetDefaultLLSDHandler(DefaultLLSDMethod handler) public bool SetDefaultLLSDHandler(DefaultLLSDMethod handler)
{ {
m_defaultLlsdHandler = handler; m_defaultLlsdHandler = handler;
@ -346,6 +378,22 @@ namespace OpenSim.Framework.Servers.HttpServer
/// <param name="response"></param> /// <param name="response"></param>
public virtual void HandleRequest(OSHttpRequest request, OSHttpResponse response) public virtual void HandleRequest(OSHttpRequest request, OSHttpResponse response)
{ {
if (request.HttpMethod == String.Empty) // Can't handle empty requests, not wasting a thread
{
try
{
SendHTML500(response);
}
catch
{
}
return;
}
string requestMethod = request.HttpMethod;
string uriString = request.RawUrl;
string reqnum = "unknown"; string reqnum = "unknown";
int tickstart = Environment.TickCount; int tickstart = Environment.TickCount;
@ -463,7 +511,7 @@ namespace OpenSim.Framework.Servers.HttpServer
request.InputStream.Close(); request.InputStream.Close();
// HTTP IN support. The script engine taes it from here // HTTP IN support. The script engine takes it from here
// Nothing to worry about for us. // Nothing to worry about for us.
// //
if (buffer == null) if (buffer == null)
@ -577,19 +625,19 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e); m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e);
} }
catch (InvalidOperationException e) catch (Exception e)
{ {
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e); m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw " + e.ToString());
SendHTML500(response); SendHTML500(response);
} }
finally finally
{ {
// Every month or so this will wrap and give bad numbers, not really a problem // Every month or so this will wrap and give bad numbers, not really a problem
// since its just for reporting, 200ms limit can be adjusted // since its just for reporting, tickdiff limit can be adjusted
int tickdiff = Environment.TickCount - tickstart; int tickdiff = Environment.TickCount - tickstart;
if (tickdiff > 500) if (tickdiff > 3000)
m_log.InfoFormat( m_log.InfoFormat(
"[BASE HTTP SERVER]: slow request <{0}> for {1} took {2} ms", reqnum, request.RawUrl, tickdiff); "[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff);
} }
} }
@ -753,7 +801,19 @@ namespace OpenSim.Framework.Servers.HttpServer
if (methodWasFound) if (methodWasFound)
{ {
xmlRprcRequest.Params.Add(request.Url); // Param[2] xmlRprcRequest.Params.Add(request.Url); // Param[2]
xmlRprcRequest.Params.Add(request.Headers.Get("X-Forwarded-For")); // Param[3]
string xff = "X-Forwarded-For";
string xfflower = xff.ToLower();
foreach (string s in request.Headers.AllKeys)
{
if (s != null && s.Equals(xfflower))
{
xff = xfflower;
break;
}
}
xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3]
try try
{ {

View File

@ -83,7 +83,7 @@ namespace OpenSim.Framework.Servers.HttpServer
/// <summary> /// <summary>
/// Regular expression used to match against path of the /// Regular expression used to match against path of the
/// incoming HTTP request. If you want to match any string /// incoming HTTP request. If you want to match any string
/// either use '.*' or null. To match on the emtpy string use /// either use '.*' or null. To match on the empty string use
/// '^$'. /// '^$'.
/// </summary> /// </summary>
public virtual Regex Path public virtual Regex Path

View File

@ -34,7 +34,6 @@ using System.Text;
using HttpServer; using HttpServer;
using HttpServer.FormDecoders; using HttpServer.FormDecoders;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
namespace OpenSim.Framework.Servers.Tests namespace OpenSim.Framework.Servers.Tests

View File

@ -28,7 +28,6 @@
using System; using System;
using System.Reflection; using System.Reflection;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;

View File

@ -28,7 +28,6 @@
using System; using System;
using System.Reflection; using System.Reflection;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
@ -38,8 +37,6 @@ namespace OpenSim.Framework.Tests
[TestFixture] [TestFixture]
public class PrimeNumberHelperTests public class PrimeNumberHelperTests
{ {
[Test] [Test]
public void TestGetPrime() public void TestGetPrime()
{ {

View File

@ -27,7 +27,6 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;

View File

@ -90,7 +90,7 @@ namespace OpenSim.Framework
return deleted; return deleted;
} }
else else
throw new InvalidOperationException("Cannot pop from emtpy stack"); throw new InvalidOperationException("Cannot pop from empty stack");
} }
public T Peek() public T Peek()

View File

@ -459,10 +459,17 @@ namespace OpenSim.Framework
/// <param name="oldy">Old region y-coord</param> /// <param name="oldy">Old region y-coord</param>
/// <param name="newy">New region y-coord</param> /// <param name="newy">New region y-coord</param>
/// <returns></returns> /// <returns></returns>
public static bool IsOutsideView(uint oldx, uint newx, uint oldy, uint newy) public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy)
{ {
// Eventually this will be a function of the draw distance / camera position too. int dd = (int)((drawdist + Constants.RegionSize - 1) / Constants.RegionSize);
return (((int)Math.Abs((int)(oldx - newx)) > 1) || ((int)Math.Abs((int)(oldy - newy)) > 1));
int startX = (int)oldx - dd;
int startY = (int)oldy - dd;
int endX = (int)oldx + dd;
int endY = (int)oldy + dd;
return (newx < startX || endX < newx || newy < startY || endY < newy);
} }
public static string FieldToString(byte[] bytes) public static string FieldToString(byte[] bytes)
@ -1334,6 +1341,11 @@ namespace OpenSim.Framework
return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri; return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
} }
public static byte[] StringToBytes256(string str, params object[] args)
{
return StringToBytes256(string.Format(str, args));
}
public static byte[] StringToBytes256(string str) public static byte[] StringToBytes256(string str)
{ {
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
@ -1352,6 +1364,11 @@ namespace OpenSim.Framework
return data; return data;
} }
public static byte[] StringToBytes1024(string str, params object[] args)
{
return StringToBytes1024(string.Format(str, args));
}
public static byte[] StringToBytes1024(string str) public static byte[] StringToBytes1024(string str)
{ {
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }

View File

@ -29,6 +29,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Globalization;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Security; using System.Net.Security;
@ -557,34 +558,27 @@ namespace OpenSim.Framework
{ {
float qx = GetQ(x); float qx = GetQ(x);
float qy = GetQ(y); float qy = GetQ(y);
if (qx < qy) return qy.CompareTo(qx); // descending order
return -1;
if (qx == qy)
return 0;
return 1;
} }
private float GetQ(Object o) private float GetQ(Object o)
{ {
// Example: image/png;q=0.9 // Example: image/png;q=0.9
float qvalue = 1F;
if (o is String) if (o is String)
{ {
string mime = (string)o; string mime = (string)o;
string[] parts = mime.Split(new char[] { ';' }); string[] parts = mime.Split(';');
if (parts.Length > 1) if (parts.Length > 1)
{ {
string[] kvp = parts[1].Split(new char[] { '=' }); string[] kvp = parts[1].Split('=');
if (kvp.Length == 2 && kvp[0] == "q") if (kvp.Length == 2 && kvp[0] == "q")
{ float.TryParse(kvp[1], NumberStyles.Number, CultureInfo.InvariantCulture, out qvalue);
float qvalue = 1F;
float.TryParse(kvp[1], out qvalue);
return qvalue;
}
} }
} }
return 1F; return qvalue;
} }
} }

View File

@ -294,6 +294,18 @@ namespace OpenSim
"show connections", "show connections",
"Show connection data", HandleShow); "Show connection data", HandleShow);
m_console.Commands.AddCommand("region", false, "show circuits",
"show circuits",
"Show agent circuit data", HandleShow);
m_console.Commands.AddCommand("region", false, "show http-handlers",
"show http-handlers",
"Show all registered http handlers", HandleShow);
m_console.Commands.AddCommand("region", false, "show pending-objects",
"show pending-objects",
"Show # of objects on the pending queues of all scene viewers", HandleShow);
m_console.Commands.AddCommand("region", false, "show modules", m_console.Commands.AddCommand("region", false, "show modules",
"show modules", "show modules",
"Show module data", HandleShow); "Show module data", HandleShow);
@ -943,6 +955,66 @@ namespace OpenSim
MainConsole.Instance.Output(connections.ToString()); MainConsole.Instance.Output(connections.ToString());
break; break;
case "circuits":
System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n");
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
//this.HttpServer.
acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName);
foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.AgentCircuits.Values)
acd.AppendFormat("\t{0} {1} ({2})\n", aCircuit.firstname, aCircuit.lastname, (aCircuit.child ? "Child" : "Root"));
}
);
MainConsole.Instance.Output(acd.ToString());
break;
case "http-handlers":
System.Text.StringBuilder handlers = new System.Text.StringBuilder("Registered HTTP Handlers:\n");
handlers.AppendFormat("* XMLRPC:\n");
foreach (String s in HttpServer.GetXmlRpcHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* HTTP:\n");
List<String> poll = HttpServer.GetPollServiceHandlerKeys();
foreach (String s in HttpServer.GetHTTPHandlerKeys())
handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
handlers.AppendFormat("* Agent:\n");
foreach (String s in HttpServer.GetAgentHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* LLSD:\n");
foreach (String s in HttpServer.GetLLSDHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
handlers.AppendFormat("* StreamHandlers ({0}):\n", HttpServer.GetStreamHandlerKeys().Count);
foreach (String s in HttpServer.GetStreamHandlerKeys())
handlers.AppendFormat("\t{0}\n", s);
MainConsole.Instance.Output(handlers.ToString());
break;
case "pending-objects":
System.Text.StringBuilder pending = new System.Text.StringBuilder("Pending objects:\n");
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
scene.ForEachScenePresence(
delegate(ScenePresence sp)
{
pending.AppendFormat("{0}: {1} {2} pending\n",
scene.RegionInfo.RegionName, sp.Name, sp.SceneViewer.GetPendingObjectsCount());
}
);
}
);
MainConsole.Instance.Output(pending.ToString());
break;
case "modules": case "modules":
MainConsole.Instance.Output("The currently loaded shared modules are:"); MainConsole.Instance.Output("The currently loaded shared modules are:");
foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules) foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules)
@ -958,11 +1030,12 @@ namespace OpenSim
delegate(Scene scene) delegate(Scene scene)
{ {
MainConsole.Instance.Output(String.Format( MainConsole.Instance.Output(String.Format(
"Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}", "Region Name: {0}, Region XLoc: {1}, Region YLoc: {2}, Region Port: {3}, Estate Name: {4}",
scene.RegionInfo.RegionName, scene.RegionInfo.RegionName,
scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocX,
scene.RegionInfo.RegionLocY, scene.RegionInfo.RegionLocY,
scene.RegionInfo.InternalEndPoint.Port)); scene.RegionInfo.InternalEndPoint.Port,
scene.RegionInfo.EstateSettings.EstateName));
}); });
break; break;

View File

@ -792,63 +792,116 @@ namespace OpenSim
regionnum = m_sceneManager.Scenes.Count; regionnum = m_sceneManager.Scenes.Count;
} }
/// <summary>
/// Create an estate with an initial region.
/// </summary>
/// <remarks>
/// This method doesn't allow an estate to be created with the same name as existing estates.
/// </remarks>
/// <param name="regInfo"></param>
/// <param name="existingName">A list of estate names that already exist.</param>
/// <returns>true if the estate was created, false otherwise</returns>
public bool CreateEstate(RegionInfo regInfo, List<string> existingNames)
{
// Create a new estate
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true);
string newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
if (existingNames.Contains(newName))
{
MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName);
return false;
}
regInfo.EstateSettings.EstateName = newName;
// FIXME: Later on, the scene constructor will reload the estate settings no matter what.
// Therefore, we need to do an initial save here otherwise the new estate name will be reset
// back to the default. The reloading of estate settings by scene could be eliminated if it
// knows that the passed in settings in RegionInfo are already valid. Also, it might be
// possible to eliminate some additional later saves made by callers of this method.
regInfo.EstateSettings.Save();
return true;
}
/// <summary> /// <summary>
/// Load the estate information for the provided RegionInfo object. /// Load the estate information for the provided RegionInfo object.
/// </summary> /// </summary>
/// <param name="regInfo"> /// <param name="regInfo"></param>
/// A <see cref="RegionInfo"/>
/// </param>
public void PopulateRegionEstateInfo(RegionInfo regInfo) public void PopulateRegionEstateInfo(RegionInfo regInfo)
{ {
IEstateDataService estateDataService = EstateDataService; if (EstateDataService != null)
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
if (estateDataService != null)
{
regInfo.EstateSettings = estateDataService.LoadEstateSettings(regInfo.RegionID, false);
}
if (regInfo.EstateSettings.EstateID == 0) // No record at all if (regInfo.EstateSettings.EstateID == 0) // No record at all
{ {
MainConsole.Instance.Output("Your region is not part of an estate."); MainConsole.Instance.OutputFormat("Region {0} is not part of an estate.", regInfo.RegionName);
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
List<string> estateNames = new List<string>();
foreach (EstateSettings estate in estates)
estateNames.Add(estate.EstateName);
while (true) while (true)
{ {
string response = MainConsole.Instance.CmdPrompt("Do you wish to join an existing estate?", "no", new List<string>() { "yes", "no" }); if (estates.Count == 0)
if (response == "no") {
{ MainConsole.Instance.Output("No existing estates found. You must create a new one.");
// Create a new estate
regInfo.EstateSettings = estateDataService.LoadEstateSettings(regInfo.RegionID, true); if (CreateEstate(regInfo, estateNames))
break;
regInfo.EstateSettings.EstateName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName); else
//regInfo.EstateSettings.Save(); continue;
break;
} }
else else
{ {
response = MainConsole.Instance.CmdPrompt("Estate name to join", "None"); string response
if (response == "None") = MainConsole.Instance.CmdPrompt(
continue; string.Format(
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
List<int> estateIDs = estateDataService.GetEstates(response); "no",
if (estateIDs.Count < 1) new List<string>() { "yes", "no" });
if (response == "no")
{ {
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again"); if (CreateEstate(regInfo, estateNames))
continue; break;
else
continue;
}
else
{
response
= MainConsole.Instance.CmdPrompt(
string.Format(
"Name of estate to join. Existing estate names are ({0})", string.Join(", ", estateNames.ToArray())),
"None");
if (response == "None")
continue;
List<int> estateIDs = EstateDataService.GetEstates(response);
if (estateIDs.Count < 1)
{
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
continue;
}
int estateID = estateIDs[0];
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
break;
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
} }
int estateID = estateIDs[0];
regInfo.EstateSettings = estateDataService.LoadEstateSettings(estateID);
if (estateDataService.LinkRegion(regInfo.RegionID, estateID))
break;
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
} }
} }
} }
} }
} }
public class OpenSimConfigSource public class OpenSimConfigSource
{ {

View File

@ -122,6 +122,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public int PacketsReceived; public int PacketsReceived;
/// <summary>Number of packets sent to this client</summary> /// <summary>Number of packets sent to this client</summary>
public int PacketsSent; public int PacketsSent;
/// <summary>Number of packets resent to this client</summary>
public int PacketsResent;
/// <summary>Total byte count of unacked packets sent to this client</summary> /// <summary>Total byte count of unacked packets sent to this client</summary>
public int UnackedBytes; public int UnackedBytes;
@ -256,9 +258,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public string GetStats() public string GetStats()
{ {
return string.Format( return string.Format(
"{0,7} {1,7} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}", "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}",
PacketsReceived,
PacketsSent, PacketsSent,
PacketsReceived, PacketsResent,
UnackedBytes, UnackedBytes,
m_packetOutboxes[(int)ThrottleOutPacketType.Resend].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Resend].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.Land].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Land].Count,
@ -441,13 +444,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// an outgoing packet from each, obeying the throttling bucket limits /// an outgoing packet from each, obeying the throttling bucket limits
/// </summary> /// </summary>
/// ///
/// <remarks>
/// Packet queues are inspected in ascending numerical order starting from 0. Therefore, queues with a lower /// Packet queues are inspected in ascending numerical order starting from 0. Therefore, queues with a lower
/// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have
/// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the
/// wind queue). /// wind queue).
/// ///
/// <remarks>This function is only called from a synchronous loop in the /// This function is only called from a synchronous loop in the
/// UDPServer so we don't need to bother making this thread safe</remarks> /// UDPServer so we don't need to bother making this thread safe
/// </remarks>
///
/// <returns>True if any packets were sent, otherwise false</returns> /// <returns>True if any packets were sent, otherwise false</returns>
public bool DequeueOutgoing() public bool DequeueOutgoing()
{ {
@ -476,7 +482,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_udpServer.SendPacketFinal(nextPacket); m_udpServer.SendPacketFinal(nextPacket);
m_nextPackets[i] = null; m_nextPackets[i] = null;
packetSent = true; packetSent = true;
this.PacketsSent++;
} }
} }
else else
@ -493,7 +498,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Send the packet // Send the packet
m_udpServer.SendPacketFinal(packet); m_udpServer.SendPacketFinal(packet);
packetSent = true; packetSent = true;
this.PacketsSent++;
} }
else else
{ {

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
@ -506,7 +507,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Bump up the resend count on this packet // Bump up the resend count on this packet
Interlocked.Increment(ref outgoingPacket.ResendCount); Interlocked.Increment(ref outgoingPacket.ResendCount);
//Interlocked.Increment(ref Stats.ResentPackets);
// Requeue or resend the packet // Requeue or resend the packet
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false)) if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false))
@ -582,6 +582,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
udpClient.NeedAcks.Add(outgoingPacket); udpClient.NeedAcks.Add(outgoingPacket);
} }
} }
else
{
Interlocked.Increment(ref udpClient.PacketsResent);
}
#endregion Sequence Number Assignment #endregion Sequence Number Assignment
@ -636,10 +640,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
object[] array = new object[] { buffer, packet }; object[] array = new object[] { buffer, packet };
if (m_asyncPacketHandling) Util.FireAndForget(HandleUseCircuitCode, array);
Util.FireAndForget(HandleUseCircuitCode, array);
else
HandleUseCircuitCode(array);
return; return;
} }
@ -844,7 +845,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandleUseCircuitCode(object o) private void HandleUseCircuitCode(object o)
{ {
DateTime startTime = DateTime.Now; // DateTime startTime = DateTime.Now;
object[] array = (object[])o; object[] array = (object[])o;
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1]; UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1];
@ -856,10 +857,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Begin the process of adding the client to the simulator // Begin the process of adding the client to the simulator
AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
// Acknowledge the UseCircuitCode packet // Send ack
SendAckImmediate(remoteEndPoint, packet.Header.Sequence); SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
// m_log.DebugFormat( // m_log.DebugFormat(
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
} }
@ -923,25 +924,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
{ {
// Create the LLUDPClient // In priciple there shouldn't be more than one thread here, ever.
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); // But in case that happens, we need to synchronize this piece of code
IClientAPI existingClient; // because it's too important
lock (this)
if (!m_scene.TryGetClient(agentID, out existingClient))
{ {
// Create the LLClientView IClientAPI existingClient;
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
client.DisableFacelights = m_disableFacelights; if (!m_scene.TryGetClient(agentID, out existingClient))
{
// Create the LLUDPClient
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
// Create the LLClientView
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
// Start the IClientAPI client.DisableFacelights = m_disableFacelights;
client.Start();
} // Start the IClientAPI
else client.Start();
{
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}", }
udpClient.AgentID, remoteEndPoint, circuitCode); else
{
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
existingClient.AgentId, remoteEndPoint, circuitCode);
}
} }
} }
@ -1050,6 +1058,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Update Timers #endregion Update Timers
// Use this for emergency monitoring -- bug hunting
//if (m_scene.EmergencyMonitoring)
// clientPacketHandler = MonitoredClientOutgoingPacketHandler;
//else
// clientPacketHandler = ClientOutgoingPacketHandler;
// Handle outgoing packets, resends, acknowledgements, and pings for each // Handle outgoing packets, resends, acknowledgements, and pings for each
// client. m_packetSent will be set to true if a packet is sent // client. m_packetSent will be set to true if a packet is sent
m_scene.ForEachClient(clientPacketHandler); m_scene.ForEachClient(clientPacketHandler);
@ -1065,6 +1079,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex); m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
} }
} }
Watchdog.RemoveThread(); Watchdog.RemoveThread();
@ -1102,6 +1117,112 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
#region Emergency Monitoring
// Alternative packet handler fuull of instrumentation
// Handy for hunting bugs
private Stopwatch watch1 = new Stopwatch();
private Stopwatch watch2 = new Stopwatch();
private float avgProcessingTicks = 0;
private float avgResendUnackedTicks = 0;
private float avgSendAcksTicks = 0;
private float avgSendPingTicks = 0;
private float avgDequeueTicks = 0;
private long nticks = 0;
private long nticksUnack = 0;
private long nticksAck = 0;
private long nticksPing = 0;
private int npacksSent = 0;
private int npackNotSent = 0;
private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
{
nticks++;
watch1.Start();
try
{
if (client is LLClientView)
{
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
if (udpClient.IsConnected)
{
if (m_resendUnacked)
{
nticksUnack++;
watch2.Start();
ResendUnacked(udpClient);
watch2.Stop();
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
watch2.Reset();
}
if (m_sendAcks)
{
nticksAck++;
watch2.Start();
SendAcks(udpClient);
watch2.Stop();
avgSendAcksTicks = (nticksAck - 1) / (float)nticksAck * avgSendAcksTicks + (watch2.ElapsedTicks / (float)nticksAck);
watch2.Reset();
}
if (m_sendPing)
{
nticksPing++;
watch2.Start();
SendPing(udpClient);
watch2.Stop();
avgSendPingTicks = (nticksPing - 1) / (float)nticksPing * avgSendPingTicks + (watch2.ElapsedTicks / (float)nticksPing);
watch2.Reset();
}
watch2.Start();
// Dequeue any outgoing packets that are within the throttle limits
if (udpClient.DequeueOutgoing())
{
m_packetSent = true;
npacksSent++;
}
else
npackNotSent++;
watch2.Stop();
avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
watch2.Reset();
}
else
m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
}
}
catch (Exception ex)
{
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
" threw an exception: " + ex.Message, ex);
}
watch1.Stop();
avgProcessingTicks = (nticks - 1) / (float)nticks * avgProcessingTicks + (watch1.ElapsedTicks / (float)nticks);
watch1.Reset();
// reuse this -- it's every ~100ms
if (m_scene.EmergencyMonitoring && nticks % 100 == 0)
{
m_log.InfoFormat("[LLUDPSERVER]: avg processing ticks: {0} avg unacked: {1} avg acks: {2} avg ping: {3} avg dequeue: {4} (TickCountRes: {5} sent: {6} notsent: {7})",
avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent);
npackNotSent = npacksSent = 0;
}
}
#endregion
private void ProcessInPacket(object state) private void ProcessInPacket(object state)
{ {
IncomingPacket incomingPacket = (IncomingPacket)state; IncomingPacket incomingPacket = (IncomingPacket)state;

View File

@ -210,6 +210,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
content = Math.Min(content + dripAmount, maxBurst); content = Math.Min(content + dripAmount, maxBurst);
lastDrip = now; lastDrip = now;
if (dripAmount < 0 || content < 0)
// sim has been idle for too long, integer has overflown
// previous calculation is meaningless, let's put it at correct max
content = maxBurst;
return true; return true;
} }
} }

View File

@ -143,7 +143,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Process all the pending adds // Process all the pending adds
OutgoingPacket pendingAdd; OutgoingPacket pendingAdd;
while (m_pendingAdds.TryDequeue(out pendingAdd)) while (m_pendingAdds.TryDequeue(out pendingAdd))
m_packets[pendingAdd.SequenceNumber] = pendingAdd; if (pendingAdd != null)
m_packets[pendingAdd.SequenceNumber] = pendingAdd;
// Process all the pending removes, including updating statistics and round-trip times // Process all the pending removes, including updating statistics and round-trip times
PendingAck pendingRemove; PendingAck pendingRemove;
@ -152,17 +153,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket))
{ {
m_packets.Remove(pendingRemove.SequenceNumber); if (ackedPacket != null)
// Update stats
Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
if (!pendingRemove.FromResend)
{ {
// Calculate the round-trip time for this packet and its ACK m_packets.Remove(pendingRemove.SequenceNumber);
int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount;
if (rtt > 0) // Update stats
ackedPacket.Client.UpdateRoundTrip(rtt); Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
if (!pendingRemove.FromResend)
{
// Calculate the round-trip time for this packet and its ACK
int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount;
if (rtt > 0)
ackedPacket.Client.UpdateRoundTrip(rtt);
}
} }
} }
} }

View File

@ -26,12 +26,14 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using Caps=OpenSim.Framework.Capabilities.Caps; using Caps=OpenSim.Framework.Capabilities.Caps;
@ -61,6 +63,9 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
{ {
m_scene = scene; m_scene = scene;
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
"show capabilities",
"Shows all registered capabilities", CapabilitiesCommand);
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
@ -72,7 +77,9 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
m_scene.UnregisterModuleInterface<ICapabilitiesModule>(this); m_scene.UnregisterModuleInterface<ICapabilitiesModule>(this);
} }
public void PostInitialise() {} public void PostInitialise()
{
}
public void Close() {} public void Close() {}
@ -226,5 +233,23 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
m_log.Info(" >> "+x+", "+y+": "+kvp.Value); m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
} }
} }
private void CapabilitiesCommand(string module, string[] cmdparams)
{
System.Text.StringBuilder caps = new System.Text.StringBuilder();
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
foreach (KeyValuePair<UUID, Caps> kvp in m_capsHandlers)
{
caps.AppendFormat("** User {0}:\n", kvp.Key);
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); )
{
Uri uri = new Uri(kvp2.Value.ToString());
caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery);
}
}
MainConsole.Instance.Output(caps.ToString());
}
} }
} }

View File

@ -92,9 +92,9 @@ namespace Flotsam.RegionModules.AssetCache
// Expiration is expressed in hours. // Expiration is expressed in hours.
private const double m_DefaultMemoryExpiration = 1.0; private const double m_DefaultMemoryExpiration = 1.0;
private const double m_DefaultFileExpiration = 48; private const double m_DefaultFileExpiration = 48;
private TimeSpan m_MemoryExpiration = TimeSpan.Zero; private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration);
private TimeSpan m_FileExpiration = TimeSpan.Zero; private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.Zero; private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(m_DefaultFileExpiration);
private static int m_CacheDirectoryTiers = 1; private static int m_CacheDirectoryTiers = 1;
private static int m_CacheDirectoryTierLen = 3; private static int m_CacheDirectoryTierLen = 3;
@ -147,7 +147,7 @@ namespace Flotsam.RegionModules.AssetCache
} }
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory); m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_CacheDirectory);
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", false); m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", false);
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration)); m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
@ -245,16 +245,7 @@ namespace Flotsam.RegionModules.AssetCache
private void UpdateMemoryCache(string key, AssetBase asset) private void UpdateMemoryCache(string key, AssetBase asset)
{ {
if (m_MemoryCacheEnabled) if (m_MemoryCacheEnabled)
{ m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
if (m_MemoryExpiration > TimeSpan.Zero)
{
m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
}
else
{
m_MemoryCache.AddOrUpdate(key, asset, Double.MaxValue);
}
}
} }
public void Cache(AssetBase asset) public void Cache(AssetBase asset)
@ -450,7 +441,7 @@ namespace Flotsam.RegionModules.AssetCache
private void CleanupExpiredFiles(object source, ElapsedEventArgs e) private void CleanupExpiredFiles(object source, ElapsedEventArgs e)
{ {
if (m_LogLevel >= 2) if (m_LogLevel >= 2)
m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration.ToString()); m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration);
// Purge all files last accessed prior to this point // Purge all files last accessed prior to this point
DateTime purgeLine = DateTime.Now - m_FileExpiration; DateTime purgeLine = DateTime.Now - m_FileExpiration;

View File

@ -245,14 +245,12 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
WriteTextureData(httpRequest, httpResponse, texture, format); WriteTextureData(httpRequest, httpResponse, texture, format);
return true; return true;
} }
} }
// not found // not found
m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); // m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true; return true;
} }
private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format) private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)

View File

@ -167,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
} }
} }
m_log.InfoFormat("[AVFACTORY]: complete texture check for {0}", client.AgentId); m_log.DebugFormat("[AVFACTORY]: complete texture check for {0}", client.AgentId);
// If we only found default textures, then the appearance is not cached // If we only found default textures, then the appearance is not cached
return (defonly ? false : true); return (defonly ? false : true);

View File

@ -49,16 +49,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
{ {
m_scene = scene; m_scene = scene;
m_scene.RegisterModuleInterface<IDialogModule>(this); m_scene.RegisterModuleInterface<IDialogModule>(this);
m_scene.AddCommand( m_scene.AddCommand(
this, "alert", "alert <first> <last> <message>", this, "alert", "alert <message>",
"Send an alert to a user", "Send an alert to everyone",
HandleAlertConsoleCommand); HandleAlertConsoleCommand);
m_scene.AddCommand( m_scene.AddCommand(
this, "alert general", "alert [general] <message>", this, "alert-user", "alert-user <first> <last> <message>",
"Send an alert to everyone", "Send an alert to a user",
"If keyword 'general' is omitted, then <message> must be surrounded by quotation marks.",
HandleAlertConsoleCommand); HandleAlertConsoleCommand);
} }
@ -177,55 +176,32 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
{ {
if (m_scene.ConsoleScene() != null && m_scene.ConsoleScene() != m_scene) if (m_scene.ConsoleScene() != null && m_scene.ConsoleScene() != m_scene)
return; return;
bool isGeneral = false;
string firstName = string.Empty;
string lastName = string.Empty;
string message = string.Empty; string message = string.Empty;
if (cmdparams.Length > 1) if (cmdparams[0].ToLower().Equals("alert"))
{ {
firstName = cmdparams[1]; message = CombineParams(cmdparams, 1);
isGeneral = firstName.ToLower().Equals("general"); m_log.InfoFormat("[DIALOG]: Sending general alert in region {0} with message {1}",
} m_scene.RegionInfo.RegionName, message);
if (cmdparams.Length == 2 && !isGeneral) SendGeneralAlert(message);
{
// alert "message"
message = cmdparams[1];
isGeneral = true;
}
else if (cmdparams.Length > 2 && isGeneral)
{
// alert general <message>
message = CombineParams(cmdparams, 2);
} }
else if (cmdparams.Length > 3) else if (cmdparams.Length > 3)
{ {
// alert <first> <last> <message> string firstName = cmdparams[1];
lastName = cmdparams[2]; string lastName = cmdparams[2];
message = CombineParams(cmdparams, 3); message = CombineParams(cmdparams, 3);
m_log.InfoFormat(
"[DIALOG]: Sending alert in region {0} to {1} {2} with message {3}",
m_scene.RegionInfo.RegionName, firstName, lastName, message);
SendAlertToUser(firstName, lastName, message, false);
} }
else else
{ {
OpenSim.Framework.Console.MainConsole.Instance.Output( OpenSim.Framework.Console.MainConsole.Instance.Output(
"Usage: alert \"message\" | alert general <message> | alert <first> <last> <message>"); "Usage: alert <message> | alert-user <first> <last> <message>");
return; return;
} }
if (isGeneral)
{
m_log.InfoFormat(
"[DIALOG]: Sending general alert in region {0} with message {1}",
m_scene.RegionInfo.RegionName, message);
SendGeneralAlert(message);
}
else
{
m_log.InfoFormat(
"[DIALOG]: Sending alert in region {0} to {1} {2} with message {3}",
m_scene.RegionInfo.RegionName, firstName, lastName, message);
SendAlertToUser(firstName, lastName, message, false);
}
} }
private string CombineParams(string[] commandParams, int pos) private string CombineParams(string[] commandParams, int pos)

View File

@ -41,6 +41,7 @@ using OpenSim.Framework.Serialization;
using OpenSim.Framework.Serialization.External; using OpenSim.Framework.Serialization.External;
using OpenSim.Region.CoreModules.World.Archiver; using OpenSim.Region.CoreModules.World.Archiver;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
@ -75,6 +76,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// The stream from which the inventory archive will be loaded. /// The stream from which the inventory archive will be loaded.
/// </value> /// </value>
private Stream m_loadStream; private Stream m_loadStream;
protected bool m_controlFileLoaded;
protected bool m_assetsLoaded;
protected bool m_inventoryNodesLoaded;
protected int m_successfulAssetRestores;
protected int m_failedAssetRestores;
protected int m_successfulItemRestores;
/// <summary>
/// Root destination folder for the IAR load.
/// </summary>
protected InventoryFolderBase m_rootDestinationFolder;
/// <summary>
/// Inventory nodes loaded from the iar.
/// </summary>
protected HashSet<InventoryNodeBase> m_loadedNodes = new HashSet<InventoryNodeBase>();
/// <summary>
/// In order to load identically named folders, we need to keep track of the folders that we have already
/// resolved.
/// </summary>
Dictionary <string, InventoryFolderBase> m_resolvedFolders = new Dictionary<string, InventoryFolderBase>();
/// <summary>
/// Record the creator id that should be associated with an asset. This is used to adjust asset creator ids
/// after OSP resolution (since OSP creators are only stored in the item
/// </summary>
protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
public InventoryArchiveReadRequest( public InventoryArchiveReadRequest(
Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge) Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge)
@ -100,20 +131,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <summary> /// <summary>
/// Execute the request /// Execute the request
/// </summary> /// </summary>
/// <remarks>
/// Only call this once. To load another IAR, construct another request object.
/// </remarks>
/// <returns> /// <returns>
/// A list of the inventory nodes loaded. If folders were loaded then only the root folders are /// A list of the inventory nodes loaded. If folders were loaded then only the root folders are
/// returned /// returned
/// </returns> /// </returns>
/// <exception cref="System.Exception">Thrown if load fails.</exception>
public HashSet<InventoryNodeBase> Execute() public HashSet<InventoryNodeBase> Execute()
{ {
try try
{ {
string filePath = "ERROR"; string filePath = "ERROR";
int successfulAssetRestores = 0;
int failedAssetRestores = 0;
int successfulItemRestores = 0;
HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();
List<InventoryFolderBase> folderCandidates List<InventoryFolderBase> folderCandidates
= InventoryArchiveUtils.FindFolderByPath( = InventoryArchiveUtils.FindFolderByPath(
@ -124,16 +154,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// Possibly provide an option later on to automatically create this folder if it does not exist // Possibly provide an option later on to automatically create this folder if it does not exist
m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath);
return loadedNodes; return m_loadedNodes;
} }
InventoryFolderBase rootDestinationFolder = folderCandidates[0]; m_rootDestinationFolder = folderCandidates[0];
archive = new TarArchiveReader(m_loadStream); archive = new TarArchiveReader(m_loadStream);
// In order to load identically named folders, we need to keep track of the folders that we have already
// resolved
Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>();
byte[] data; byte[] data;
TarArchiveReader.TarEntryType entryType; TarArchiveReader.TarEntryType entryType;
@ -142,45 +167,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (filePath == ArchiveConstants.CONTROL_FILE_PATH) if (filePath == ArchiveConstants.CONTROL_FILE_PATH)
{ {
LoadControlFile(filePath, data); LoadControlFile(filePath, data);
} }
else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
{ {
if (LoadAsset(filePath, data)) LoadAssetFile(filePath, data);
successfulAssetRestores++;
else
failedAssetRestores++;
if ((successfulAssetRestores) % 50 == 0)
m_log.DebugFormat(
"[INVENTORY ARCHIVER]: Loaded {0} assets...",
successfulAssetRestores);
} }
else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH)) else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH))
{ {
filePath = filePath.Substring(ArchiveConstants.INVENTORY_PATH.Length); LoadInventoryFile(filePath, entryType, data);
// Trim off the file portion if we aren't already dealing with a directory path
if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
filePath = filePath.Remove(filePath.LastIndexOf("/") + 1);
InventoryFolderBase foundFolder
= ReplicateArchivePathToUserInventory(
filePath, rootDestinationFolder, resolvedFolders, loadedNodes);
if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
{
InventoryItemBase item = LoadItem(data, foundFolder);
if (item != null)
{
successfulItemRestores++;
// If we aren't loading the folder containing the item then well need to update the
// viewer separately for that item.
if (!loadedNodes.Contains(foundFolder))
loadedNodes.Add(item);
}
}
} }
} }
@ -188,10 +182,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_log.DebugFormat( m_log.DebugFormat(
"[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
successfulAssetRestores, failedAssetRestores); m_successfulAssetRestores, m_failedAssetRestores);
m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", m_successfulItemRestores);
return loadedNodes; return m_loadedNodes;
} }
finally finally
{ {
@ -400,9 +394,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService);
if (UUID.Zero != ospResolvedId) // The user exists in this grid if (UUID.Zero != ospResolvedId) // The user exists in this grid
{ {
// m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId);
item.CreatorIdAsUuid = ospResolvedId; item.CreatorIdAsUuid = ospResolvedId;
// XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the // Don't preserve the OSPA in the creator id (which actually gets persisted to the
// database). Instead, replace with the UUID that we found. // database). Instead, replace with the UUID that we found.
item.CreatorId = ospResolvedId.ToString(); item.CreatorId = ospResolvedId.ToString();
@ -410,7 +406,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
} }
else if (item.CreatorData == null || item.CreatorData == String.Empty) else if (item.CreatorData == null || item.CreatorData == String.Empty)
{ {
item.CreatorIdAsUuid = m_userInfo.PrincipalID; item.CreatorId = m_userInfo.PrincipalID.ToString();
item.CreatorIdAsUuid = new UUID(item.CreatorId);
} }
item.Owner = m_userInfo.PrincipalID; item.Owner = m_userInfo.PrincipalID;
@ -418,6 +415,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// Reset folder ID to the one in which we want to load it // Reset folder ID to the one in which we want to load it
item.Folder = loadFolder.ID; item.Folder = loadFolder.ID;
// Record the creator id for the item's asset so that we can use it later, if necessary, when the asset
// is loaded.
// FIXME: This relies on the items coming before the assets in the TAR file. Need to create stronger
// checks for this, and maybe even an external tool for creating OARs which enforces this, rather than
// relying on native tar tools.
m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid;
m_scene.AddInventoryItem(item); m_scene.AddInventoryItem(item);
return item; return item;
@ -446,18 +450,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
} }
string extension = filename.Substring(i); string extension = filename.Substring(i);
string uuid = filename.Remove(filename.Length - extension.Length); string rawUuid = filename.Remove(filename.Length - extension.Length);
UUID assetId = new UUID(rawUuid);
if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension))
{ {
sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
if (assetType == (sbyte)AssetType.Unknown) if (assetType == (sbyte)AssetType.Unknown)
m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); {
m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId);
}
else if (assetType == (sbyte)AssetType.Object)
{
if (m_creatorIdForAssetId.ContainsKey(assetId))
{
string xmlData = Utils.BytesToString(data);
SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
foreach (SceneObjectPart sop in sog.Parts)
{
if (sop.CreatorData == null || sop.CreatorData == "")
{
sop.CreatorID = m_creatorIdForAssetId[assetId];
}
}
data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sog));
}
}
//m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType);
AssetBase asset = new AssetBase(new UUID(uuid), "RandomName", assetType, UUID.Zero.ToString()); AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString());
asset.Data = data; asset.Data = data;
m_scene.AssetService.Store(asset); m_scene.AssetService.Store(asset);
@ -495,7 +519,88 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
majorVersion, MAX_MAJOR_VERSION)); majorVersion, MAX_MAJOR_VERSION));
} }
m_log.InfoFormat("[INVENTORY ARCHIVER]: Loading IAR with version {0}", version); m_controlFileLoaded = true;
m_log.InfoFormat("[INVENTORY ARCHIVER]: Loading IAR with version {0}", version);
} }
/// <summary>
/// Load inventory file
/// </summary>
/// <param name="path"></param>
/// <param name="entryType"></param>
/// <param name="data"></param>
protected void LoadInventoryFile(string path, TarArchiveReader.TarEntryType entryType, byte[] data)
{
if (!m_controlFileLoaded)
throw new Exception(
string.Format(
"The IAR you are trying to load does not list {0} before {1}. Aborting load",
ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.INVENTORY_PATH));
if (m_assetsLoaded)
throw new Exception(
string.Format(
"The IAR you are trying to load does not list all {0} before {1}. Aborting load",
ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH));
path = path.Substring(ArchiveConstants.INVENTORY_PATH.Length);
// Trim off the file portion if we aren't already dealing with a directory path
if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
path = path.Remove(path.LastIndexOf("/") + 1);
InventoryFolderBase foundFolder
= ReplicateArchivePathToUserInventory(
path, m_rootDestinationFolder, m_resolvedFolders, m_loadedNodes);
if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
{
InventoryItemBase item = LoadItem(data, foundFolder);
if (item != null)
{
m_successfulItemRestores++;
// If we aren't loading the folder containing the item then well need to update the
// viewer separately for that item.
if (!m_loadedNodes.Contains(foundFolder))
m_loadedNodes.Add(item);
}
}
m_inventoryNodesLoaded = true;
}
/// <summary>
/// Load asset file
/// </summary>
/// <param name="path"></param>
/// <param name="data"></param>
protected void LoadAssetFile(string path, byte[] data)
{
if (!m_controlFileLoaded)
throw new Exception(
string.Format(
"The IAR you are trying to load does not list {0} before {1}. Aborting load",
ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.ASSETS_PATH));
if (!m_inventoryNodesLoaded)
throw new Exception(
string.Format(
"The IAR you are trying to load does not list all {0} before {1}. Aborting load",
ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH));
if (LoadAsset(path, data))
m_successfulAssetRestores++;
else
m_failedAssetRestores++;
if ((m_successfulAssetRestores) % 50 == 0)
m_log.DebugFormat(
"[INVENTORY ARCHIVER]: Loaded {0} assets...",
m_successfulAssetRestores);
m_assetsLoaded = true;
}
} }
} }

View File

@ -109,9 +109,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
scene.AddCommand( scene.AddCommand(
this, "load iar", this, "load iar",
"load iar [--merge] <first> <last> <inventory path> <password> [<IAR path>]", "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]",
"Load user inventory archive (IAR).", "Load user inventory archive (IAR).",
"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" "-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
+ "<first> is user's first name." + Environment.NewLine + "<first> is user's first name." + Environment.NewLine
+ "<last> is user's last name." + Environment.NewLine + "<last> is user's last name." + Environment.NewLine
+ "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine + "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine
@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
+ "<last> is the user's last name." + Environment.NewLine + "<last> is the user's last name." + Environment.NewLine
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + 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
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
+ "-v|--verbose extra debug messages." + Environment.NewLine + "-v|--verbose extra debug messages." + Environment.NewLine
+ "<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),
@ -180,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
catch (EntryPointNotFoundException e) catch (EntryPointNotFoundException e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream." "[INVENTORY 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.Error(e);
@ -220,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
catch (EntryPointNotFoundException e) catch (EntryPointNotFoundException e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream." "[INVENTORY 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.Error(e);
@ -268,7 +269,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
catch (EntryPointNotFoundException e) catch (EntryPointNotFoundException e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream." "[INVENTORY 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.Error(e);
@ -316,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
catch (EntryPointNotFoundException e) catch (EntryPointNotFoundException e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream." "[INVENTORY 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.Error(e);
@ -357,7 +358,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 load iar [--merge] <first name> <last name> <inventory path> <user password> [<load file path>]"); "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]");
return; return;
} }
@ -396,6 +397,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
//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("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; });
List<string> mainParams = ops.Parse(cmdparams); List<string> mainParams = ops.Parse(cmdparams);

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Data;
using OpenSim.Framework;
using OpenSim.Framework.Serialization;
using OpenSim.Framework.Serialization.External;
using OpenSim.Framework.Communications;
using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
[TestFixture]
public class InventoryArchiveTestCase
{
protected ManualResetEvent mre = new ManualResetEvent(false);
/// <summary>
/// A raw array of bytes that we'll use to create an IAR memory stream suitable for isolated use in each test.
/// </summary>
protected byte[] m_iarStreamBytes;
/// <summary>
/// Stream of data representing a common IAR for load tests.
/// </summary>
protected MemoryStream m_iarStream;
protected UserAccount m_uaMT
= new UserAccount {
PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000555"),
FirstName = "Mr",
LastName = "Tiddles" };
protected UserAccount m_uaLL1
= new UserAccount {
PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000666"),
FirstName = "Lord",
LastName = "Lucan" };
protected UserAccount m_uaLL2
= new UserAccount {
PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000777"),
FirstName = "Lord",
LastName = "Lucan" };
protected string m_item1Name = "Ray Gun Item";
[SetUp]
public virtual void SetUp()
{
m_iarStream = new MemoryStream(m_iarStreamBytes);
}
[TestFixtureSetUp]
public void FixtureSetup()
{
ConstructDefaultIarBytesForTestLoad();
}
protected void ConstructDefaultIarBytesForTestLoad()
{
// log4net.Config.XmlConfigurator.Configure();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene("Inventory");
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
MemoryStream archiveWriteStream = new MemoryStream();
// Create asset
SceneObjectGroup object1;
SceneObjectPart part1;
{
string partName = "Ray Gun Object";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
Vector3 groupPosition = new Vector3(10, 20, 30);
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
Vector3 offsetPosition = new Vector3(5, 10, 15);
part1
= new SceneObjectPart(
ownerId, shape, groupPosition, rotationOffset, offsetPosition);
part1.Name = partName;
object1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(object1, false);
}
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
scene.AssetService.Store(asset1);
// Create item
InventoryItemBase item1 = new InventoryItemBase();
item1.Name = m_item1Name;
item1.ID = UUID.Parse("00000000-0000-0000-0000-000000000020");
item1.AssetID = asset1.FullID;
item1.GroupID = UUID.Random();
item1.CreatorIdAsUuid = m_uaLL1.PrincipalID;
item1.Owner = m_uaLL1.PrincipalID;
item1.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID;
scene.AddInventoryItem(item1);
archiverModule.ArchiveInventory(
Guid.NewGuid(), m_uaLL1.FirstName, m_uaLL1.LastName, m_item1Name, "hampshire", archiveWriteStream);
m_iarStreamBytes = archiveWriteStream.ToArray();
}
protected void SaveCompleted(
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException)
{
mre.Set();
}
}
}

View File

@ -31,7 +31,6 @@ using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Data; using OpenSim.Data;
using OpenSim.Framework; using OpenSim.Framework;
@ -50,182 +49,21 @@ using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{ {
[TestFixture] [TestFixture]
public class InventoryArchiverTests public class InventoryArchiverTests : InventoryArchiveTestCase
{ {
protected ManualResetEvent mre = new ManualResetEvent(false); protected TestScene m_scene;
protected InventoryArchiverModule m_archiverModule;
/// <summary>
/// Stream of data representing a common IAR that can be reused in load tests.
/// </summary>
protected MemoryStream m_iarStream;
protected UserAccount m_ua1
= new UserAccount {
PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000555"),
FirstName = "Mr",
LastName = "Tiddles" };
protected UserAccount m_ua2
= new UserAccount {
PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000666"),
FirstName = "Lord",
LastName = "Lucan" };
string m_item1Name = "b.lsl";
private void SaveCompleted(
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException)
{
mre.Set();
}
[SetUp] [SetUp]
public void Init() public override void SetUp()
{ {
ConstructDefaultIarForTestLoad(); base.SetUp();
}
protected void ConstructDefaultIarForTestLoad()
{
string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(m_item1Name, UUID.Random());
MemoryStream archiveWriteStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
InventoryItemBase item1 = new InventoryItemBase();
item1.Name = m_item1Name;
item1.AssetID = UUID.Random();
item1.GroupID = UUID.Random();
//item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName);
//item1.CreatorId = userUuid.ToString();
item1.CreatorId = m_ua2.PrincipalID.ToString();
item1.Owner = UUID.Zero;
Scene scene = SceneSetupHelpers.SetupScene("Inventory");
UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
string item1FileName
= string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary<string, object>(), scene.UserAccountService));
tar.Close();
m_iarStream = new MemoryStream(archiveWriteStream.ToArray());
}
/// <summary>
/// Test saving an inventory path to a V0.1 OpenSim Inventory Archive
/// (subject to change since there is no fixed format yet).
/// </summary>
[Test]
public void TestSavePathToIarV0_1()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene("Inventory");
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
// Create user
string userFirstName = "Jock";
string userLastName = "Stirrup";
string userPassword = "troll";
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword);
// Create asset SerialiserModule serialiserModule = new SerialiserModule();
SceneObjectGroup object1; m_archiverModule = new InventoryArchiverModule();
SceneObjectPart part1;
{
string partName = "My Little Dog Object";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
Vector3 groupPosition = new Vector3(10, 20, 30);
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
Vector3 offsetPosition = new Vector3(5, 10, 15);
part1 m_scene = SceneSetupHelpers.SetupScene("Inventory");
= new SceneObjectPart( SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
ownerId, shape, groupPosition, rotationOffset, offsetPosition);
part1.Name = partName;
object1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(object1, false);
}
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
scene.AssetService.Store(asset1);
// Create item
UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
InventoryItemBase item1 = new InventoryItemBase();
item1.Name = "My Little Dog";
item1.AssetID = asset1.FullID;
item1.ID = item1Id;
InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
item1.Folder = objsFolder.ID;
scene.AddInventoryItem(item1);
MemoryStream archiveWriteStream = new MemoryStream();
archiverModule.OnInventoryArchiveSaved += SaveCompleted;
// Test saving a particular path
mre.Reset();
archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
mre.WaitOne(60000, false);
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}{2}",
ArchiveConstants.INVENTORY_PATH,
InventoryArchiveWriteRequest.CreateArchiveFolderName(objsFolder),
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;
// }
}
}
// 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> /// <summary>
@ -238,17 +76,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
TestHelper.InMethod(); TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene("Inventory");
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
// Create user // Create user
string userFirstName = "Jock"; string userFirstName = "Jock";
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); UserProfileTestUtils.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
// Create asset // Create asset
SceneObjectGroup object1; SceneObjectGroup object1;
@ -267,12 +100,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
part1.Name = partName; part1.Name = partName;
object1 = new SceneObjectGroup(part1); object1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(object1, false); m_scene.AddNewSceneObject(object1, false);
} }
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
scene.AssetService.Store(asset1); m_scene.AssetService.Store(asset1);
// Create item // Create item
UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
@ -282,15 +115,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
item1.AssetID = asset1.FullID; item1.AssetID = asset1.FullID;
item1.ID = item1Id; item1.ID = item1Id;
InventoryFolderBase objsFolder InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0]; = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0];
item1.Folder = objsFolder.ID; item1.Folder = objsFolder.ID;
scene.AddInventoryItem(item1); m_scene.AddInventoryItem(item1);
MemoryStream archiveWriteStream = new MemoryStream(); MemoryStream archiveWriteStream = new MemoryStream();
archiverModule.OnInventoryArchiveSaved += SaveCompleted; m_archiverModule.OnInventoryArchiveSaved += SaveCompleted;
mre.Reset(); mre.Reset();
archiverModule.ArchiveInventory( m_archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream); Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream);
mre.WaitOne(60000, false); mre.WaitOne(60000, false);
@ -346,474 +179,99 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
} }
/// <summary> /// <summary>
/// Test that things work when the load path specified starts with a slash /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized
/// </summary> /// objects.
/// </summary>
[Test] [Test]
public void TestLoadIarPathStartsWithSlash() public void TestLoadIarCreatorAccountPresent()
{ {
TestHelper.InMethod(); TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
SerialiserModule serialiserModule = new SerialiserModule();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene("inventory");
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "password");
archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/Objects", "password", m_iarStream);
UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1 InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath( = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name);
scene.InventoryService, m_ua1.PrincipalID, "/Objects/" + m_item1Name);
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1 in TestLoadIarFolderStartsWithSlash()");
}
/// <summary>
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
/// an account exists with the creator name.
/// </summary>
///
/// This test also does some deeper probing of loading into nested inventory structures
[Test]
public void TestLoadIarV0_1ExistingUsers()
{
TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
SerialiserModule serialiserModule = new SerialiserModule();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
// Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
Scene scene = SceneSetupHelpers.SetupScene("inventory");
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood");
UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, m_item1Name);
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
// We have to disable this check since loaded items that did find users via OSPA resolution are now only storing the
// UUID, not the OSPA itself.
// Assert.That(
// foundItem1.CreatorId, Is.EqualTo(item1.CreatorId),
// "Loaded item non-uuid creator doesn't match original");
Assert.That( Assert.That(
foundItem1.CreatorId, Is.EqualTo(m_ua2.PrincipalID.ToString()), foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()),
"Loaded item non-uuid creator doesn't match original"); "Loaded item non-uuid creator doesn't match original");
Assert.That( Assert.That(
foundItem1.CreatorIdAsUuid, Is.EqualTo(m_ua2.PrincipalID), foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID),
"Loaded item uuid creator doesn't match original"); "Loaded item uuid creator doesn't match original");
Assert.That(foundItem1.Owner, Is.EqualTo(m_ua1.PrincipalID), Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID),
"Loaded item owner doesn't match inventory reciever"); "Loaded item owner doesn't match inventory reciever");
// Now try loading to a root child folder AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_ua1.PrincipalID, "xA"); string xmlData = Utils.BytesToString(asset1.Data);
MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "xA", "meowfood", archiveReadStream);
Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
InventoryItemBase foundItem2
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, "xA/" + m_item1Name);
Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
// Now try loading to a more deeply nested folder
UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_ua1.PrincipalID, "xB/xC");
archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "xB/xC", "meowfood", archiveReadStream);
InventoryItemBase foundItem3
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, "xB/xC/" + m_item1Name);
Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3");
} }
/// <summary>
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
/// an account exists with the same name as the creator, though not the same id.
/// </summary>
[Test] [Test]
public void TestIarV0_1WithEscapedChars() public void TestLoadIarV0_1SameNameCreator()
{ {
TestHelper.InMethod(); TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
string itemName = "You & you are a mean/man/"; UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
string humanEscapedItemName = @"You & you are a mean\/man\/"; UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
string userPassword = "meowfood";
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene("Inventory");
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
// Create user
string userFirstName = "Jock";
string userLastName = "Stirrup";
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "meowfood");
// Create asset m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
SceneObjectGroup object1;
SceneObjectPart part1;
{
string partName = "part name";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
Vector3 groupPosition = new Vector3(10, 20, 30);
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
Vector3 offsetPosition = new Vector3(5, 10, 15);
part1
= new SceneObjectPart(
ownerId, shape, groupPosition, rotationOffset, offsetPosition);
part1.Name = partName;
object1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(object1, false);
}
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
scene.AssetService.Store(asset1);
// Create item
UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
InventoryItemBase item1 = new InventoryItemBase();
item1.Name = itemName;
item1.AssetID = asset1.FullID;
item1.ID = item1Id;
InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
item1.Folder = objsFolder.ID;
scene.AddInventoryItem(item1);
MemoryStream archiveWriteStream = new MemoryStream();
archiverModule.OnInventoryArchiveSaved += SaveCompleted;
mre.Reset();
archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
mre.WaitOne(60000, false);
// LOAD ITEM
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
InventoryItemBase foundItem1 InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath( = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName);
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
// Assert.That(
// foundItem1.CreatorId, Is.EqualTo(userUuid),
// "Loaded item non-uuid creator doesn't match that of the loading user");
Assert.That( Assert.That(
foundItem1.Name, Is.EqualTo(itemName), foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
"Loaded item name doesn't match saved name"); "Loaded item non-uuid creator doesn't match original");
Assert.That(
foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
"Loaded item uuid creator doesn't match original");
Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
"Loaded item owner doesn't match inventory reciever");
AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
string xmlData = Utils.BytesToString(asset1.Data);
SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
} }
/// <summary> /// <summary>
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
/// embedded creators do not exist in the system /// the creator or an account with the creator's name does not exist within the system.
/// </summary> /// </summary>
///
/// This may possibly one day get overtaken by the as yet incomplete temporary profiles feature
/// (as tested in the a later commented out test)
/// This test is currently disabled
[Test] [Test]
public void TestLoadIarV0_1AbsentUsers() public void TestLoadIarV0_1AbsentCreator()
{ {
TestHelper.InMethod(); TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
string userFirstName = "Charlie"; UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaMT, "password");
string userLastName = "Chan"; m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
UUID userUuid = UUID.Parse("00000000-0000-0000-0000-000000000999");
string userItemCreatorFirstName = "Bat";
string userItemCreatorLastName = "Man";
//UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000008888");
string itemName = "b.lsl";
string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(itemName, UUID.Random());
MemoryStream archiveWriteStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
InventoryItemBase item1 = new InventoryItemBase();
item1.Name = itemName;
item1.AssetID = UUID.Random();
item1.GroupID = UUID.Random();
item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName);
//item1.CreatorId = userUuid.ToString();
//item1.CreatorId = "00000000-0000-0000-0000-000000000444";
item1.Owner = UUID.Zero;
string item1FileName
= string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary<string,object>(), null));
tar.Close();
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
SerialiserModule serialiserModule = new SerialiserModule();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
// Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
Scene scene = SceneSetupHelpers.SetupScene("inventory");
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userUuid, "meowfood");
archiverModule.DearchiveInventory(userFirstName, userLastName, "/", "meowfood", archiveReadStream);
InventoryItemBase foundItem1 InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, itemName); = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
// Assert.That(
// foundItem1.CreatorId, Is.EqualTo(userUuid),
// "Loaded item non-uuid creator doesn't match that of the loading user");
Assert.That( Assert.That(
foundItem1.CreatorIdAsUuid, Is.EqualTo(userUuid), foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()),
"Loaded item non-uuid creator doesn't match that of the loading user");
Assert.That(
foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID),
"Loaded item uuid creator doesn't match that of the loading user"); "Loaded item uuid creator doesn't match that of the loading user");
}
/// <summary>
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
/// no account exists with the creator name
/// </summary>
/// Disabled since temporary profiles have not yet been implemented.
///
//[Test]
//public void TestLoadIarV0_1TempProfiles()
//{
// TestHelper.InMethod();
// //log4net.Config.XmlConfigurator.Configure(); AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
string xmlData = Utils.BytesToString(asset1.Data);
SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
// string userFirstName = "Dennis"; Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID));
// string userLastName = "Menace";
// UUID userUuid = UUID.Parse("00000000-0000-0000-0000-000000000aaa");
// string user2FirstName = "Walter";
// string user2LastName = "Mitty";
// string itemName = "b.lsl";
// string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(itemName, UUID.Random());
// MemoryStream archiveWriteStream = new MemoryStream();
// TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
// InventoryItemBase item1 = new InventoryItemBase();
// item1.Name = itemName;
// item1.AssetID = UUID.Random();
// item1.GroupID = UUID.Random();
// item1.CreatorId = OspResolver.MakeOspa(user2FirstName, user2LastName);
// item1.Owner = UUID.Zero;
// string item1FileName
// = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
// tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
// tar.Close();
// MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
// SerialiserModule serialiserModule = new SerialiserModule();
// InventoryArchiverModule archiverModule = new InventoryArchiverModule();
// // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
// Scene scene = SceneSetupHelpers.SetupScene();
// IUserAdminService userAdminService = scene.CommsManager.UserAdminService;
// SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
// userAdminService.AddUser(
// userFirstName, userLastName, "meowfood", String.Empty, 1000, 1000, userUuid);
// archiverModule.DearchiveInventory(userFirstName, userLastName, "/", "troll", archiveReadStream);
// // Check that a suitable temporary user profile has been created.
// UserProfileData user2Profile
// = scene.CommsManager.UserService.GetUserProfile(
// OspResolver.HashName(user2FirstName + " " + user2LastName));
// Assert.That(user2Profile, Is.Not.Null);
// Assert.That(user2Profile.FirstName == user2FirstName);
// Assert.That(user2Profile.SurName == user2LastName);
// CachedUserInfo userInfo
// = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
// userInfo.OnInventoryReceived += InventoryReceived;
// lock (this)
// {
// userInfo.FetchInventory();
// Monitor.Wait(this, 60000);
// }
// InventoryItemBase foundItem = userInfo.RootFolder.FindItemByPath(itemName);
// Assert.That(foundItem.CreatorId, Is.EqualTo(item1.CreatorId));
// Assert.That(
// foundItem.CreatorIdAsUuid, Is.EqualTo(OspResolver.HashName(user2FirstName + " " + user2LastName)));
// Assert.That(foundItem.Owner, Is.EqualTo(userUuid));
// Console.WriteLine("### Successfully completed {0} ###", MethodBase.GetCurrentMethod());
//}
/// <summary>
/// Test replication of an archive path to the user's inventory.
/// </summary>
[Test]
public void TestNewIarPath()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene("inventory");
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>();
string folder1Name = "1";
string folder2aName = "2a";
string folder2bName = "2b";
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1Name, UUID.Random());
string folder2aArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2aName, UUID.Random());
string folder2bArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2bName, UUID.Random());
string iarPath1 = string.Join("", new string[] { folder1ArchiveName, folder2aArchiveName });
string iarPath2 = string.Join("", new string[] { folder1ArchiveName, folder2bArchiveName });
{
// Test replication of path1
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded);
List<InventoryFolderBase> folder1Candidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
Assert.That(folder1Candidates.Count, Is.EqualTo(1));
InventoryFolderBase folder1 = folder1Candidates[0];
List<InventoryFolderBase> folder2aCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName);
Assert.That(folder2aCandidates.Count, Is.EqualTo(1));
}
{
// Test replication of path2
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded);
List<InventoryFolderBase> folder1Candidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
Assert.That(folder1Candidates.Count, Is.EqualTo(1));
InventoryFolderBase folder1 = folder1Candidates[0];
List<InventoryFolderBase> folder2aCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName);
Assert.That(folder2aCandidates.Count, Is.EqualTo(1));
List<InventoryFolderBase> folder2bCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2bName);
Assert.That(folder2bCandidates.Count, Is.EqualTo(1));
}
}
/// <summary>
/// Test replication of a partly existing archive path to the user's inventory. This should create
/// a duplicate path without the merge option.
/// </summary>
[Test]
public void TestPartExistingIarPath()
{
TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene("inventory");
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
string folder1ExistingName = "a";
string folder2Name = "b";
InventoryFolderBase folder1
= UserInventoryTestUtils.CreateInventoryFolder(
scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
List<InventoryFolderBase> folder1PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
Assert.That(folder1PostCandidates.Count, Is.EqualTo(2));
// FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder.
InventoryFolderBase folder1Post = null;
foreach (InventoryFolderBase folder in folder1PostCandidates)
{
if (folder.ID != folder1.ID)
{
folder1Post = folder;
break;
}
}
// Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID));
List<InventoryFolderBase> folder2PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b");
Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
}
/// <summary>
/// Test replication of a partly existing archive path to the user's inventory. This should create
/// a merged path.
/// </summary>
[Test]
public void TestMergeIarPath()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene("inventory");
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
string folder1ExistingName = "a";
string folder2Name = "b";
InventoryFolderBase folder1
= UserInventoryTestUtils.CreateInventoryFolder(
scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true)
.ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
List<InventoryFolderBase> folder1PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
Assert.That(folder1PostCandidates.Count, Is.EqualTo(1));
Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID));
List<InventoryFolderBase> folder2PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b");
Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
} }
} }
} }

View File

@ -0,0 +1,478 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Data;
using OpenSim.Framework;
using OpenSim.Framework.Serialization;
using OpenSim.Framework.Serialization.External;
using OpenSim.Framework.Communications;
using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
[TestFixture]
public class PathTests : InventoryArchiveTestCase
{
/// <summary>
/// Test saving an inventory path to a V0.1 OpenSim Inventory Archive
/// (subject to change since there is no fixed format yet).
/// </summary>
[Test]
public void TestSavePathToIarV0_1()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene("Inventory");
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
// Create user
string userFirstName = "Jock";
string userLastName = "Stirrup";
string userPassword = "troll";
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword);
// Create asset
SceneObjectGroup object1;
SceneObjectPart part1;
{
string partName = "My Little Dog Object";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
Vector3 groupPosition = new Vector3(10, 20, 30);
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
Vector3 offsetPosition = new Vector3(5, 10, 15);
part1 = new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition);
part1.Name = partName;
object1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(object1, false);
}
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
scene.AssetService.Store(asset1);
// Create item
UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
InventoryItemBase item1 = new InventoryItemBase();
item1.Name = "My Little Dog";
item1.AssetID = asset1.FullID;
item1.ID = item1Id;
InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
item1.Folder = objsFolder.ID;
scene.AddInventoryItem(item1);
MemoryStream archiveWriteStream = new MemoryStream();
archiverModule.OnInventoryArchiveSaved += SaveCompleted;
// Test saving a particular path
mre.Reset();
archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
mre.WaitOne(60000, false);
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}{2}",
ArchiveConstants.INVENTORY_PATH,
InventoryArchiveWriteRequest.CreateArchiveFolderName(objsFolder),
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;
// }
}
}
// 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 loading an IAR to various different inventory paths.
/// </summary>
[Test]
public void TestLoadIarToInventoryPaths()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
SerialiserModule serialiserModule = new SerialiserModule();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
// Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
Scene scene = SceneSetupHelpers.SetupScene("inventory");
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, m_uaMT, "meowfood");
UserProfileTestUtils.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
// Now try loading to a root child folder
UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA");
MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray());
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
InventoryItemBase foundItem2
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name);
Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
// Now try loading to a more deeply nested folder
UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC");
archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
InventoryItemBase foundItem3
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name);
Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3");
}
/// <summary>
/// Test that things work when the load path specified starts with a slash
/// </summary>
[Test]
public void TestLoadIarPathStartsWithSlash()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
SerialiserModule serialiserModule = new SerialiserModule();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene("inventory");
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
UserProfileTestUtils.CreateUserWithInventory(scene, m_uaMT, "password");
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(
scene.InventoryService, m_uaMT.PrincipalID, "/Objects/" + m_item1Name);
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1 in TestLoadIarFolderStartsWithSlash()");
}
[Test]
public void TestLoadIarPathWithEscapedChars()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
string itemName = "You & you are a mean/man/";
string humanEscapedItemName = @"You & you are a mean\/man\/";
string userPassword = "meowfood";
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
Scene scene = SceneSetupHelpers.SetupScene("Inventory");
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
// Create user
string userFirstName = "Jock";
string userLastName = "Stirrup";
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "meowfood");
// Create asset
SceneObjectGroup object1;
SceneObjectPart part1;
{
string partName = "part name";
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
Vector3 groupPosition = new Vector3(10, 20, 30);
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
Vector3 offsetPosition = new Vector3(5, 10, 15);
part1
= new SceneObjectPart(
ownerId, shape, groupPosition, rotationOffset, offsetPosition);
part1.Name = partName;
object1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(object1, false);
}
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
scene.AssetService.Store(asset1);
// Create item
UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
InventoryItemBase item1 = new InventoryItemBase();
item1.Name = itemName;
item1.AssetID = asset1.FullID;
item1.ID = item1Id;
InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
item1.Folder = objsFolder.ID;
scene.AddInventoryItem(item1);
MemoryStream archiveWriteStream = new MemoryStream();
archiverModule.OnInventoryArchiveSaved += SaveCompleted;
mre.Reset();
archiverModule.ArchiveInventory(
Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
mre.WaitOne(60000, false);
// LOAD ITEM
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(
scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName);
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
// Assert.That(
// foundItem1.CreatorId, Is.EqualTo(userUuid),
// "Loaded item non-uuid creator doesn't match that of the loading user");
Assert.That(
foundItem1.Name, Is.EqualTo(itemName),
"Loaded item name doesn't match saved name");
}
/// <summary>
/// Test replication of an archive path to the user's inventory.
/// </summary>
[Test]
public void TestNewIarPath()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene("inventory");
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>();
string folder1Name = "1";
string folder2aName = "2a";
string folder2bName = "2b";
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1Name, UUID.Random());
string folder2aArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2aName, UUID.Random());
string folder2bArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2bName, UUID.Random());
string iarPath1 = string.Join("", new string[] { folder1ArchiveName, folder2aArchiveName });
string iarPath2 = string.Join("", new string[] { folder1ArchiveName, folder2bArchiveName });
{
// Test replication of path1
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded);
List<InventoryFolderBase> folder1Candidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
Assert.That(folder1Candidates.Count, Is.EqualTo(1));
InventoryFolderBase folder1 = folder1Candidates[0];
List<InventoryFolderBase> folder2aCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName);
Assert.That(folder2aCandidates.Count, Is.EqualTo(1));
}
{
// Test replication of path2
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded);
List<InventoryFolderBase> folder1Candidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
Assert.That(folder1Candidates.Count, Is.EqualTo(1));
InventoryFolderBase folder1 = folder1Candidates[0];
List<InventoryFolderBase> folder2aCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName);
Assert.That(folder2aCandidates.Count, Is.EqualTo(1));
List<InventoryFolderBase> folder2bCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2bName);
Assert.That(folder2bCandidates.Count, Is.EqualTo(1));
}
}
/// <summary>
/// Test replication of a partly existing archive path to the user's inventory. This should create
/// a duplicate path without the merge option.
/// </summary>
[Test]
public void TestPartExistingIarPath()
{
TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene("inventory");
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
string folder1ExistingName = "a";
string folder2Name = "b";
InventoryFolderBase folder1
= UserInventoryTestUtils.CreateInventoryFolder(
scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
List<InventoryFolderBase> folder1PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
Assert.That(folder1PostCandidates.Count, Is.EqualTo(2));
// FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder.
InventoryFolderBase folder1Post = null;
foreach (InventoryFolderBase folder in folder1PostCandidates)
{
if (folder.ID != folder1.ID)
{
folder1Post = folder;
break;
}
}
// Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID));
List<InventoryFolderBase> folder2PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b");
Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
}
/// <summary>
/// Test replication of a partly existing archive path to the user's inventory. This should create
/// a merged path.
/// </summary>
[Test]
public void TestMergeIarPath()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene("inventory");
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
string folder1ExistingName = "a";
string folder2Name = "b";
InventoryFolderBase folder1
= UserInventoryTestUtils.CreateInventoryFolder(
scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true)
.ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
List<InventoryFolderBase> folder1PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
Assert.That(folder1PostCandidates.Count, Is.EqualTo(1));
Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID));
List<InventoryFolderBase> folder2PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b");
Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
}
}
}

View File

@ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0}\n{1}", e.Message, e.StackTrace); m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0} {1}", e.Message, e.StackTrace);
sp.ControllingClient.SendTeleportFailed("Internal error"); sp.ControllingClient.SendTeleportFailed("Internal error");
} }
} }
@ -284,9 +284,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return; return;
} }
if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero)) string reason;
if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out reason))
{ {
sp.ControllingClient.SendTeleportFailed("The destination region has refused access"); sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason);
return; return;
} }
@ -317,14 +318,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agentCircuit.Id0 = currentAgentCircuit.Id0; agentCircuit.Id0 = currentAgentCircuit.Id0;
} }
if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
{ {
// brand new agent, let's create a new caps seed // brand new agent, let's create a new caps seed
agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
} }
string reason = String.Empty;
// Let's create an agent there if one doesn't exist yet. // Let's create an agent there if one doesn't exist yet.
bool logout = false; bool logout = false;
if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
@ -337,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// OK, it got this agent. Let's close some child agents // OK, it got this agent. Let's close some child agents
sp.CloseChildAgents(newRegionX, newRegionY); sp.CloseChildAgents(newRegionX, newRegionY);
IClientIPEndpoint ipepClient; IClientIPEndpoint ipepClient;
if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
{ {
//sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
#region IP Translation for NAT #region IP Translation for NAT
@ -400,6 +399,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (!UpdateAgent(reg, finalDestination, agent)) if (!UpdateAgent(reg, finalDestination, agent))
{ {
// Region doesn't take it // Region doesn't take it
m_log.WarnFormat(
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.",
sp.Name, finalDestination.RegionName);
Fail(sp, finalDestination); Fail(sp, finalDestination);
return; return;
} }
@ -426,16 +429,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// that the client contacted the destination before we send the attachments and close things here. // that the client contacted the destination before we send the attachments and close things here.
if (!WaitForCallback(sp.UUID)) if (!WaitForCallback(sp.UUID))
{ {
Fail(sp, finalDestination); m_log.WarnFormat(
"[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.",
sp.Name, finalDestination.RegionName);
Fail(sp, finalDestination);
return; return;
} }
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
CrossAttachmentsIntoNewRegion(finalDestination, sp, true); CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
// Well, this is it. The agent is over there. // Well, this is it. The agent is over there.
KillEntity(sp.Scene, sp.LocalId); KillEntity(sp.Scene, sp.LocalId);
// May need to logout or other cleanup // May need to logout or other cleanup
@ -448,7 +453,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
{ {
Thread.Sleep(5000); Thread.Sleep(5000);
sp.Close(); sp.Close();
@ -522,14 +527,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return region; return region;
} }
protected virtual bool NeedsNewAgent(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY)
{ {
return Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY); return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
} }
protected virtual bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg)
{ {
return Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY); return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
} }
protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) protected virtual bool IsOutsideRegion(Scene s, Vector3 pos)
@ -778,7 +783,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos)) string reason;
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out reason))
{ {
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
if (r == null) if (r == null)
@ -983,7 +989,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// </summary> /// </summary>
public void EnableChildAgent(ScenePresence sp, GridRegion region) public void EnableChildAgent(ScenePresence sp, GridRegion region)
{ {
m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighour {0}", region.RegionName); m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();
@ -1045,7 +1051,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (m_regionInfo != null) if (m_regionInfo != null)
{ {
neighbours = RequestNeighbours(sp.Scene, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); neighbours = RequestNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY);
} }
else else
{ {
@ -1272,8 +1278,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <param name="pRegionLocX"></param> /// <param name="pRegionLocX"></param>
/// <param name="pRegionLocY"></param> /// <param name="pRegionLocY"></param>
/// <returns></returns> /// <returns></returns>
protected List<GridRegion> RequestNeighbours(Scene pScene, uint pRegionLocX, uint pRegionLocY) protected List<GridRegion> RequestNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY)
{ {
Scene pScene = avatar.Scene;
RegionInfo m_regionInfo = pScene.RegionInfo; RegionInfo m_regionInfo = pScene.RegionInfo;
Border[] northBorders = pScene.NorthBorders.ToArray(); Border[] northBorders = pScene.NorthBorders.ToArray();
@ -1281,10 +1288,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Border[] eastBorders = pScene.EastBorders.ToArray(); Border[] eastBorders = pScene.EastBorders.ToArray();
Border[] westBorders = pScene.WestBorders.ToArray(); Border[] westBorders = pScene.WestBorders.ToArray();
// Legacy one region. Provided for simplicity while testing the all inclusive method in the else statement. // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't
// clear what should be done with a "far view" given that megaregions already extended the
// view to include everything in the megaregion
if (northBorders.Length <= 1 && southBorders.Length <= 1 && eastBorders.Length <= 1 && westBorders.Length <= 1) if (northBorders.Length <= 1 && southBorders.Length <= 1 && eastBorders.Length <= 1 && westBorders.Length <= 1)
{ {
return pScene.GridService.GetNeighbours(m_regionInfo.ScopeID, m_regionInfo.RegionID); int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance;
int startX = (int)pRegionLocX * (int)Constants.RegionSize - dd + (int)(Constants.RegionSize/2);
int startY = (int)pRegionLocY * (int)Constants.RegionSize - dd + (int)(Constants.RegionSize/2);
int endX = (int)pRegionLocX * (int)Constants.RegionSize + dd + (int)(Constants.RegionSize/2);
int endY = (int)pRegionLocY * (int)Constants.RegionSize + dd + (int)(Constants.RegionSize/2);
List<GridRegion> neighbours =
avatar.Scene.GridService.GetRegionRange(m_regionInfo.ScopeID, startX, endX, startY, endY);
neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; });
return neighbours;
} }
else else
{ {

View File

@ -130,9 +130,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return region; return region;
} }
protected override bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) protected override bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg)
{ {
if (base.NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
return true; return true;
int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID);

View File

@ -55,6 +55,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
} }
private string m_ProfileServerURI; private string m_ProfileServerURI;
private bool m_OutboundPermission;
// private bool m_Initialized = false; // private bool m_Initialized = false;
@ -78,7 +79,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
if (thisModuleConfig != null) if (thisModuleConfig != null)
{
m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
}
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!");
} }
@ -103,7 +107,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)) if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission)
{ {
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); }); Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
} }
@ -197,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (IsForeignUser(sender, out userAssetServer)) if (IsForeignUser(sender, out userAssetServer))
m_assMapper.Get(item.AssetID, sender, userAssetServer); m_assMapper.Get(item.AssetID, sender, userAssetServer);
if (IsForeignUser(receiver, out userAssetServer)) if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission)
m_assMapper.Post(item.AssetID, receiver, userAssetServer); m_assMapper.Post(item.AssetID, receiver, userAssetServer);
} }

View File

@ -148,6 +148,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = m_Scene.InventoryService.GetItem(item); item = m_Scene.InventoryService.GetItem(item);
if (item.Owner != remoteClient.AgentId)
return UUID.Zero;
if (item != null) if (item != null)
{ {
if ((InventoryType)item.InvType == InventoryType.Notecard) if ((InventoryType)item.InvType == InventoryType.Notecard)
@ -524,6 +527,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (item != null) if (item != null)
{ {
item.Owner = remoteClient.AgentId;
AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
if (rezAsset != null) if (rezAsset != null)

View File

@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare
m_scene = scene; m_scene = scene;
m_scene.RegisterModuleInterface<IRegionModule>(this); m_scene.RegisterModuleInterface<IRegionModule>(this);
m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
// ini file settings // ini file settings
try try
{ {
@ -148,7 +148,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare
public void SendProfileToClient(ScenePresence presence) public void SendProfileToClient(ScenePresence presence)
{ {
IClientAPI client = presence.ControllingClient; IClientAPI client = presence.ControllingClient;
if (m_enableWindlight) if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid)
{ {
if (presence.IsChildAgent == false) if (presence.IsChildAgent == false)
{ {
@ -165,7 +165,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare
public void SendProfileToClient(ScenePresence presence, RegionLightShareData wl) public void SendProfileToClient(ScenePresence presence, RegionLightShareData wl)
{ {
IClientAPI client = presence.ControllingClient; IClientAPI client = presence.ControllingClient;
if (m_enableWindlight) if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid)
{ {
if (presence.IsChildAgent == false) if (presence.IsChildAgent == false)
{ {
@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare
{ {
Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast"); Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast");
Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin"); Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin");
Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Enable the windlight plugin"); Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Disable the windlight plugin");
m_commander.RegisterCommand("load", wlload); m_commander.RegisterCommand("load", wlload);
m_commander.RegisterCommand("enable", wlenable); m_commander.RegisterCommand("enable", wlenable);

View File

@ -47,7 +47,6 @@
<RegionModule id="RemoteAuthorizationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization.RemoteAuthorizationServicesConnector" /> <RegionModule id="RemoteAuthorizationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization.RemoteAuthorizationServicesConnector" />
<RegionModule id="HGAssetBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.HGAssetBroker" /> <RegionModule id="HGAssetBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.HGAssetBroker" />
<RegionModule id="LocalInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.LocalInventoryServicesConnector" /> <RegionModule id="LocalInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.LocalInventoryServicesConnector" />
<RegionModule id="RemoteInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteInventoryServicesConnector" />
<RegionModule id="RemoteXInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteXInventoryServicesConnector" /> <RegionModule id="RemoteXInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteXInventoryServicesConnector" />
<RegionModule id="HGInventoryBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.HGInventoryBroker" /> <RegionModule id="HGInventoryBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.HGInventoryBroker" />
<RegionModule id="LocalNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.LocalNeighbourServicesConnector" /> <RegionModule id="LocalNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.LocalNeighbourServicesConnector" />

View File

@ -139,7 +139,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
if (scene != null) if (scene != null)
{ {
UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, userID); UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID));
isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName, isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName,
account.Email, scene.RegionInfo.RegionName, regionID, out message); account.Email, scene.RegionInfo.RegionName, regionID, out message);
} }

View File

@ -247,13 +247,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public void NeighboursCommand(string module, string[] cmdparams) public void NeighboursCommand(string module, string[] cmdparams)
{ {
System.Text.StringBuilder caps = new System.Text.StringBuilder();
foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache) foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache)
{ {
m_log.InfoFormat("*** Neighbours of {0} {1} ***", kvp.Key, kvp.Value.RegionName); caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key);
List<GridRegion> regions = kvp.Value.GetNeighbours(); List<GridRegion> regions = kvp.Value.GetNeighbours();
foreach (GridRegion r in regions) foreach (GridRegion r in regions)
m_log.InfoFormat(" {0} @ {1}={2}", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize); caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize);
} }
MainConsole.Instance.Output(caps.ToString());
} }
} }

View File

@ -32,7 +32,6 @@ using System.Reflection;
using System.Threading; using System.Threading;
using log4net.Config; using log4net.Config;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using Nini.Config; using Nini.Config;

View File

@ -200,6 +200,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return; return;
} }
} }
else
{
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID);
return;
}
} }
} }
} }

View File

@ -1,362 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using log4net;
using System;
using System.Collections.Generic;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Statistics;
using OpenSim.Services.Connectors;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
{
public class RemoteInventoryServicesConnector : BaseInventoryConnector, ISharedRegionModule, IInventoryService
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false;
private bool m_Initialized = false;
private Scene m_Scene;
private InventoryServicesConnector m_RemoteConnector;
private IUserManagement m_UserManager;
private IUserManagement UserManager
{
get
{
if (m_UserManager == null)
{
m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
}
return m_UserManager;
}
}
public Type ReplaceableInterface
{
get { return null; }
}
public string Name
{
get { return "RemoteInventoryServicesConnector"; }
}
public RemoteInventoryServicesConnector()
{
}
public RemoteInventoryServicesConnector(IConfigSource source)
{
Init(source);
}
protected override void Init(IConfigSource source)
{
m_RemoteConnector = new InventoryServicesConnector(source);
base.Init(source);
}
#region ISharedRegionModule
public void Initialise(IConfigSource source)
{
IConfig moduleConfig = source.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("InventoryServices", "");
if (name == Name)
{
Init(source);
m_Enabled = true;
m_log.Info("[INVENTORY CONNECTOR]: Remote inventory enabled");
}
}
}
public void PostInitialise()
{
}
public void Close()
{
}
public void AddRegion(Scene scene)
{
// m_Scene = scene;
//m_log.Debug("[XXXX] Adding scene " + m_Scene.RegionInfo.RegionName);
if (!m_Enabled)
return;
if (!m_Initialized)
{
m_Initialized = true;
}
scene.RegisterModuleInterface<IInventoryService>(this);
m_cache.AddRegion(scene);
if (m_Scene == null)
m_Scene = scene;
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_cache.RemoveRegion(scene);
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled remote inventory for region {0}", scene.RegionInfo.RegionName);
}
#endregion ISharedRegionModule
#region IInventoryService
public override bool CreateUserInventory(UUID user)
{
return false;
}
public override List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
{
return new List<InventoryFolderBase>();
}
public override InventoryCollection GetUserInventory(UUID userID)
{
return null;
}
public override void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
{
UUID sessionID = GetSessionID(userID);
try
{
m_RemoteConnector.GetUserInventory(userID.ToString(), sessionID, callback);
}
catch (Exception e)
{
if (StatsManager.SimExtraStats != null)
StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure();
m_log.ErrorFormat("[INVENTORY CONNECTOR]: Request inventory operation failed, {0} {1}",
e.Source, e.Message);
}
}
// inherited. See base class
// public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
public override Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(UUID userID)
{
UUID sessionID = GetSessionID(userID);
return m_RemoteConnector.GetSystemFolders(userID.ToString(), sessionID);
}
public override InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
UUID sessionID = GetSessionID(userID);
try
{
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID.ToString(), folderID, sessionID);
foreach (InventoryItemBase item in invCol.Items)
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
return invCol;
}
catch (Exception e)
{
m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1}",
e.Source, e.Message);
}
InventoryCollection nullCollection = new InventoryCollection();
nullCollection.Folders = new List<InventoryFolderBase>();
nullCollection.Items = new List<InventoryItemBase>();
nullCollection.UserID = userID;
return nullCollection;
}
public override List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
{
UUID sessionID = GetSessionID(userID);
return m_RemoteConnector.GetFolderItems(userID.ToString(), folderID, sessionID);
}
public override bool AddFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.AddFolder(folder.Owner.ToString(), folder, sessionID);
}
public override bool UpdateFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.UpdateFolder(folder.Owner.ToString(), folder, sessionID);
}
public override bool MoveFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.MoveFolder(folder.Owner.ToString(), folder, sessionID);
}
public override bool DeleteFolders(UUID ownerID, List<UUID> folderIDs)
{
if (folderIDs == null)
return false;
if (folderIDs.Count == 0)
return false;
UUID sessionID = GetSessionID(ownerID);
return m_RemoteConnector.DeleteFolders(ownerID.ToString(), folderIDs, sessionID);
}
public override bool PurgeFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.PurgeFolder(folder.Owner.ToString(), folder, sessionID);
}
// public bool AddItem(InventoryItemBase item) inherited
// Uses AddItemPlain
protected override bool AddItemPlain(InventoryItemBase item)
{
if (item == null)
return false;
UUID sessionID = GetSessionID(item.Owner);
return m_RemoteConnector.AddItem(item.Owner.ToString(), item, sessionID);
}
public override bool UpdateItem(InventoryItemBase item)
{
if (item == null)
return false;
UUID sessionID = GetSessionID(item.Owner);
return m_RemoteConnector.UpdateItem(item.Owner.ToString(), item, sessionID);
}
public override bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
{
if (items == null)
return false;
UUID sessionID = GetSessionID(ownerID);
return m_RemoteConnector.MoveItems(ownerID.ToString(), items, sessionID);
}
public override bool DeleteItems(UUID ownerID, List<UUID> itemIDs)
{
if (itemIDs == null)
return false;
if (itemIDs.Count == 0)
return true;
UUID sessionID = GetSessionID(ownerID);
return m_RemoteConnector.DeleteItems(ownerID.ToString(), itemIDs, sessionID);
}
public override InventoryItemBase GetItem(InventoryItemBase item)
{
if (item == null)
return null;
UUID sessionID = GetSessionID(item.Owner);
return m_RemoteConnector.QueryItem(item.Owner.ToString(), item, sessionID);
}
public override InventoryFolderBase GetFolder(InventoryFolderBase folder)
{
if (folder == null)
return null;
UUID sessionID = GetSessionID(folder.Owner);
return m_RemoteConnector.QueryFolder(folder.Owner.ToString(), folder, sessionID);
}
public override bool HasInventoryForUser(UUID userID)
{
return false;
}
public override List<InventoryItemBase> GetActiveGestures(UUID userId)
{
return new List<InventoryItemBase>();
}
public override int GetAssetPermissions(UUID userID, UUID assetID)
{
UUID sessionID = GetSessionID(userID);
return m_RemoteConnector.GetAssetPermissions(userID.ToString(), assetID, sessionID);
}
#endregion
private UUID GetSessionID(UUID userID)
{
return UUID.Zero;
}
}
}

View File

@ -32,7 +32,6 @@ using System.Reflection;
using System.Threading; using System.Threading;
using log4net.Config; using log4net.Config;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using Nini.Config; using Nini.Config;

View File

@ -225,17 +225,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
if (destination == null) if (destination == null)
return false; return false;
// We limit the number of messages sent for a position change to just one per
// simulator so when we receive the update we need to hand it to each of the
// scenes; scenes each check to see if the is a scene presence for the avatar
// note that we really don't need the GridRegion for this call
foreach (Scene s in m_sceneList) foreach (Scene s in m_sceneList)
{ {
if (s.RegionInfo.RegionHandle == destination.RegionHandle) //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
{ s.IncomingChildAgentDataUpdate(cAgentData);
//m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
s.IncomingChildAgentDataUpdate(cAgentData);
return true;
}
} }
//m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
return false; return true;
} }
public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
@ -257,15 +257,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false; return false;
} }
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position) public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason)
{ {
reason = "Communications failure";
if (destination == null) if (destination == null)
return false; return false;
foreach (Scene s in m_sceneList) foreach (Scene s in m_sceneList)
{ {
if (s.RegionInfo.RegionID == destination.RegionID) if (s.RegionInfo.RegionID == destination.RegionID)
return s.QueryAccess(id, position); return s.QueryAccess(id, position, out reason);
} }
//m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess"); //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess");
return false; return false;

View File

@ -192,15 +192,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false; return false;
// Try local first // Try local first
if (m_localBackend.UpdateAgent(destination, cAgentData)) if (m_localBackend.IsLocalRegion(destination.RegionHandle))
return true; return m_localBackend.UpdateAgent(destination, cAgentData);
// else do the remote thing
if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
return m_remoteConnector.UpdateAgent(destination, cAgentData);
return false;
return m_remoteConnector.UpdateAgent(destination, cAgentData);
} }
public bool UpdateAgent(GridRegion destination, AgentPosition cAgentData) public bool UpdateAgent(GridRegion destination, AgentPosition cAgentData)
@ -209,15 +204,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false; return false;
// Try local first // Try local first
if (m_localBackend.UpdateAgent(destination, cAgentData)) if (m_localBackend.IsLocalRegion(destination.RegionHandle))
return true; return m_localBackend.UpdateAgent(destination, cAgentData);
// else do the remote thing
if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
return m_remoteConnector.UpdateAgent(destination, cAgentData);
return false;
return m_remoteConnector.UpdateAgent(destination, cAgentData);
} }
public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
@ -239,18 +229,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
} }
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position) public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason)
{ {
reason = "Communications failure";
if (destination == null) if (destination == null)
return false; return false;
// Try local first // Try local first
if (m_localBackend.QueryAccess(destination, id, position)) if (m_localBackend.QueryAccess(destination, id, position, out reason))
return true; return true;
// else do the remote thing // else do the remote thing
if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
return m_remoteConnector.QueryAccess(destination, id, position); return m_remoteConnector.QueryAccess(destination, id, position, out reason);
return false; return false;

View File

@ -32,7 +32,6 @@ using System.Reflection;
using System.Threading; using System.Threading;
using log4net.Config; using log4net.Config;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Assets; using OpenMetaverse.Assets;
using OpenSim.Framework; using OpenSim.Framework;

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Security;
using System.Text;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.World.Estate
{
/// <summary>
/// Estate management console commands.
/// </summary>
public class EstateManagementCommands
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected EstateManagementModule m_module;
protected Commander m_commander = new Commander("estate");
public EstateManagementCommands(EstateManagementModule module)
{
m_module = module;
}
public void Initialise()
{
m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName);
m_module.Scene.AddCommand(m_module, "set terrain texture",
"set terrain texture <number> <uuid> [<x>] [<y>]",
"Sets the terrain <number> to <uuid>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate.",
consoleSetTerrainTexture);
m_module.Scene.AddCommand(m_module, "set terrain heights",
"set terrain heights <corner> <min> <max> [<x>] [<y>]",
"Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.",
consoleSetTerrainHeights);
Command showCommand
= new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowEstatesCommand, "Shows all estates on the simulator.");
m_commander.RegisterCommand("show", showCommand);
m_module.Scene.RegisterModuleCommander(m_commander);
m_module.Scene.EventManager.OnPluginConsole += EventManagerOnPluginConsole;
}
public void Close()
{
m_module.Scene.EventManager.OnPluginConsole -= EventManagerOnPluginConsole;
m_module.Scene.UnregisterModuleCommander(m_commander.Name);
}
/// <summary>
/// Processes commandline input. Do not call directly.
/// </summary>
/// <param name="args">Commandline arguments</param>
protected void EventManagerOnPluginConsole(string[] args)
{
if (args[0] == "estate")
{
if (args.Length == 1)
{
m_commander.ProcessConsoleCommand("help", new string[0]);
return;
}
string[] tmpArgs = new string[args.Length - 2];
int i;
for (i = 2; i < args.Length; i++)
tmpArgs[i - 2] = args[i];
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
}
}
protected void consoleSetTerrainTexture(string module, string[] args)
{
string num = args[3];
string uuid = args[4];
int x = (args.Length > 5 ? int.Parse(args[5]) : -1);
int y = (args.Length > 6 ? int.Parse(args[6]) : -1);
if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x)
{
if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y)
{
int corner = int.Parse(num);
UUID texture = UUID.Parse(uuid);
m_log.Debug("[ESTATEMODULE]: Setting terrain textures for " + m_module.Scene.RegionInfo.RegionName +
string.Format(" (C#{0} = {1})", corner, texture));
switch (corner)
{
case 0:
m_module.Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture;
break;
case 1:
m_module.Scene.RegionInfo.RegionSettings.TerrainTexture2 = texture;
break;
case 2:
m_module.Scene.RegionInfo.RegionSettings.TerrainTexture3 = texture;
break;
case 3:
m_module.Scene.RegionInfo.RegionSettings.TerrainTexture4 = texture;
break;
}
m_module.Scene.RegionInfo.RegionSettings.Save();
m_module.TriggerRegionInfoChange();
m_module.sendRegionInfoPacketToAll();
}
}
}
protected void consoleSetTerrainHeights(string module, string[] args)
{
string num = args[3];
string min = args[4];
string max = args[5];
int x = (args.Length > 6 ? int.Parse(args[6]) : -1);
int y = (args.Length > 7 ? int.Parse(args[7]) : -1);
if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x)
{
if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y)
{
int corner = int.Parse(num);
float lowValue = float.Parse(min, Culture.NumberFormatInfo);
float highValue = float.Parse(max, Culture.NumberFormatInfo);
m_log.Debug("[ESTATEMODULE]: Setting terrain heights " + m_module.Scene.RegionInfo.RegionName +
string.Format(" (C{0}, {1}-{2}", corner, lowValue, highValue));
switch (corner)
{
case 0:
m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue;
break;
case 1:
m_module.Scene.RegionInfo.RegionSettings.Elevation1NW = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2NW = highValue;
break;
case 2:
m_module.Scene.RegionInfo.RegionSettings.Elevation1SE = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2SE = highValue;
break;
case 3:
m_module.Scene.RegionInfo.RegionSettings.Elevation1NE = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2NE = highValue;
break;
}
m_module.Scene.RegionInfo.RegionSettings.Save();
m_module.TriggerRegionInfoChange();
m_module.sendRegionHandshakeToAll();
}
}
}
protected void ShowEstatesCommand(Object[] args)
{
StringBuilder report = new StringBuilder();
RegionInfo ri = m_module.Scene.RegionInfo;
EstateSettings es = ri.EstateSettings;
report.AppendFormat("Estate information for region {0}\n", ri.RegionName);
report.AppendFormat(
"{0,-20} {1,-7} {2,-20}\n",
"Estate Name",
"ID",
"Owner");
report.AppendFormat(
"{0,-20} {1,-7} {2,-20}\n",
es.EstateName, es.EstateID, m_module.UserManager.GetUserName(es.EstateOwner));
MainConsole.Instance.Output(report.ToString());
}
}
}

View File

@ -72,6 +72,7 @@ namespace OpenSim.Region.CoreModules.World.Land
protected Commander m_commander = new Commander("land"); protected Commander m_commander = new Commander("land");
protected IUserManagement m_userManager; protected IUserManagement m_userManager;
protected IPrimCountModule m_primCountModule;
// Minimum for parcels to work is 64m even if we don't actually use them. // Minimum for parcels to work is 64m even if we don't actually use them.
#pragma warning disable 0429 #pragma warning disable 0429
@ -147,6 +148,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
{ {
m_userManager = m_scene.RequestModuleInterface<IUserManagement>(); m_userManager = m_scene.RequestModuleInterface<IUserManagement>();
m_primCountModule = m_scene.RequestModuleInterface<IPrimCountModule>();
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -306,10 +308,14 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <returns>The parcel created.</returns> /// <returns>The parcel created.</returns>
protected ILandObject CreateDefaultParcel() protected ILandObject CreateDefaultParcel()
{ {
ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); // m_log.DebugFormat(
// "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
return AddLandObject(fullSimParcel); return AddLandObject(fullSimParcel);
} }
@ -579,7 +585,7 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
else else
{ {
m_log.WarnFormat("[LAND]: Invalid local land ID {0}", landLocalID); m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Invalid local land ID {0}", landLocalID);
} }
} }
@ -590,6 +596,11 @@ namespace OpenSim.Region.CoreModules.World.Land
public ILandObject AddLandObject(ILandObject land) public ILandObject AddLandObject(ILandObject land)
{ {
ILandObject new_land = land.Copy(); ILandObject new_land = land.Copy();
// Only now can we add the prim counts to the land object - we rely on the global ID which is generated
// as a random UUID inside LandData initialization
if (m_primCountModule != null)
new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID);
lock (m_landList) lock (m_landList)
{ {
@ -630,7 +641,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{ {
if (m_landIDList[x, y] == local_id) if (m_landIDList[x, y] == local_id)
{ {
m_log.WarnFormat("[LAND]: Not removing land object {0}; still being used at {1}, {2}", m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Not removing land object {0}; still being used at {1}, {2}",
local_id, x, y); local_id, x, y);
return; return;
//throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y);
@ -851,6 +862,10 @@ namespace OpenSim.Region.CoreModules.World.Land
public void EventManagerOnParcelPrimCountUpdate() public void EventManagerOnParcelPrimCountUpdate()
{ {
// m_log.DebugFormat(
// "[LAND MANAGEMENT MODULE]: Triggered EventManagerOnParcelPrimCountUpdate() for {0}",
// m_scene.RegionInfo.RegionName);
ResetAllLandPrimCounts(); ResetAllLandPrimCounts();
EntityBase[] entities = m_scene.Entities.GetEntities(); EntityBase[] entities = m_scene.Entities.GetEntities();
foreach (EntityBase obj in entities) foreach (EntityBase obj in entities)
@ -1198,7 +1213,7 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
else else
{ {
m_log.WarnFormat("[PARCEL]: Invalid land object {0} passed for parcel object owner request", local_id); m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Invalid land object {0} passed for parcel object owner request", local_id);
} }
} }
@ -1361,7 +1376,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{ {
ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
new_land.LandData = data.Copy(); new_land.LandData = data.Copy();
new_land.SetLandBitmapFromByteArray(); new_land.SetLandBitmapFromByteArray();
AddLandObject(new_land); AddLandObject(new_land);
} }
@ -1426,7 +1441,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{ {
IClientAPI client; IClientAPI client;
if (! m_scene.TryGetClient(agentID, out client)) { if (! m_scene.TryGetClient(agentID, out client)) {
m_log.WarnFormat("[LAND] unable to retrieve IClientAPI for {0}", agentID.ToString()); m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to retrieve IClientAPI for {0}", agentID);
return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
} }
@ -1475,7 +1490,7 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
else else
{ {
m_log.WarnFormat("[LAND] unable to find parcelID {0}", parcelID); m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID);
} }
return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
} }
@ -1533,17 +1548,17 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
catch (LLSD.LLSDParseException e) catch (LLSD.LLSDParseException e)
{ {
m_log.ErrorFormat("[LAND] Fetch error: {0}", e.Message); m_log.ErrorFormat("[LAND MANAGEMENT MODULE]: Fetch error: {0}", e.Message);
m_log.ErrorFormat("[LAND] ... in request {0}", request); m_log.ErrorFormat("[LAND MANAGEMENT MODULE]: ... in request {0}", request);
} }
catch(InvalidCastException) catch (InvalidCastException)
{ {
m_log.ErrorFormat("[LAND] Wrong type in request {0}", request); m_log.ErrorFormat("[LAND MANAGEMENT MODULE]: Wrong type in request {0}", request);
} }
LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse(); LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse();
response.parcel_id = parcelID; response.parcel_id = parcelID;
m_log.DebugFormat("[LAND] got parcelID {0}", parcelID); m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelID {0}", parcelID);
return LLSDHelpers.SerialiseLLSDReply(response); return LLSDHelpers.SerialiseLLSDReply(response);
} }
@ -1564,7 +1579,7 @@ namespace OpenSim.Region.CoreModules.World.Land
ExtendedLandData extLandData = new ExtendedLandData(); ExtendedLandData extLandData = new ExtendedLandData();
Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle, Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle,
out extLandData.X, out extLandData.Y); out extLandData.X, out extLandData.Y);
m_log.DebugFormat("[LAND] got parcelinfo request for regionHandle {0}, x/y {1}/{2}", m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
extLandData.RegionHandle, extLandData.X, extLandData.Y); extLandData.RegionHandle, extLandData.X, extLandData.Y);
// for this region or for somewhere else? // for this region or for somewhere else?
@ -1605,7 +1620,7 @@ namespace OpenSim.Region.CoreModules.World.Land
info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y);
} }
// we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark.
m_log.DebugFormat("[LAND] got parcelinfo for parcel {0} in region {1}; sending...", m_log.DebugFormat("[LAND MANAGEMENT MODULE]: got parcelinfo for parcel {0} in region {1}; sending...",
data.LandData.Name, data.RegionHandle); data.LandData.Name, data.RegionHandle);
// HACK for now // HACK for now
RegionInfo r = new RegionInfo(); RegionInfo r = new RegionInfo();
@ -1616,7 +1631,7 @@ namespace OpenSim.Region.CoreModules.World.Land
remoteClient.SendParcelInfo(r, data.LandData, parcelID, data.X, data.Y); remoteClient.SendParcelInfo(r, data.LandData, parcelID, data.X, data.Y);
} }
else else
m_log.Debug("[LAND] got no parcelinfo; not sending"); m_log.Debug("[LAND MANAGEMENT MODULE]: got no parcelinfo; not sending");
} }
public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)

View File

@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land
private int m_lastSeqId = 0; private int m_lastSeqId = 0;
protected LandData m_landData = new LandData(); protected LandData m_landData = new LandData();
protected Scene m_scene; protected Scene m_scene;
protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
@ -79,6 +79,8 @@ namespace OpenSim.Region.CoreModules.World.Land
set { m_landData = value; } set { m_landData = value; }
} }
public IPrimCounts PrimCounts { get; set; }
public UUID RegionUUID public UUID RegionUUID
{ {

View File

@ -51,8 +51,8 @@ namespace OpenSim.Region.CoreModules.World.Land
public class PrimCountModule : IPrimCountModule, INonSharedRegionModule public class PrimCountModule : IPrimCountModule, INonSharedRegionModule
{ {
private static readonly ILog m_log = // private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_Scene; private Scene m_Scene;
private Dictionary<UUID, PrimCounts> m_PrimCounts = private Dictionary<UUID, PrimCounts> m_PrimCounts =
@ -64,10 +64,16 @@ namespace OpenSim.Region.CoreModules.World.Land
private Dictionary<UUID, ParcelCounts> m_ParcelCounts = private Dictionary<UUID, ParcelCounts> m_ParcelCounts =
new Dictionary<UUID, ParcelCounts>(); new Dictionary<UUID, ParcelCounts>();
// For now, a simple simwide taint to get this up. Later parcel based
// taint to allow recounting a parcel if only ownership has changed /// <value>
// without recounting the whole sim. /// For now, a simple simwide taint to get this up. Later parcel based
/// taint to allow recounting a parcel if only ownership has changed
/// without recounting the whole sim.
///
/// We start out tainted so that the first get call resets the various prim counts.
/// <value>
private bool m_Tainted = true; private bool m_Tainted = true;
private Object m_TaintLock = new Object(); private Object m_TaintLock = new Object();
public Type ReplaceableInterface public Type ReplaceableInterface
@ -82,9 +88,10 @@ namespace OpenSim.Region.CoreModules.World.Land
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
{ {
m_Scene = scene; m_Scene = scene;
m_Scene.RegisterModuleInterface<IPrimCountModule>(this);
m_Scene.EventManager.OnParcelPrimCountAdd += m_Scene.EventManager.OnObjectAddedToScene += OnParcelPrimCountAdd;
OnParcelPrimCountAdd;
m_Scene.EventManager.OnObjectBeingRemovedFromScene += m_Scene.EventManager.OnObjectBeingRemovedFromScene +=
OnObjectBeingRemovedFromScene; OnObjectBeingRemovedFromScene;
m_Scene.EventManager.OnParcelPrimCountTainted += m_Scene.EventManager.OnParcelPrimCountTainted +=
@ -156,6 +163,8 @@ namespace OpenSim.Region.CoreModules.World.Land
// NOTE: Call under Taint Lock // NOTE: Call under Taint Lock
private void AddObject(SceneObjectGroup obj) private void AddObject(SceneObjectGroup obj)
{ {
// m_log.DebugFormat("[PRIM COUNT MODULE]: Adding object {0} to prim count", obj.Name);
if (obj.IsAttachment) if (obj.IsAttachment)
return; return;
if (((obj.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)) if (((obj.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0))
@ -164,6 +173,10 @@ namespace OpenSim.Region.CoreModules.World.Land
Vector3 pos = obj.AbsolutePosition; Vector3 pos = obj.AbsolutePosition;
ILandObject landObject = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); ILandObject landObject = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
LandData landData = landObject.LandData; LandData landData = landObject.LandData;
// m_log.DebugFormat(
// "[PRIM COUNT MODULE]: Object {0} is owned by {1} over land owned by {2}",
// obj.Name, obj.OwnerID, landData.OwnerID);
ParcelCounts parcelCounts; ParcelCounts parcelCounts;
if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
@ -218,8 +231,16 @@ namespace OpenSim.Region.CoreModules.World.Land
return primCounts; return primCounts;
} }
/// <summary>
/// Get the number of prims on the parcel that are owned by the parcel owner.
/// </summary>
/// <param name="parcelID"></param>
/// <returns></returns>
public int GetOwnerCount(UUID parcelID) public int GetOwnerCount(UUID parcelID)
{ {
// m_log.DebugFormat("[PRIM COUNT MODULE]: GetOwnerCount for {0}", parcelID);
lock (m_TaintLock) lock (m_TaintLock)
{ {
if (m_Tainted) if (m_Tainted)
@ -232,6 +253,11 @@ namespace OpenSim.Region.CoreModules.World.Land
return 0; return 0;
} }
/// <summary>
/// Get the number of prims on the parcel that have been set to the group that owns the parcel.
/// </summary>
/// <param name="parcelID"></param>
/// <returns></returns>
public int GetGroupCount(UUID parcelID) public int GetGroupCount(UUID parcelID)
{ {
lock (m_TaintLock) lock (m_TaintLock)
@ -246,6 +272,11 @@ namespace OpenSim.Region.CoreModules.World.Land
return 0; return 0;
} }
/// <summary>
/// Get the number of prims on the parcel that are not owned by the parcel owner or set to the parcel group.
/// </summary>
/// <param name="parcelID"></param>
/// <returns></returns>
public int GetOthersCount(UUID parcelID) public int GetOthersCount(UUID parcelID)
{ {
lock (m_TaintLock) lock (m_TaintLock)
@ -260,6 +291,11 @@ namespace OpenSim.Region.CoreModules.World.Land
return 0; return 0;
} }
/// <summary>
/// Get the number of prims that are in the entire simulator for the owner of this parcel.
/// </summary>
/// <param name="parcelID"></param>
/// <returns></returns>
public int GetSimulatorCount(UUID parcelID) public int GetSimulatorCount(UUID parcelID)
{ {
lock (m_TaintLock) lock (m_TaintLock)
@ -278,6 +314,12 @@ namespace OpenSim.Region.CoreModules.World.Land
return 0; return 0;
} }
/// <summary>
/// Get the number of prims that a particular user owns on this parcel.
/// </summary>
/// <param name="parcelID"></param>
/// <param name="userID"></param>
/// <returns></returns>
public int GetUserCount(UUID parcelID, UUID userID) public int GetUserCount(UUID parcelID, UUID userID)
{ {
lock (m_TaintLock) lock (m_TaintLock)
@ -299,18 +341,21 @@ namespace OpenSim.Region.CoreModules.World.Land
// NOTE: This method MUST be called while holding the taint lock! // NOTE: This method MUST be called while holding the taint lock!
private void Recount() private void Recount()
{ {
// m_log.DebugFormat("[PRIM COUNT MODULE]: Recounting prims on {0}", m_Scene.RegionInfo.RegionName);
m_OwnerMap.Clear(); m_OwnerMap.Clear();
m_SimwideCounts.Clear(); m_SimwideCounts.Clear();
m_ParcelCounts.Clear(); m_ParcelCounts.Clear();
List<ILandObject> land = m_Scene.LandChannel.AllParcels(); List<ILandObject> land = m_Scene.LandChannel.AllParcels();
foreach (ILandObject l in land) foreach (ILandObject l in land)
{ {
LandData landData = l.LandData; LandData landData = l.LandData;
m_OwnerMap[landData.GlobalID] = landData.OwnerID; m_OwnerMap[landData.GlobalID] = landData.OwnerID;
m_SimwideCounts[landData.OwnerID] = 0; m_SimwideCounts[landData.OwnerID] = 0;
// m_log.DebugFormat("[PRIM COUNT MODULE]: Adding parcel count for {0}", landData.GlobalID);
m_ParcelCounts[landData.GlobalID] = new ParcelCounts(); m_ParcelCounts[landData.GlobalID] = new ParcelCounts();
} }

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using log4net.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Assets;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.World.Land.Tests
{
[TestFixture]
public class PrimCountModuleTests
{
protected UUID m_userId = new UUID("00000000-0000-0000-0000-100000000000");
protected UUID m_dummyUserId = new UUID("99999999-9999-9999-9999-999999999999");
protected TestScene m_scene;
protected PrimCountModule m_pcm;
protected ILandObject m_lo;
[SetUp]
public void SetUp()
{
m_pcm = new PrimCountModule();
LandManagementModule lmm = new LandManagementModule();
m_scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(m_scene, lmm, m_pcm);
ILandObject lo = new LandObject(m_userId, false, m_scene);
lo.SetLandBitmap(lo.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
m_lo = lmm.AddLandObject(lo);
//scene.loadAllLandObjectsFromStorage(scene.RegionInfo.originRegionID);
}
/// <summary>
/// Test count after a parcel owner owned object is added.
/// </summary>
[Test]
public void TestAddOwnerObject()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
IPrimCounts pc = m_lo.PrimCounts;
Assert.That(pc.Owner, Is.EqualTo(0));
Assert.That(pc.Group, Is.EqualTo(0));
Assert.That(pc.Others, Is.EqualTo(0));
Assert.That(pc.Users[m_userId], Is.EqualTo(0));
Assert.That(pc.Users[m_dummyUserId], Is.EqualTo(0));
Assert.That(pc.Simulator, Is.EqualTo(0));
SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, 0x01);
m_scene.AddNewSceneObject(sog, false);
Assert.That(pc.Owner, Is.EqualTo(3));
Assert.That(pc.Group, Is.EqualTo(0));
Assert.That(pc.Others, Is.EqualTo(0));
Assert.That(pc.Users[m_userId], Is.EqualTo(3));
Assert.That(pc.Users[m_dummyUserId], Is.EqualTo(0));
Assert.That(pc.Simulator, Is.EqualTo(3));
// Add a second object and retest
SceneObjectGroup sog2 = SceneSetupHelpers.CreateSceneObject(2, m_userId, 0x10);
m_scene.AddNewSceneObject(sog2, false);
Assert.That(pc.Owner, Is.EqualTo(5));
Assert.That(pc.Group, Is.EqualTo(0));
Assert.That(pc.Others, Is.EqualTo(0));
Assert.That(pc.Users[m_userId], Is.EqualTo(5));
Assert.That(pc.Users[m_dummyUserId], Is.EqualTo(0));
Assert.That(pc.Simulator, Is.EqualTo(5));
}
/// <summary>
/// Test count after a parcel owner owned object is removed.
/// </summary>
[Test]
public void TestRemoveOwnerObject()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
IPrimCounts pc = m_lo.PrimCounts;
m_scene.AddNewSceneObject(SceneSetupHelpers.CreateSceneObject(1, m_userId, 0x1), false);
SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_userId, 0x10);
m_scene.AddNewSceneObject(sogToDelete, false);
m_scene.DeleteSceneObject(sogToDelete, false);
Assert.That(pc.Owner, Is.EqualTo(1));
Assert.That(pc.Group, Is.EqualTo(0));
Assert.That(pc.Others, Is.EqualTo(0));
Assert.That(pc.Users[m_userId], Is.EqualTo(1));
Assert.That(pc.Users[m_dummyUserId], Is.EqualTo(0));
Assert.That(pc.Simulator, Is.EqualTo(1));
}
}
}

View File

@ -188,17 +188,17 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
} }
catch (DllNotFoundException) catch (DllNotFoundException)
{ {
m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg is not installed correctly on this system. Asset Data is emtpy for {0}", id); m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id);
} }
catch (IndexOutOfRangeException) catch (IndexOutOfRangeException)
{ {
m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is emtpy for {0}", id); m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id);
} }
catch (Exception) catch (Exception)
{ {
m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is emtpy for {0}", id); m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id);
} }
return null; return null;

View File

@ -50,7 +50,7 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
using OSDArray = OpenMetaverse.StructuredData.OSDArray; using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap; using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.CoreModules.Media.Moap namespace OpenSim.Region.CoreModules.World.Media.Moap
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
public class MoapModule : INonSharedRegionModule, IMoapModule public class MoapModule : INonSharedRegionModule, IMoapModule
@ -225,24 +225,62 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return me; return me;
} }
/// <summary>
/// Set the media entry on the face of the given part.
/// </summary>
/// <param name="part">/param>
/// <param name="face"></param>
/// <param name="me">If null, then the media entry is cleared.</param>
public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me) public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me)
{ {
// m_log.DebugFormat("[MOAP]: SetMediaEntry for {0}, face {1}", part.Name, face);
CheckFaceParam(part, face); CheckFaceParam(part, face);
if (null == part.Shape.Media) if (null == part.Shape.Media)
part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]); {
if (me == null)
return;
else
part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]);
}
lock (part.Shape.Media) lock (part.Shape.Media)
part.Shape.Media[face] = me; part.Shape.Media[face] = me;
UpdateMediaUrl(part, UUID.Zero); UpdateMediaUrl(part, UUID.Zero);
SetPartMediaFlags(part, face, me != null);
part.ScheduleFullUpdate(); part.ScheduleFullUpdate();
part.TriggerScriptChangedEvent(Changed.MEDIA); part.TriggerScriptChangedEvent(Changed.MEDIA);
} }
/// <summary>
/// Clear the media entry from the face of the given part.
/// </summary>
/// <param name="part"></param>
/// <param name="face"></param>
public void ClearMediaEntry(SceneObjectPart part, int face) public void ClearMediaEntry(SceneObjectPart part, int face)
{ {
SetMediaEntry(part, face, null); SetMediaEntry(part, face, null);
}
/// <summary>
/// Set the media flags on the texture face of the given part.
/// </summary>
/// <remarks>
/// The fact that we need a separate function to do what should be a simple one line operation is BUTT UGLY.
/// </remarks>
/// <param name="part"></param>
/// <param name="face"></param>
/// <param name="flag"></param>
protected void SetPartMediaFlags(SceneObjectPart part, int face, bool flag)
{
Primitive.TextureEntry te = part.Shape.Textures;
Primitive.TextureEntryFace teFace = te.CreateFace((uint)face);
teFace.MediaFlags = flag;
part.Shape.Textures = te;
} }
/// <summary> /// <summary>
@ -333,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
} }
// m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId); // m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
//
// for (int i = 0; i < omu.FaceMedia.Length; i++) // for (int i = 0; i < omu.FaceMedia.Length; i++)
// { // {
// MediaEntry me = omu.FaceMedia[i]; // MediaEntry me = omu.FaceMedia[i];
@ -368,10 +406,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// FIXME: Race condition here since some other texture entry manipulator may overwrite/get // FIXME: Race condition here since some other texture entry manipulator may overwrite/get
// overwritten. Unfortunately, PrimitiveBaseShape does not allow us to change texture entry // overwritten. Unfortunately, PrimitiveBaseShape does not allow us to change texture entry
// directly. // directly.
Primitive.TextureEntry te = part.Shape.Textures; SetPartMediaFlags(part, i, true);
Primitive.TextureEntryFace face = te.CreateFace((uint)i);
face.MediaFlags = true;
part.Shape.Textures = te;
// m_log.DebugFormat( // m_log.DebugFormat(
// "[MOAP]: Media flags for face {0} is {1}", // "[MOAP]: Media flags for face {0} is {1}",
// i, part.Shape.Textures.FaceTextures[i].MediaFlags); // i, part.Shape.Textures.FaceTextures[i].MediaFlags);
@ -380,6 +415,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
} }
else else
{ {
// m_log.DebugFormat("[MOAP]: Setting existing media list for {0}", part.Name);
// We need to go through the media textures one at a time to make sure that we have permission // We need to go through the media textures one at a time to make sure that we have permission
// to change them // to change them
@ -401,8 +438,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (null == media[i]) if (null == media[i])
continue; continue;
Primitive.TextureEntryFace face = te.CreateFace((uint)i); SetPartMediaFlags(part, i, true);
face.MediaFlags = true;
// m_log.DebugFormat( // m_log.DebugFormat(
// "[MOAP]: Media flags for face {0} is {1}", // "[MOAP]: Media flags for face {0} is {1}",

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using log4net.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Assets;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.World.Media.Moap;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
{
[TestFixture]
public class MoapTests
{
protected TestScene m_scene;
protected MoapModule m_module;
[SetUp]
public void SetUp()
{
m_module = new MoapModule();
m_scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(m_scene, m_module);
}
[Test]
public void TestClearMediaUrl()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
SceneObjectPart part = SceneSetupHelpers.AddSceneObject(m_scene);
MediaEntry me = new MediaEntry();
m_module.SetMediaEntry(part, 1, me);
m_module.ClearMediaEntry(part, 1);
Assert.That(part.Shape.Media[1], Is.EqualTo(null));
// Although we've cleared one face, other faces may still be present. So we need to check for an
// update media url version
Assert.That(part.MediaUrl, Is.EqualTo("x-mv:0000000001/" + UUID.Zero));
// By changing media flag to false, the face texture once again becomes identical to the DefaultTexture.
// Therefore, when libOMV reserializes it, it disappears and we are left with no face texture in this slot.
// Not at all confusing, eh?
Assert.That(part.Shape.Textures.FaceTextures[1], Is.Null);
}
[Test]
public void TestSetMediaUrl()
{
TestHelper.InMethod();
string homeUrl = "opensimulator.org";
SceneObjectPart part = SceneSetupHelpers.AddSceneObject(m_scene);
MediaEntry me = new MediaEntry() { HomeURL = homeUrl };
m_module.SetMediaEntry(part, 1, me);
Assert.That(part.Shape.Media[1].HomeURL, Is.EqualTo(homeUrl));
Assert.That(part.MediaUrl, Is.EqualTo("x-mv:0000000000/" + UUID.Zero));
Assert.That(part.Shape.Textures.FaceTextures[1].MediaFlags, Is.True);
}
}
}

View File

@ -642,7 +642,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
/// implemented by callers. /// implemented by callers.
/// </summary> /// </summary>
/// <param name="currentUser"></param> /// <param name="currentUser"></param>
/// <param name="objId"></param> /// <param name="objId">This is a scene object group UUID</param>
/// <param name="denyOnLocked"></param> /// <param name="denyOnLocked"></param>
/// <returns></returns> /// <returns></returns>
protected bool GenericObjectPermission(UUID currentUser, UUID objId, bool denyOnLocked) protected bool GenericObjectPermission(UUID currentUser, UUID objId, bool denyOnLocked)
@ -1896,7 +1896,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// "[PERMISSIONS]: Checking CanControlPrimMedia for {0} on {1} face {2} with control permissions {3}", // "[PERMISSIONS]: Checking CanControlPrimMedia for {0} on {1} face {2} with control permissions {3}",
// agentID, primID, face, me.ControlPermissions); // agentID, primID, face, me.ControlPermissions);
return GenericPrimMediaPermission(part, agentID, me.ControlPermissions); return GenericObjectPermission(agentID, part.ParentGroup.UUID, true);
} }
private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int face) private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int face)

View File

@ -30,7 +30,6 @@ using System.IO;
using System.Xml; using System.Xml;
using log4net.Config; using log4net.Config;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -62,9 +62,20 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
return LoadBitmap(new Bitmap(filename)); return LoadBitmap(new Bitmap(filename));
} }
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) public virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h)
{ {
throw new NotImplementedException(); Bitmap bitmap = new Bitmap(filename);
ITerrainChannel retval = new TerrainChannel(true);
for (int x = 0; x < retval.Width; x++)
{
for (int y = 0; y < retval.Height; y++)
{
retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128;
}
}
return retval;
} }
public virtual ITerrainChannel LoadStream(Stream stream) public virtual ITerrainChannel LoadStream(Stream stream)

View File

@ -100,8 +100,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
// service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region
regionInfos = new List<GridRegion>(); regionInfos = new List<GridRegion>();
GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName); GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName);
if (info != null) regionInfos.Add(info); if (info != null)
regionInfos.Add(info);
} }
else if (regionInfos.Count == 0 && mapName.StartsWith("http://"))
remoteClient.SendAlertMessage("Hyperlink could not be established.");
m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
List<MapBlockData> blocks = new List<MapBlockData>(); List<MapBlockData> blocks = new List<MapBlockData>();
@ -113,7 +117,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
data = new MapBlockData(); data = new MapBlockData();
data.Agents = 0; data.Agents = 0;
data.Access = info.Access; data.Access = info.Access;
data.MapImageId = info.TerrainImage; data.MapImageId = UUID.Zero; // could use info.TerrainImage but it seems to break viewer2
data.Name = info.RegionName; data.Name = info.RegionName;
data.RegionFlags = 0; // TODO not used? data.RegionFlags = 0; // TODO not used?
data.WaterHeight = 0; // not used data.WaterHeight = 0; // not used
@ -135,7 +139,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
data.Y = 0; data.Y = 0;
blocks.Add(data); blocks.Add(data);
remoteClient.SendMapBlock(blocks, 0); // not sure what the flags do here, but seems to be necessary
// to set to "2" for viewer 2
remoteClient.SendMapBlock(blocks, 2);
} }
// private Scene GetClientScene(IClientAPI client) // private Scene GetClientScene(IClientAPI client)

View File

@ -764,10 +764,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
if (!responseMap.ContainsKey(itemtype.ToString())) // remote sim doesnt have the stated region handle if (!responseMap.ContainsKey(itemtype.ToString())) // remote sim doesnt have the stated region handle
{ {
if (!m_blacklistedregions.ContainsKey(regionhandle)) m_log.DebugFormat("[WORLD MAP]: Remote sim does not have the stated region. Blacklisting.");
lock (m_blacklistedregions)
{ {
m_log.DebugFormat("[WORLD MAP]: Remote sim does not have the stated region. Blacklisting."); if (!m_blacklistedregions.ContainsKey(regionhandle))
m_blacklistedregions.Add(regionhandle, Environment.TickCount); m_blacklistedregions.Add(regionhandle, Environment.TickCount);
} }
} }

View File

@ -34,12 +34,68 @@ namespace OpenSim.Region.Framework.Interfaces
{ {
public interface IEstateDataService public interface IEstateDataService
{ {
/// <summary>
/// Load estate settings for a region.
/// </summary>
/// <param name="regionID"></param>
/// <param name="create">If true, then an estate is created if one is not found.</param>
/// <returns></returns>
EstateSettings LoadEstateSettings(UUID regionID, bool create); EstateSettings LoadEstateSettings(UUID regionID, bool create);
/// <summary>
/// Load estate settings for an estate ID.
/// </summary>
/// <param name="estateID"></param>
/// <returns></returns>
EstateSettings LoadEstateSettings(int estateID); EstateSettings LoadEstateSettings(int estateID);
/// <summary>
/// Load/Get all estate settings.
/// </summary>
/// <returns>An empty list if no estates were found.</returns>
List<EstateSettings> LoadEstateSettingsAll();
/// <summary>
/// Store estate settings.
/// </summary>
/// <remarks>
/// This is also called by EstateSettings.Save()</remarks>
/// <param name="es"></param>
void StoreEstateSettings(EstateSettings es); void StoreEstateSettings(EstateSettings es);
/// <summary>
/// Get estate IDs.
/// </summary>
/// <param name="search">Name of estate to search for. This is the exact name, no parttern matching is done.</param>
/// <returns></returns>
List<int> GetEstates(string search); List<int> GetEstates(string search);
/// <summary>
/// Get the IDs of all estates.
/// </summary>
/// <returns>An empty list if no estates were found.</returns>
List<int> GetEstatesAll();
/// <summary>
/// Link a region to an estate.
/// </summary>
/// <param name="regionID"></param>
/// <param name="estateID"></param>
/// <returns>true if the link succeeded, false otherwise</returns>
bool LinkRegion(UUID regionID, int estateID); bool LinkRegion(UUID regionID, int estateID);
/// <summary>
/// Get the UUIDs of all the regions in an estate.
/// </summary>
/// <param name="estateID"></param>
/// <returns></returns>
List<UUID> GetRegions(int estateID); List<UUID> GetRegions(int estateID);
/// <summary>
/// Delete an estate
/// </summary>
/// <param name="estateID"></param>
/// <returns>true if the delete succeeded, false otherwise</returns>
bool DeleteEstate(int estateID); bool DeleteEstate(int estateID);
} }
} }

View File

@ -33,14 +33,74 @@ namespace OpenSim.Region.Framework.Interfaces
{ {
public interface IEstateDataStore public interface IEstateDataStore
{ {
/// <summary>
/// Initialise the data store.
/// </summary>
/// <param name="connectstring"></param>
void Initialise(string connectstring); void Initialise(string connectstring);
/// <summary>
/// Load estate settings for a region.
/// </summary>
/// <param name="regionID"></param>
/// <param name="create">If true, then an estate is created if one is not found.</param>
/// <returns></returns>
EstateSettings LoadEstateSettings(UUID regionID, bool create); EstateSettings LoadEstateSettings(UUID regionID, bool create);
/// <summary>
/// Load estate settings for an estate ID.
/// </summary>
/// <param name="estateID"></param>
/// <returns></returns>
EstateSettings LoadEstateSettings(int estateID); EstateSettings LoadEstateSettings(int estateID);
/// <summary>
/// Load/Get all estate settings.
/// </summary>
/// <returns>An empty list if no estates were found.</returns>
List<EstateSettings> LoadEstateSettingsAll();
/// <summary>
/// Store estate settings.
/// </summary>
/// <remarks>
/// This is also called by EstateSettings.Save()</remarks>
/// <param name="es"></param>
void StoreEstateSettings(EstateSettings es); void StoreEstateSettings(EstateSettings es);
/// <summary>
/// Get estate IDs.
/// </summary>
/// <param name="search">Name of estate to search for. This is the exact name, no parttern matching is done.</param>
/// <returns></returns>
List<int> GetEstates(string search); List<int> GetEstates(string search);
/// <summary>
/// Get the IDs of all estates.
/// </summary>
/// <returns>An empty list if no estates were found.</returns>
List<int> GetEstatesAll();
/// <summary>
/// Link a region to an estate.
/// </summary>
/// <param name="regionID"></param>
/// <param name="estateID"></param>
/// <returns>true if the link succeeded, false otherwise</returns>
bool LinkRegion(UUID regionID, int estateID); bool LinkRegion(UUID regionID, int estateID);
/// <summary>
/// Get the UUIDs of all the regions in an estate.
/// </summary>
/// <param name="estateID"></param>
/// <returns></returns>
List<UUID> GetRegions(int estateID); List<UUID> GetRegions(int estateID);
/// <summary>
/// Delete an estate
/// </summary>
/// <param name="estateID"></param>
/// <returns>true if the delete succeeded, false otherwise</returns>
bool DeleteEstate(int estateID); bool DeleteEstate(int estateID);
} }
} }

View File

@ -32,7 +32,7 @@ namespace OpenSim.Region.Framework.Interfaces
public delegate void ChangeDelegate(UUID regionID); public delegate void ChangeDelegate(UUID regionID);
public delegate void MessageDelegate(UUID regionID, UUID fromID, string fromName, string message); public delegate void MessageDelegate(UUID regionID, UUID fromID, string fromName, string message);
public interface IEstateModule : IRegionModule public interface IEstateModule
{ {
event ChangeDelegate OnRegionInfoChange; event ChangeDelegate OnRegionInfoChange;
event ChangeDelegate OnEstateInfoChange; event ChangeDelegate OnEstateInfoChange;

View File

@ -45,6 +45,11 @@ namespace OpenSim.Region.Framework.Interfaces
bool[,] LandBitmap { get; set; } bool[,] LandBitmap { get; set; }
UUID RegionUUID { get; } UUID RegionUUID { get; }
/// <summary>
/// Prim counts for this land object.
/// </summary>
IPrimCounts PrimCounts { get; set; }
/// <summary> /// <summary>
/// The start point for the land object. This is the western-most point as one scans land working from /// The start point for the land object. This is the western-most point as one scans land working from
/// north to south. /// north to south.

View File

@ -36,5 +36,6 @@ namespace OpenSim.Region.Framework.Interfaces
void Close(); void Close();
void QueuePartForUpdate(SceneObjectPart part); void QueuePartForUpdate(SceneObjectPart part);
void SendPrimUpdates(); void SendPrimUpdates();
int GetPendingObjectsCount();
} }
} }

View File

@ -242,7 +242,15 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID); public delegate void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID);
public event EstateToolsSunUpdate OnEstateToolsSunUpdate; public event EstateToolsSunUpdate OnEstateToolsSunUpdate;
/// <summary>
/// Triggered when an object is added to the scene.
/// </summary>
public event Action<SceneObjectGroup> OnObjectAddedToScene;
/// <summary>
/// Triggered when an object is removed from the scene.
/// </summary>
public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj); public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj);
public event ObjectBeingRemovedFromScene OnObjectBeingRemovedFromScene; public event ObjectBeingRemovedFromScene OnObjectBeingRemovedFromScene;
@ -345,6 +353,7 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void Attach(uint localID, UUID itemID, UUID avatarID); public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
public event Attach OnAttach; public event Attach OnAttach;
/// <summary> /// <summary>
/// Called immediately after an object is loaded from storage. /// Called immediately after an object is loaded from storage.
/// </summary> /// </summary>
@ -800,6 +809,27 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerObjectAddedToScene(SceneObjectGroup obj)
{
Action<SceneObjectGroup> handler = OnObjectAddedToScene;
if (handler != null)
{
foreach (Action<SceneObjectGroup> d in handler.GetInvocationList())
{
try
{
d(obj);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerObjectAddedToScene failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
public void TriggerObjectBeingRemovedFromScene(SceneObjectGroup obj) public void TriggerObjectBeingRemovedFromScene(SceneObjectGroup obj)
{ {
ObjectBeingRemovedFromScene handlerObjectBeingRemovedFromScene = OnObjectBeingRemovedFromScene; ObjectBeingRemovedFromScene handlerObjectBeingRemovedFromScene = OnObjectBeingRemovedFromScene;

View File

@ -321,6 +321,8 @@ namespace OpenSim.Region.Framework.Scenes
// Passing something to another avatar or a an object will already // Passing something to another avatar or a an object will already
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = InventoryService.GetItem(item); item = InventoryService.GetItem(item);
if (item.Owner != remoteClient.AgentId)
return;
if (item != null) if (item != null)
{ {

View File

@ -64,6 +64,8 @@ namespace OpenSim.Region.Framework.Scenes
#region Fields #region Fields
public bool EmergencyMonitoring = false;
public SynchronizeSceneHandler SynchronizeScene; public SynchronizeSceneHandler SynchronizeScene;
public SimStatsReporter StatsReporter; public SimStatsReporter StatsReporter;
public List<Border> NorthBorders = new List<Border>(); public List<Border> NorthBorders = new List<Border>();
@ -81,6 +83,13 @@ namespace OpenSim.Region.Framework.Scenes
public bool m_useFlySlow; public bool m_useFlySlow;
public bool m_usePreJump; public bool m_usePreJump;
public bool m_seeIntoRegionFromNeighbor; public bool m_seeIntoRegionFromNeighbor;
protected float m_defaultDrawDistance = 255.0f;
public float DefaultDrawDistance
{
get { return m_defaultDrawDistance; }
}
// TODO: need to figure out how allow client agents but deny // TODO: need to figure out how allow client agents but deny
// 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;
@ -127,7 +136,16 @@ namespace OpenSim.Region.Framework.Scenes
protected ICapabilitiesModule m_capsModule; protected ICapabilitiesModule m_capsModule;
// Central Update Loop // Central Update Loop
protected int m_fps = 10; protected int m_fps = 10;
protected uint m_frame;
/// <summary>
/// Current scene frame number
/// </summary>
public uint Frame
{
get;
protected set;
}
protected float m_timespan = 0.089f; protected float m_timespan = 0.089f;
protected DateTime m_lastupdate = DateTime.UtcNow; protected DateTime m_lastupdate = DateTime.UtcNow;
@ -616,6 +634,8 @@ namespace OpenSim.Region.Framework.Scenes
// //
IConfig startupConfig = m_config.Configs["Startup"]; IConfig startupConfig = m_config.Configs["Startup"];
m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance);
//Animation states //Animation states
m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
// TODO: Change default to true once the feature is supported // TODO: Change default to true once the feature is supported
@ -1089,7 +1109,7 @@ namespace OpenSim.Region.Framework.Scenes
// //
while (m_regInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null) while (m_regInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
{ {
MainConsole.Instance.Output("The current estate has no owner set."); MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", m_regInfo.EstateSettings.EstateName);
List<char> excluded = new List<char>(new char[1]{' '}); List<char> excluded = new List<char>(new char[1]{' '});
string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded); string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded); string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
@ -1181,7 +1201,8 @@ namespace OpenSim.Region.Framework.Scenes
try try
{ {
Update(); while (!shuttingdown)
Update();
m_lastUpdate = Util.EnvironmentTickCount(); m_lastUpdate = Util.EnvironmentTickCount();
m_firstHeartbeat = false; m_firstHeartbeat = false;
@ -1198,187 +1219,176 @@ namespace OpenSim.Region.Framework.Scenes
Watchdog.RemoveThread(); Watchdog.RemoveThread();
} }
/// <summary>
/// Performs per-frame updates on the scene, this should be the central scene loop
/// </summary>
public override void Update() public override void Update()
{ {
float physicsFPS; TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
int maintc; float physicsFPS = 0f;
while (!shuttingdown) int maintc = Util.EnvironmentTickCount();
int tmpFrameMS = maintc;
tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
// Increment the frame counter
++Frame;
try
{ {
TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; // Check if any objects have reached their targets
physicsFPS = 0f; CheckAtTargets();
maintc = Util.EnvironmentTickCount(); // Update SceneObjectGroups that have scheduled themselves for updates
int tmpFrameMS = maintc; // Objects queue their updates onto all scene presences
tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; if (Frame % m_update_objects == 0)
m_sceneGraph.UpdateObjectGroups();
// Increment the frame counter // Run through all ScenePresences looking for updates
++m_frame; // Presence updates and queued object updates for each presence are sent to clients
if (Frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences();
try // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
if (Frame % m_update_coarse_locations == 0)
{ {
// Check if any objects have reached their targets List<Vector3> coarseLocations;
CheckAtTargets(); List<UUID> avatarUUIDs;
SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
// Update SceneObjectGroups that have scheduled themselves for updates // Send coarse locations to clients
// Objects queue their updates onto all scene presences ForEachScenePresence(delegate(ScenePresence presence)
if (m_frame % m_update_objects == 0)
m_sceneGraph.UpdateObjectGroups();
// Run through all ScenePresences looking for updates
// Presence updates and queued object updates for each presence are sent to clients
if (m_frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences();
// Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
if (m_frame % m_update_coarse_locations == 0)
{ {
List<Vector3> coarseLocations; presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
List<UUID> avatarUUIDs; });
SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); }
// Send coarse locations to clients
ForEachScenePresence(delegate(ScenePresence presence) int tmpPhysicsMS2 = Util.EnvironmentTickCount();
{ if ((Frame % m_update_physics == 0) && m_physics_enabled)
presence.SendCoarseLocations(coarseLocations, avatarUUIDs); m_sceneGraph.UpdatePreparePhysics();
}); physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
// Apply any pending avatar force input to the avatar's velocity
if (Frame % m_update_entitymovement == 0)
m_sceneGraph.UpdateScenePresenceMovement();
// Perform the main physics update. This will do the actual work of moving objects and avatars according to their
// velocity
int tmpPhysicsMS = Util.EnvironmentTickCount();
if (Frame % m_update_physics == 0)
{
if (m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
if (SynchronizeScene != null)
SynchronizeScene(this);
}
physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
// Delete temp-on-rez stuff
if (Frame % 1000 == 0 && !m_cleaningTemps)
{
int tmpTempOnRezMS = Util.EnvironmentTickCount();
m_cleaningTemps = true;
Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
}
if (RegionStatus != RegionStatus.SlaveScene)
{
if (Frame % m_update_events == 0)
{
int evMS = Util.EnvironmentTickCount();
UpdateEvents();
eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
} }
int tmpPhysicsMS2 = Util.EnvironmentTickCount(); if (Frame % m_update_backup == 0)
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
m_sceneGraph.UpdatePreparePhysics();
physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
// Apply any pending avatar force input to the avatar's velocity
if (m_frame % m_update_entitymovement == 0)
m_sceneGraph.UpdateScenePresenceMovement();
// Perform the main physics update. This will do the actual work of moving objects and avatars according to their
// velocity
int tmpPhysicsMS = Util.EnvironmentTickCount();
if (m_frame % m_update_physics == 0)
{ {
if (m_physics_enabled) int backMS = Util.EnvironmentTickCount();
physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan)); UpdateStorageBackup();
if (SynchronizeScene != null) backupMS = Util.EnvironmentTickCountSubtract(backMS);
SynchronizeScene(this);
}
physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
// Delete temp-on-rez stuff
if (m_frame % 1000 == 0 && !m_cleaningTemps)
{
int tmpTempOnRezMS = Util.EnvironmentTickCount();
m_cleaningTemps = true;
Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
} }
if (RegionStatus != RegionStatus.SlaveScene) if (Frame % m_update_terrain == 0)
{ {
if (m_frame % m_update_events == 0) int terMS = Util.EnvironmentTickCount();
{ UpdateTerrain();
int evMS = Util.EnvironmentTickCount(); terrainMS = Util.EnvironmentTickCountSubtract(terMS);
UpdateEvents();
eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
}
if (m_frame % m_update_backup == 0)
{
int backMS = Util.EnvironmentTickCount();
UpdateStorageBackup();
backupMS = Util.EnvironmentTickCountSubtract(backMS);
}
if (m_frame % m_update_terrain == 0)
{
int terMS = Util.EnvironmentTickCount();
UpdateTerrain();
terrainMS = Util.EnvironmentTickCountSubtract(terMS);
}
//if (m_frame % m_update_land == 0)
//{
// int ldMS = Util.EnvironmentTickCount();
// UpdateLand();
// landMS = Util.EnvironmentTickCountSubtract(ldMS);
//}
frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
lastCompletedFrame = Util.EnvironmentTickCount();
// if (m_frame%m_update_avatars == 0)
// UpdateInWorldTime();
StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
StatsReporter.addFrameMS(frameMS);
StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
} }
if (LoginsDisabled && m_frame == 20) //if (Frame % m_update_land == 0)
{ //{
// In 99.9% of cases it is a bad idea to manually force garbage collection. However, // int ldMS = Util.EnvironmentTickCount();
// this is a rare case where we know we have just went through a long cycle of heap // UpdateLand();
// allocations, and there is no more work to be done until someone logs in // landMS = Util.EnvironmentTickCountSubtract(ldMS);
GC.Collect(); //}
IConfig startupConfig = m_config.Configs["Startup"]; frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
{ lastCompletedFrame = Util.EnvironmentTickCount();
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
LoginsDisabled = false; // if (Frame%m_update_avatars == 0)
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); // UpdateInWorldTime();
} StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
StatsReporter.addFrameMS(frameMS);
StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
}
if (LoginsDisabled && Frame == 20)
{
// In 99.9% of cases it is a bad idea to manually force garbage collection. However,
// this is a rare case where we know we have just went through a long cycle of heap
// allocations, and there is no more work to be done until someone logs in
GC.Collect();
IConfig startupConfig = m_config.Configs["Startup"];
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
{
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
LoginsDisabled = false;
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
} }
} }
catch (NotImplementedException)
{
throw;
}
catch (AccessViolationException e)
{
m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
//catch (NullReferenceException e)
//{
// m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
//}
catch (InvalidOperationException e)
{
m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
catch (Exception e)
{
m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
finally
{
m_lastupdate = DateTime.UtcNow;
}
maintc = Util.EnvironmentTickCountSubtract(maintc);
maintc = (int)(m_timespan * 1000) - maintc;
if (maintc > 0)
Thread.Sleep(maintc);
// Tell the watchdog that this thread is still alive
Watchdog.UpdateThread();
} }
} catch (NotImplementedException)
{
throw;
}
catch (AccessViolationException e)
{
m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
//catch (NullReferenceException e)
//{
// m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
//}
catch (InvalidOperationException e)
{
m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
catch (Exception e)
{
m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
finally
{
m_lastupdate = DateTime.UtcNow;
}
maintc = Util.EnvironmentTickCountSubtract(maintc);
maintc = (int)(m_timespan * 1000) - maintc;
if (maintc > 0)
Thread.Sleep(maintc);
// Tell the watchdog that this thread is still alive
Watchdog.UpdateThread();
}
public void AddGroupTarget(SceneObjectGroup grp) public void AddGroupTarget(SceneObjectGroup grp)
{ {
@ -1946,8 +1956,14 @@ namespace OpenSim.Region.Framework.Scenes
/// If false, it is left to the caller to schedule the update /// If false, it is left to the caller to schedule the update
/// </param> /// </param>
public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
{ {
return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates))
{
EventManager.TriggerObjectAddedToScene(sceneObject);
return true;
}
return false;
} }
/// <summary> /// <summary>
@ -1964,7 +1980,13 @@ namespace OpenSim.Region.Framework.Scenes
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)
{ {
return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel); if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel))
{
EventManager.TriggerObjectAddedToScene(sceneObject);
return true;
}
return false;
} }
/// <summary> /// <summary>
@ -3009,7 +3031,9 @@ namespace OpenSim.Region.Framework.Scenes
(childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName); (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
m_sceneGraph.removeUserCount(!childagentYN); m_sceneGraph.removeUserCount(!childagentYN);
CapsModule.RemoveCapsHandler(agentID);
if (CapsModule != null)
CapsModule.RemoveCapsHandler(agentID);
// REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
// this method is doing is HORRIBLE!!! // this method is doing is HORRIBLE!!!
@ -3198,7 +3222,7 @@ namespace OpenSim.Region.Framework.Scenes
// TeleportFlags.ViaLandmark | TeleportFlags.ViaLocation | TeleportFlags.ViaLandmark | TeleportFlags.Default - Regular Teleport // TeleportFlags.ViaLandmark | TeleportFlags.ViaLocation | TeleportFlags.ViaLandmark | TeleportFlags.Default - Regular Teleport
// Don't disable this log message - it's too helpful // Don't disable this log message - it's too helpful
m_log.InfoFormat( m_log.DebugFormat(
"[CONNECTION BEGIN]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, teleportflags {6})", "[CONNECTION BEGIN]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, teleportflags {6})",
RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
agent.AgentID, agent.circuitcode, teleportFlags); agent.AgentID, agent.circuitcode, teleportFlags);
@ -3264,8 +3288,11 @@ namespace OpenSim.Region.Framework.Scenes
RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
agent.AgentID, agent.circuitcode); agent.AgentID, agent.circuitcode);
CapsModule.NewUserConnection(agent); if (CapsModule != null)
CapsModule.AddCapsHandler(agent.AgentID); {
CapsModule.NewUserConnection(agent);
CapsModule.AddCapsHandler(agent.AgentID);
}
} }
else else
{ {
@ -3280,7 +3307,9 @@ namespace OpenSim.Region.Framework.Scenes
agent.AgentID, RegionInfo.RegionName); agent.AgentID, RegionInfo.RegionName);
sp.AdjustKnownSeeds(); sp.AdjustKnownSeeds();
CapsModule.NewUserConnection(agent);
if (CapsModule != null)
CapsModule.NewUserConnection(agent);
} }
} }
@ -3768,15 +3797,15 @@ namespace OpenSim.Region.Framework.Scenes
public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
Vector3 lookat, uint teleportFlags) Vector3 lookat, uint teleportFlags)
{ {
GridRegion regionInfo = GridService.GetRegionByName(UUID.Zero, regionName); List<GridRegion> regions = GridService.GetRegionsByName(RegionInfo.ScopeID, regionName, 1);
if (regionInfo == null) if (regions == null || regions.Count == 0)
{ {
// can't find the region: Tell viewer and abort // can't find the region: Tell viewer and abort
remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
return; return;
} }
RequestTeleportLocation(remoteClient, regionInfo.RegionHandle, position, lookat, teleportFlags); RequestTeleportLocation(remoteClient, regions[0].RegionHandle, position, lookat, teleportFlags);
} }
/// <summary> /// <summary>
@ -4921,8 +4950,9 @@ namespace OpenSim.Region.Framework.Scenes
// from logging into the region, teleporting into the region // from logging into the region, teleporting into the region
// or corssing the broder walking, but will NOT prevent // or corssing the broder walking, but will NOT prevent
// child agent creation, thereby emulating the SL behavior. // child agent creation, thereby emulating the SL behavior.
public bool QueryAccess(UUID agentID, Vector3 position) public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
{ {
reason = String.Empty;
return true; return true;
} }
} }

View File

@ -193,7 +193,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, ulong regionHandle); public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest);
/// <summary> /// <summary>
/// This informs all neighboring regions about the settings of it's child agent. /// This informs all neighboring regions about the settings of it's child agent.
@ -202,31 +203,17 @@ namespace OpenSim.Region.Framework.Scenes
/// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc.
/// ///
/// </summary> /// </summary>
private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, ulong regionHandle) private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, GridRegion dest)
{ {
//m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName);
try try
{ {
//m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); m_scene.SimulationService.UpdateAgent(dest, cAgentData);
uint x = 0, y = 0;
Utils.LongToUInts(regionHandle, out x, out y);
GridRegion destination = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
m_scene.SimulationService.UpdateAgent(destination, cAgentData);
} }
catch catch
{ {
// Ignore; we did our best // Ignore; we did our best
} }
//if (regionAccepted)
//{
// //m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent");
//}
//else
//{
// //m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent");
//}
} }
private void SendChildAgentDataUpdateCompleted(IAsyncResult iar) private void SendChildAgentDataUpdateCompleted(IAsyncResult iar)
@ -240,14 +227,28 @@ namespace OpenSim.Region.Framework.Scenes
// This assumes that we know what our neighbors are. // This assumes that we know what our neighbors are.
try try
{ {
uint x = 0, y = 0;
List<string> simulatorList = new List<string>();
foreach (ulong regionHandle in presence.KnownChildRegionHandles) foreach (ulong regionHandle in presence.KnownChildRegionHandles)
{ {
if (regionHandle != m_regionInfo.RegionHandle) if (regionHandle != m_regionInfo.RegionHandle)
{ {
SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; // we only want to send one update to each simulator; the simulator will
d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, regionHandle, // hand it off to the regions where a child agent exists, this does assume
SendChildAgentDataUpdateCompleted, // that the region position is cached or performance will degrade
d); Utils.LongToUInts(regionHandle, out x, out y);
GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
if (! simulatorList.Contains(dest.ServerURI))
{
// we havent seen this simulator before, add it to the list
// and send it an update
simulatorList.Add(dest.ServerURI);
SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
SendChildAgentDataUpdateCompleted,
d);
}
} }
} }
} }

View File

@ -88,9 +88,21 @@ namespace OpenSim.Region.Framework.Scenes
protected internal object m_syncRoot = new object(); protected internal object m_syncRoot = new object();
protected internal PhysicsScene _PhyScene; protected internal PhysicsScene _PhyScene;
protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalID = new Dictionary<uint, SceneObjectGroup>(); /// <summary>
/// Index the SceneObjectGroup for each part by the root part's UUID.
/// </summary>
protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>();
/// <summary>
/// Index the SceneObjectGroup for each part by that part's UUID.
/// </summary>
protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullPartID = new Dictionary<UUID, SceneObjectGroup>();
/// <summary>
/// Index the SceneObjectGroup for each part by that part's local ID.
/// </summary>
protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>();
private Object m_updateLock = new Object(); private Object m_updateLock = new Object();
@ -133,8 +145,10 @@ namespace OpenSim.Region.Framework.Scenes
lock (SceneObjectGroupsByFullID) lock (SceneObjectGroupsByFullID)
SceneObjectGroupsByFullID.Clear(); SceneObjectGroupsByFullID.Clear();
lock (SceneObjectGroupsByLocalID) lock (SceneObjectGroupsByFullPartID)
SceneObjectGroupsByLocalID.Clear(); SceneObjectGroupsByFullPartID.Clear();
lock (SceneObjectGroupsByLocalPartID)
SceneObjectGroupsByLocalPartID.Clear();
Entities.Clear(); Entities.Clear();
} }
@ -204,9 +218,10 @@ namespace OpenSim.Region.Framework.Scenes
for (int i = 0; i < Math.Min(presences.Count, maxLocations); ++i) for (int i = 0; i < Math.Min(presences.Count, maxLocations); ++i)
{ {
ScenePresence sp = presences[i]; ScenePresence sp = presences[i];
// If this presence is a child agent, we don't want its coarse locations // If this presence is a child agent, we don't want its coarse locations
if (sp.IsChildAgent) if (sp.IsChildAgent)
return; continue;
if (sp.ParentID != 0) if (sp.ParentID != 0)
{ {
@ -348,6 +363,10 @@ namespace OpenSim.Region.Framework.Scenes
if (Entities.ContainsKey(sceneObject.UUID)) if (Entities.ContainsKey(sceneObject.UUID))
return false; return false;
// m_log.DebugFormat(
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
SceneObjectPart[] children = sceneObject.Parts; SceneObjectPart[] children = sceneObject.Parts;
@ -384,17 +403,20 @@ namespace OpenSim.Region.Framework.Scenes
OnObjectCreate(sceneObject); OnObjectCreate(sceneObject);
lock (SceneObjectGroupsByFullID) lock (SceneObjectGroupsByFullID)
{
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
lock (SceneObjectGroupsByFullPartID)
{
SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject;
foreach (SceneObjectPart part in children) foreach (SceneObjectPart part in children)
SceneObjectGroupsByFullID[part.UUID] = sceneObject; SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
} }
lock (SceneObjectGroupsByLocalID) lock (SceneObjectGroupsByLocalPartID)
{ {
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; SceneObjectGroupsByLocalPartID[sceneObject.LocalId] = sceneObject;
foreach (SceneObjectPart part in children) foreach (SceneObjectPart part in children)
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
} }
return true; return true;
@ -425,21 +447,24 @@ namespace OpenSim.Region.Framework.Scenes
if (OnObjectRemove != null) if (OnObjectRemove != null)
OnObjectRemove(Entities[uuid]); OnObjectRemove(Entities[uuid]);
lock (SceneObjectGroupsByFullID) lock (SceneObjectGroupsByFullID)
SceneObjectGroupsByFullID.Remove(grp.UUID);
lock (SceneObjectGroupsByFullPartID)
{ {
SceneObjectPart[] parts = grp.Parts; SceneObjectPart[] parts = grp.Parts;
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
SceneObjectGroupsByFullID.Remove(parts[i].UUID); SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID); SceneObjectGroupsByFullPartID.Remove(grp.RootPart.UUID);
} }
lock (SceneObjectGroupsByLocalID) lock (SceneObjectGroupsByLocalPartID)
{ {
SceneObjectPart[] parts = grp.Parts; SceneObjectPart[] parts = grp.Parts;
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
SceneObjectGroupsByLocalID.Remove(parts[i].LocalId); SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId); SceneObjectGroupsByLocalPartID.Remove(grp.RootPart.LocalId);
} }
return Entities.Remove(uuid); return Entities.Remove(uuid);
@ -626,7 +651,7 @@ namespace OpenSim.Region.Framework.Scenes
if (!Entities.Remove(agentID)) if (!Entities.Remove(agentID))
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list", "[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list",
agentID); agentID);
} }
@ -649,7 +674,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
m_log.WarnFormat("[SCENE]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
} }
} }
} }
@ -853,14 +878,14 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID);
SceneObjectGroup sog; SceneObjectGroup sog;
lock (SceneObjectGroupsByLocalID) lock (SceneObjectGroupsByLocalPartID)
SceneObjectGroupsByLocalID.TryGetValue(localID, out sog); SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
if (sog != null) if (sog != null)
{ {
if (sog.HasChildPrim(localID)) if (sog.HasChildPrim(localID))
return sog; return sog;
SceneObjectGroupsByLocalID.Remove(localID); SceneObjectGroupsByLocalPartID.Remove(localID);
} }
EntityBase[] entityList = GetEntities(); EntityBase[] entityList = GetEntities();
@ -872,8 +897,8 @@ namespace OpenSim.Region.Framework.Scenes
sog = (SceneObjectGroup)ent; sog = (SceneObjectGroup)ent;
if (sog.HasChildPrim(localID)) if (sog.HasChildPrim(localID))
{ {
lock (SceneObjectGroupsByLocalID) lock (SceneObjectGroupsByLocalPartID)
SceneObjectGroupsByLocalID[localID] = sog; SceneObjectGroupsByLocalPartID[localID] = sog;
return sog; return sog;
} }
} }
@ -890,16 +915,16 @@ namespace OpenSim.Region.Framework.Scenes
private SceneObjectGroup GetGroupByPrim(UUID fullID) private SceneObjectGroup GetGroupByPrim(UUID fullID)
{ {
SceneObjectGroup sog; SceneObjectGroup sog;
lock (SceneObjectGroupsByFullID) lock (SceneObjectGroupsByFullPartID)
SceneObjectGroupsByFullID.TryGetValue(fullID, out sog); SceneObjectGroupsByFullPartID.TryGetValue(fullID, out sog);
if (sog != null) if (sog != null)
{ {
if (sog.ContainsPart(fullID)) if (sog.ContainsPart(fullID))
return sog; return sog;
lock (SceneObjectGroupsByFullID) lock (SceneObjectGroupsByFullPartID)
SceneObjectGroupsByFullID.Remove(fullID); SceneObjectGroupsByFullPartID.Remove(fullID);
} }
EntityBase[] entityList = GetEntities(); EntityBase[] entityList = GetEntities();
@ -910,8 +935,8 @@ namespace OpenSim.Region.Framework.Scenes
sog = (SceneObjectGroup)ent; sog = (SceneObjectGroup)ent;
if (sog.HasChildPrim(fullID)) if (sog.HasChildPrim(fullID))
{ {
lock (SceneObjectGroupsByFullID) lock (SceneObjectGroupsByFullPartID)
SceneObjectGroupsByFullID[fullID] = sog; SceneObjectGroupsByFullPartID[fullID] = sog;
return sog; return sog;
} }
} }
@ -1063,11 +1088,12 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// Performs action on all scene object groups. /// Performs action once on all scene object groups.
/// </summary> /// </summary>
/// <param name="action"></param> /// <param name="action"></param>
protected internal void ForEachSOG(Action<SceneObjectGroup> action) protected internal void ForEachSOG(Action<SceneObjectGroup> action)
{ {
// FIXME: Need to lock here, really.
List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
foreach (SceneObjectGroup obj in objlist) foreach (SceneObjectGroup obj in objlist)
{ {
@ -1078,11 +1104,11 @@ namespace OpenSim.Region.Framework.Scenes
catch (Exception e) catch (Exception e)
{ {
// Catch it and move on. This includes situations where splist has inconsistent info // Catch it and move on. This includes situations where splist has inconsistent info
m_log.WarnFormat("[SCENE]: Problem processing action in ForEachSOG: ", e.ToString()); m_log.WarnFormat(
"[SCENEGRAPH]: Problem processing action in ForEachSOG: {0} {1}", e.Message, e.StackTrace);
} }
} }
} }
/// <summary> /// <summary>
/// Performs action on all scene presences. This can ultimately run the actions in parallel but /// Performs action on all scene presences. This can ultimately run the actions in parallel but
@ -1102,8 +1128,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString()); m_log.Info("[SCENEGRAPH]: Error in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
m_log.Info("[BUG] Stack Trace: " + e.StackTrace); m_log.Info("[SCENEGRAPH]: Stack Trace: " + e.StackTrace);
} }
}); });
Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
@ -1118,7 +1144,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString()); m_log.Error("[SCENEGRAPH]: Error in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
} }
} }
} }
@ -1776,7 +1802,10 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="rot"></param> /// <param name="rot"></param>
public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot) public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot)
{ {
//m_log.DebugFormat("[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}", originalPrim, offset, AgentID); // m_log.DebugFormat(
// "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}",
// originalPrimID, offset, AgentID);
SceneObjectGroup original = GetGroupByPrim(originalPrimID); SceneObjectGroup original = GetGroupByPrim(originalPrimID);
if (original != null) if (original != null)
{ {
@ -1807,7 +1836,28 @@ namespace OpenSim.Region.Framework.Scenes
copy.RootPart.SalePrice = 10; copy.RootPart.SalePrice = 10;
} }
// FIXME: This section needs to be refactored so that it just calls AddSceneObject()
Entities.Add(copy); Entities.Add(copy);
lock (SceneObjectGroupsByFullID)
SceneObjectGroupsByFullID[copy.UUID] = copy;
SceneObjectPart[] children = copy.Parts;
lock (SceneObjectGroupsByFullPartID)
{
SceneObjectGroupsByFullPartID[copy.UUID] = copy;
foreach (SceneObjectPart part in children)
SceneObjectGroupsByFullPartID[part.UUID] = copy;
}
lock (SceneObjectGroupsByLocalPartID)
{
SceneObjectGroupsByLocalPartID[copy.LocalId] = copy;
foreach (SceneObjectPart part in children)
SceneObjectGroupsByLocalPartID[copy.LocalId] = copy;
}
// PROBABLE END OF FIXME
// Since we copy from a source group that is in selected // Since we copy from a source group that is in selected
// state, but the copy is shown deselected in the viewer, // state, but the copy is shown deselected in the viewer,

View File

@ -2055,8 +2055,9 @@ namespace OpenSim.Region.Framework.Scenes
public void GetProperties(IClientAPI client) public void GetProperties(IClientAPI client)
{ {
//Viewer wants date in microseconds so multiply it by 1,000,000.
client.SendObjectPropertiesReply( client.SendObjectPropertiesReply(
m_fromUserInventoryItemID, (ulong)_creationDate, _creatorID, UUID.Zero, UUID.Zero, m_fromUserInventoryItemID, (ulong)_creationDate*(ulong)1e6, _creatorID, UUID.Zero, UUID.Zero,
_groupID, (short)InventorySerial, _lastOwnerID, UUID, _ownerID, _groupID, (short)InventorySerial, _lastOwnerID, UUID, _ownerID,
ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description, ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description,
ParentGroup.RootPart._ownerMask, ParentGroup.RootPart._nextOwnerMask, ParentGroup.RootPart._groupMask, ParentGroup.RootPart._everyoneMask, ParentGroup.RootPart._ownerMask, ParentGroup.RootPart._nextOwnerMask, ParentGroup.RootPart._groupMask, ParentGroup.RootPart._everyoneMask,
@ -2098,7 +2099,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
Quaternion newRot; Quaternion newRot;
if (this.LinkNum == 0) if (this.LinkNum == 0 || this.LinkNum == 1)
{ {
newRot = RotationOffset; newRot = RotationOffset;
} }

View File

@ -1089,9 +1089,13 @@ namespace OpenSim.Region.Framework.Scenes
public Dictionary<UUID, string> GetScriptStates() public Dictionary<UUID, string> GetScriptStates()
{ {
Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
if (m_part.ParentGroup.Scene == null) // Group not in a scene
return ret;
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
if (engines == null) // No engine at all if (engines == null) // No engine at all
return ret; return ret;

View File

@ -626,7 +626,7 @@ namespace OpenSim.Region.Framework.Scenes
Utils.LongToUInts(handle, out x, out y); Utils.LongToUInts(handle, out x, out y);
x = x / Constants.RegionSize; x = x / Constants.RegionSize;
y = y / Constants.RegionSize; y = y / Constants.RegionSize;
if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) if (Util.IsOutsideView(DrawDistance, x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY))
{ {
old.Add(handle); old.Add(handle);
} }
@ -700,6 +700,7 @@ namespace OpenSim.Region.Framework.Scenes
private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
{ {
m_DrawDistance = world.DefaultDrawDistance;
m_rootRegionHandle = reginfo.RegionHandle; m_rootRegionHandle = reginfo.RegionHandle;
m_controllingClient = client; m_controllingClient = client;
m_firstname = m_controllingClient.FirstName; m_firstname = m_controllingClient.FirstName;
@ -1161,7 +1162,9 @@ namespace OpenSim.Region.Framework.Scenes
if (m_agentTransfer != null) if (m_agentTransfer != null)
m_agentTransfer.EnableChildAgents(this); m_agentTransfer.EnableChildAgents(this);
else else
m_log.DebugFormat("[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active"); m_log.DebugFormat(
"[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active for region {0}",
m_scene.RegionInfo.RegionName);
IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
if (friendsModule != null) if (friendsModule != null)
@ -1277,7 +1280,11 @@ namespace OpenSim.Region.Framework.Scenes
m_CameraUpAxis = agentData.CameraUpAxis; m_CameraUpAxis = agentData.CameraUpAxis;
// The Agent's Draw distance setting // The Agent's Draw distance setting
m_DrawDistance = agentData.Far; // When we get to the point of re-computing neighbors everytime this
// changes, then start using the agent's drawdistance rather than the
// region's draw distance.
// m_DrawDistance = agentData.Far;
m_DrawDistance = Scene.DefaultDrawDistance;
// Check if Client has camera in 'follow cam' or 'build' mode. // Check if Client has camera in 'follow cam' or 'build' mode.
Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation);
@ -2435,7 +2442,7 @@ namespace OpenSim.Region.Framework.Scenes
// If we are using the the cached appearance then send it out to everyone // If we are using the the cached appearance then send it out to everyone
if (cachedappearance) if (cachedappearance)
{ {
m_log.InfoFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name);
// If the avatars baked textures are all in the cache, then we have a // If the avatars baked textures are all in the cache, then we have a
// complete appearance... send it out, if not, then we'll send it when // complete appearance... send it out, if not, then we'll send it when
@ -2652,8 +2659,11 @@ namespace OpenSim.Region.Framework.Scenes
#region Border Crossing Methods #region Border Crossing Methods
/// <summary> /// <summary>
/// Checks to see if the avatar is in range of a border and calls CrossToNewRegion /// Starts the process of moving an avatar into another region if they are crossing the border.
/// </summary> /// </summary>
/// <remarks>
/// Also removes the avatar from the physical scene if transit has started.
/// </remarks>
protected void CheckForBorderCrossing() protected void CheckForBorderCrossing()
{ {
if (IsChildAgent) if (IsChildAgent)
@ -2721,7 +2731,6 @@ namespace OpenSim.Region.Framework.Scenes
neighbor = HaveNeighbor(Cardinals.N, ref fix); neighbor = HaveNeighbor(Cardinals.N, ref fix);
} }
// Makes sure avatar does not end up outside region // Makes sure avatar does not end up outside region
if (neighbor <= 0) if (neighbor <= 0)
{ {
@ -2776,6 +2785,13 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
// We must remove the agent from the physical scene if it has been placed in transit. If we don't,
// then this method continues to be called from ScenePresence.Update() until the handover of the client between
// regions is completed. Since this handover can take more than 1000ms (due to the 1000ms
// event queue polling response from the server), this results in the avatar pausing on the border
// for the handover period.
RemoveFromPhysicalScene();
// This constant has been inferred from experimentation // This constant has been inferred from experimentation
// I'm not sure what this value should be, so I tried a few values. // I'm not sure what this value should be, so I tried a few values.
timeStep = 0.04f; timeStep = 0.04f;
@ -2787,6 +2803,15 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Checks whether this region has a neighbour in the given direction.
/// </summary>
/// <param name="car"></param>
/// <param name="fix"></param>
/// <returns>
/// An integer which represents a compass point. N == 1, going clockwise until we reach NW == 8.
/// Returns a positive integer if there is a region in that direction, a negative integer if not.
/// </returns>
protected int HaveNeighbor(Cardinals car, ref int[] fix) protected int HaveNeighbor(Cardinals car, ref int[] fix)
{ {
uint neighbourx = m_regionInfo.RegionLocX; uint neighbourx = m_regionInfo.RegionLocX;
@ -2893,7 +2918,7 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
//m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY))
{ {
byebyeRegions.Add(handle); byebyeRegions.Add(handle);
} }
@ -2969,7 +2994,12 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 offset = new Vector3(shiftx, shifty, 0f); Vector3 offset = new Vector3(shiftx, shifty, 0f);
m_DrawDistance = cAgentData.Far; // When we get to the point of re-computing neighbors everytime this
// changes, then start using the agent's drawdistance rather than the
// region's draw distance.
// m_DrawDistance = cAgentData.Far;
m_DrawDistance = Scene.DefaultDrawDistance;
if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!!
m_pos = cAgentData.Position + offset; m_pos = cAgentData.Position + offset;
@ -3119,7 +3149,11 @@ namespace OpenSim.Region.Framework.Scenes
m_CameraLeftAxis = cAgent.LeftAxis; m_CameraLeftAxis = cAgent.LeftAxis;
m_CameraUpAxis = cAgent.UpAxis; m_CameraUpAxis = cAgent.UpAxis;
m_DrawDistance = cAgent.Far; // When we get to the point of re-computing neighbors everytime this
// changes, then start using the agent's drawdistance rather than the
// region's draw distance.
// m_DrawDistance = cAgent.Far;
m_DrawDistance = Scene.DefaultDrawDistance;
if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
ControllingClient.SetChildAgentThrottle(cAgent.Throttles); ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

View File

@ -205,6 +205,14 @@ namespace OpenSim.Region.Framework.Scenes
Reset(); Reset();
} }
public int GetPendingObjectsCount()
{
if (m_pendingObjects != null)
return m_pendingObjects.Count;
return 0;
}
public class ScenePartUpdate public class ScenePartUpdate
{ {
public UUID FullID; public UUID FullID;

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.Generic;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Timers;
using Timer=System.Timers.Timer;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.Framework.Scenes.Tests
{
/// <summary>
/// Attachment tests
/// </summary>
[TestFixture]
public class AttachmentTests
{
public Scene scene, scene2;
public UUID agent1;
public static Random random;
public ulong region1, region2;
public AgentCircuitData acd1;
public SceneObjectGroup sog1, sog2, sog3;
[TestFixtureSetUp]
public void Init()
{
TestHelper.InMethod();
scene = SceneSetupHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000);
scene2 = SceneSetupHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000);
ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
interregionComms.Initialise(new IniConfigSource());
interregionComms.PostInitialise();
SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms);
SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms);
agent1 = UUID.Random();
random = new Random();
sog1 = NewSOG(UUID.Random(), scene, agent1);
sog2 = NewSOG(UUID.Random(), scene, agent1);
sog3 = NewSOG(UUID.Random(), scene, agent1);
//ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
region1 = scene.RegionInfo.RegionHandle;
region2 = scene2.RegionInfo.RegionHandle;
SceneSetupHelpers.AddRootAgent(scene, agent1);
}
[Test]
public void T030_TestAddAttachments()
{
TestHelper.InMethod();
ScenePresence presence = scene.GetScenePresence(agent1);
presence.AddAttachment(sog1);
presence.AddAttachment(sog2);
presence.AddAttachment(sog3);
Assert.That(presence.HasAttachments(), Is.True);
Assert.That(presence.ValidateAttachments(), Is.True);
}
[Test]
public void T031_RemoveAttachments()
{
TestHelper.InMethod();
ScenePresence presence = scene.GetScenePresence(agent1);
presence.RemoveAttachment(sog1);
presence.RemoveAttachment(sog2);
presence.RemoveAttachment(sog3);
Assert.That(presence.HasAttachments(), Is.False);
}
// I'm commenting this test because scene setup NEEDS InventoryService to
// be non-null
//[Test]
public void T032_CrossAttachments()
{
TestHelper.InMethod();
ScenePresence presence = scene.GetScenePresence(agent1);
ScenePresence presence2 = scene2.GetScenePresence(agent1);
presence2.AddAttachment(sog1);
presence2.AddAttachment(sog2);
ISharedRegionModule serialiser = new SerialiserModule();
SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
//Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
}
private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent)
{
SceneObjectPart sop = new SceneObjectPart();
sop.Name = RandomName();
sop.Description = RandomName();
sop.Text = RandomName();
sop.SitName = RandomName();
sop.TouchName = RandomName();
sop.UUID = uuid;
sop.Shape = PrimitiveBaseShape.Default;
sop.Shape.State = 1;
sop.OwnerID = agent;
SceneObjectGroup sog = new SceneObjectGroup(sop);
sog.SetScene(scene);
return sog;
}
private static string RandomName()
{
StringBuilder name = new StringBuilder();
int size = random.Next(5,12);
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ;
name.Append(ch);
}
return name.ToString();
}
}
}

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