Merge branch 'master' of /home/opensim/var/repo/opensim

Conflicts:
	OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs
integration
BlueWall 2012-11-27 07:11:50 -05:00
commit 1140cb613b
171 changed files with 5301 additions and 3687 deletions

View File

@ -132,6 +132,16 @@
</exec> </exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.server.handlers.tests">
<arg value="./bin/OpenSim.Server.Handlers.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.server.handlers.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.services.inventoryservice.tests">
<arg value="./bin/OpenSim.Services.InventoryService.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
<delete dir="%temp%"/> <delete dir="%temp%"/>
</target> </target>
@ -235,6 +245,16 @@
<arg value="-xml=test-results/OpenSim.Capabilities.Handlers.Tests.dll-Results.xml" /> <arg value="-xml=test-results/OpenSim.Capabilities.Handlers.Tests.dll-Results.xml" />
</exec> </exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.server.handlers.tests">
<arg value="./bin/OpenSim.Server.Handlers.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Server.Handlers.Tests.dll-Results.xml" />
</exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.services.inventoryservice.tests">
<arg value="./bin/OpenSim.Services.InventoryService.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
@ -245,6 +265,7 @@
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
</target> </target>
<target name="doxygen"> <target name="doxygen">

View File

@ -93,6 +93,7 @@ what it is today.
* Garmin Kawaguichi * Garmin Kawaguichi
* Gryc Ueusp * Gryc Ueusp
* Hiro Lecker * Hiro Lecker
* Iain Oliver
* Imaze Rhiano * Imaze Rhiano
* Intimidated * Intimidated
* Jeremy Bongio (IBM) * Jeremy Bongio (IBM)

View File

@ -141,8 +141,6 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
// PostInilise can fire before the region is loaded, so need to // PostInilise can fire before the region is loaded, so need to
// track down the cause of that // track down the cause of that
Thread.Sleep(300); Thread.Sleep(300);
m_openSim.ModuleLoader.PostInitialise();
m_openSim.ModuleLoader.ClearCache();
} }
public void Dispose() public void Dispose()

View File

@ -2314,7 +2314,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
destinationItem.Description = item.Description; destinationItem.Description = item.Description;
destinationItem.InvType = item.InvType; destinationItem.InvType = item.InvType;
destinationItem.CreatorId = item.CreatorId; destinationItem.CreatorId = item.CreatorId;
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
destinationItem.CreatorData = item.CreatorData; destinationItem.CreatorData = item.CreatorData;
destinationItem.NextPermissions = item.NextPermissions; destinationItem.NextPermissions = item.NextPermissions;
destinationItem.CurrentPermissions = item.CurrentPermissions; destinationItem.CurrentPermissions = item.CurrentPermissions;
@ -2369,7 +2368,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
destinationItem.Description = item.Description; destinationItem.Description = item.Description;
destinationItem.InvType = item.InvType; destinationItem.InvType = item.InvType;
destinationItem.CreatorId = item.CreatorId; destinationItem.CreatorId = item.CreatorId;
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
destinationItem.CreatorData = item.CreatorData; destinationItem.CreatorData = item.CreatorData;
destinationItem.NextPermissions = item.NextPermissions; destinationItem.NextPermissions = item.NextPermissions;
destinationItem.CurrentPermissions = item.CurrentPermissions; destinationItem.CurrentPermissions = item.CurrentPermissions;
@ -2482,7 +2480,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
destinationItem.Description = item.Description; destinationItem.Description = item.Description;
destinationItem.InvType = item.InvType; destinationItem.InvType = item.InvType;
destinationItem.CreatorId = item.CreatorId; destinationItem.CreatorId = item.CreatorId;
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
destinationItem.CreatorData = item.CreatorData; destinationItem.CreatorData = item.CreatorData;
destinationItem.NextPermissions = item.NextPermissions; destinationItem.NextPermissions = item.NextPermissions;
destinationItem.CurrentPermissions = item.CurrentPermissions; destinationItem.CurrentPermissions = item.CurrentPermissions;
@ -2788,7 +2785,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
inventoryItem.Description = GetStringAttribute(item,"desc",""); inventoryItem.Description = GetStringAttribute(item,"desc","");
inventoryItem.InvType = GetIntegerAttribute(item,"invtype",-1); inventoryItem.InvType = GetIntegerAttribute(item,"invtype",-1);
inventoryItem.CreatorId = GetStringAttribute(item,"creatorid",""); inventoryItem.CreatorId = GetStringAttribute(item,"creatorid","");
inventoryItem.CreatorIdAsUuid = (UUID)GetStringAttribute(item,"creatoruuid","");
inventoryItem.CreatorData = GetStringAttribute(item, "creatordata", ""); inventoryItem.CreatorData = GetStringAttribute(item, "creatordata", "");
inventoryItem.NextPermissions = GetUnsignedAttribute(perms, "next", 0x7fffffff); inventoryItem.NextPermissions = GetUnsignedAttribute(perms, "next", 0x7fffffff);
inventoryItem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff); inventoryItem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff);

View File

@ -42,7 +42,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
{ {
[TestFixture] [TestFixture]
public class GetTextureHandlerTests public class GetTextureHandlerTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestTextureNotFound() public void TestTextureNotFound()

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Data
{
public class XGroup
{
public UUID groupID;
public UUID ownerRoleID;
public string name;
public string charter;
public bool showInList;
public UUID insigniaID;
public int membershipFee;
public bool openEnrollment;
public bool allowPublish;
public bool maturePublish;
public UUID founderID;
public ulong everyonePowers;
public ulong ownersPowers;
public XGroup Clone()
{
return (XGroup)MemberwiseClone();
}
}
/// <summary>
/// Early stub interface for groups data, not final.
/// </summary>
/// <remarks>
/// Currently in-use only for regression test purposes. Needs to be filled out over time.
/// </remarks>
public interface IXGroupData
{
bool StoreGroup(XGroup group);
XGroup[] GetGroups(string field, string val);
XGroup[] GetGroups(string[] fields, string[] vals);
bool DeleteGroups(string field, string val);
bool DeleteGroups(string[] fields, string[] vals);
}
}

View File

@ -122,7 +122,7 @@ namespace OpenSim.Data.MSSQL
} }
} }
public class MSSQLItemHandler : MSSQLGenericTableHandler<XInventoryItem> public class MSSQLItemHandler : MSSQLInventoryHandler<XInventoryItem>
{ {
public MSSQLItemHandler(string c, string t, string m) : public MSSQLItemHandler(string c, string t, string m) :
base(c, t, m) base(c, t, m)
@ -131,6 +131,12 @@ namespace OpenSim.Data.MSSQL
public bool MoveItem(string id, string newParent) public bool MoveItem(string id, string newParent)
{ {
XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
if (retrievedItems.Length == 0)
return false;
UUID oldParent = retrievedItems[0].parentFolderID;
using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlConnection conn = new SqlConnection(m_ConnectionString))
{ {
using (SqlCommand cmd = new SqlCommand()) using (SqlCommand cmd = new SqlCommand())
@ -141,9 +147,16 @@ namespace OpenSim.Data.MSSQL
cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id)); cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id));
cmd.Connection = conn; cmd.Connection = conn;
conn.Open(); conn.Open();
return cmd.ExecuteNonQuery() == 0 ? false : true;
if (cmd.ExecuteNonQuery() == 0)
return false;
} }
} }
IncrementFolderVersion(oldParent);
IncrementFolderVersion(newParent);
return true;
} }
public XInventoryItem[] GetActiveGestures(UUID principalID) public XInventoryItem[] GetActiveGestures(UUID principalID)
@ -196,30 +209,13 @@ namespace OpenSim.Data.MSSQL
if (!base.Store(item)) if (!base.Store(item))
return false; return false;
string sql = "update inventoryfolders set version=version+1 where folderID = @folderID"; IncrementFolderVersion(item.parentFolderID);
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString()); return true;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false;
}
}
return true;
}
} }
} }
public class MSSQLFolderHandler : MSSQLGenericTableHandler<XInventoryFolder> public class MSSQLFolderHandler : MSSQLInventoryHandler<XInventoryFolder>
{ {
public MSSQLFolderHandler(string c, string t, string m) : public MSSQLFolderHandler(string c, string t, string m) :
base(c, t, m) base(c, t, m)
@ -228,6 +224,13 @@ namespace OpenSim.Data.MSSQL
public bool MoveFolder(string id, string newParentFolderID) public bool MoveFolder(string id, string newParentFolderID)
{ {
XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id });
if (folders.Length == 0)
return false;
UUID oldParentFolderUUID = folders[0].parentFolderID;
using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlConnection conn = new SqlConnection(m_ConnectionString))
{ {
using (SqlCommand cmd = new SqlCommand()) using (SqlCommand cmd = new SqlCommand())
@ -238,9 +241,65 @@ namespace OpenSim.Data.MSSQL
cmd.Parameters.Add(m_database.CreateParameter("@folderID", id)); cmd.Parameters.Add(m_database.CreateParameter("@folderID", id));
cmd.Connection = conn; cmd.Connection = conn;
conn.Open(); conn.Open();
return cmd.ExecuteNonQuery() == 0 ? false : true;
if (cmd.ExecuteNonQuery() == 0)
return false;
} }
} }
IncrementFolderVersion(oldParentFolderUUID);
IncrementFolderVersion(newParentFolderID);
return true;
}
public override bool Store(XInventoryFolder folder)
{
if (!base.Store(folder))
return false;
IncrementFolderVersion(folder.parentFolderID);
return true;
}
}
public class MSSQLInventoryHandler<T> : MSSQLGenericTableHandler<T> where T: class, new()
{
public MSSQLInventoryHandler(string c, string t, string m) : base(c, t, m) {}
protected bool IncrementFolderVersion(UUID folderID)
{
return IncrementFolderVersion(folderID.ToString());
}
protected bool IncrementFolderVersion(string folderID)
{
// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
// Util.PrintCallStack();
string sql = "update inventoryfolders set version=version+1 where folderID = ?folderID";
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.Parameters.AddWithValue("@folderID", folderID);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false;
}
}
}
return true;
} }
} }
} }

View File

@ -122,7 +122,7 @@ namespace OpenSim.Data.MySQL
} }
} }
public class MySqlItemHandler : MySQLGenericTableHandler<XInventoryItem> public class MySqlItemHandler : MySqlInventoryHandler<XInventoryItem>
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -241,47 +241,9 @@ namespace OpenSim.Data.MySQL
return true; return true;
} }
private bool IncrementFolderVersion(UUID folderID)
{
return IncrementFolderVersion(folderID.ToString());
}
private bool IncrementFolderVersion(string folderID)
{
// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
// Util.PrintCallStack();
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = dbcon;
cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID");
cmd.Parameters.AddWithValue("?folderID", folderID);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false;
}
cmd.Dispose();
}
dbcon.Close();
}
return true;
}
} }
public class MySqlFolderHandler : MySQLGenericTableHandler<XInventoryFolder> public class MySqlFolderHandler : MySqlInventoryHandler<XInventoryFolder>
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -326,13 +288,18 @@ namespace OpenSim.Data.MySQL
return true; return true;
} }
}
private bool IncrementFolderVersion(UUID folderID) public class MySqlInventoryHandler<T> : MySQLGenericTableHandler<T> where T: class, new()
{
public MySqlInventoryHandler(string c, string t, string m) : base(c, t, m) {}
protected bool IncrementFolderVersion(UUID folderID)
{ {
return IncrementFolderVersion(folderID.ToString()); return IncrementFolderVersion(folderID.ToString());
} }
private bool IncrementFolderVersion(string folderID) protected bool IncrementFolderVersion(string folderID)
{ {
// m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID); // m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID);
// Util.PrintCallStack(); // Util.PrintCallStack();

View File

@ -0,0 +1,67 @@
/*
* 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.Linq;
using System.Reflection;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Data;
namespace OpenSim.Data.Null
{
/// <summary>
/// Not a proper generic data handler yet - probably needs to actually store the data as well instead of relying
/// on descendent classes
/// </summary>
public class NullGenericDataHandler
{
protected List<T> Get<T>(string[] fields, string[] vals, List<T> inputEntities)
{
List<T> entities = inputEntities;
for (int i = 0; i < fields.Length; i++)
{
entities
= entities.Where(
e =>
{
FieldInfo fi = typeof(T).GetField(fields[i]);
if (fi == null)
throw new NotImplementedException(string.Format("No field {0} for val {1}", fields[i], vals[i]));
return fi.GetValue(e).ToString() == vals[i];
}
).ToList();
}
return entities;
}
}
}

View File

@ -26,57 +26,65 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using Nini.Config; using System.Threading;
using log4net;
using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Data; using OpenSim.Data;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Base;
namespace OpenSim.Services.InventoryService namespace OpenSim.Data.Null
{ {
public class InventoryServiceBase : ServiceBase public class NullXGroupData : NullGenericDataHandler, IXGroupData
{ {
protected IInventoryDataPlugin m_Database = null; // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public InventoryServiceBase(IConfigSource config) : base(config) private Dictionary<UUID, XGroup> m_groups = new Dictionary<UUID, XGroup>();
public NullXGroupData(string connectionString, string realm) {}
public bool StoreGroup(XGroup group)
{ {
string dllName = String.Empty; lock (m_groups)
string connString = String.Empty;
//
// Try reading the [DatabaseService] section first, if it exists
//
IConfig dbConfig = config.Configs["DatabaseService"];
if (dbConfig != null)
{ {
dllName = dbConfig.GetString("StorageProvider", String.Empty); m_groups[group.groupID] = group.Clone();
connString = dbConfig.GetString("ConnectionString", String.Empty);
} }
// return true;
// Try reading the more specific [InventoryService] section, if it exists
//
IConfig inventoryConfig = config.Configs["InventoryService"];
if (inventoryConfig != null)
{
dllName = inventoryConfig.GetString("StorageProvider", dllName);
connString = inventoryConfig.GetString("ConnectionString", connString);
}
//
// We tried, but this doesn't exist. We can't proceed.
//
if (dllName.Equals(String.Empty))
throw new Exception("No InventoryService configuration");
m_Database = LoadPlugin<IInventoryDataPlugin>(dllName);
if (m_Database == null)
throw new Exception("Could not find a storage interface in the given module");
m_Database.Initialise(connString);
} }
public XGroup[] GetGroups(string field, string val)
{
return GetGroups(new string[] { field }, new string[] { val });
}
public XGroup[] GetGroups(string[] fields, string[] vals)
{
lock (m_groups)
{
List<XGroup> origGroups = Get<XGroup>(fields, vals, m_groups.Values.ToList());
return origGroups.Select(g => g.Clone()).ToArray();
}
}
public bool DeleteGroups(string field, string val)
{
return DeleteGroups(new string[] { field }, new string[] { val });
}
public bool DeleteGroups(string[] fields, string[] vals)
{
lock (m_groups)
{
XGroup[] groupsToDelete = GetGroups(fields, vals);
Array.ForEach(groupsToDelete, g => m_groups.Remove(g.groupID));
}
return true;
}
} }
} }

View File

@ -120,12 +120,12 @@ namespace OpenSim.Data.SQLite
} }
} }
public T[] Get(string field, string key) public virtual T[] Get(string field, string key)
{ {
return Get(new string[] { field }, new string[] { key }); return Get(new string[] { field }, new string[] { key });
} }
public T[] Get(string[] fields, string[] keys) public virtual T[] Get(string[] fields, string[] keys)
{ {
if (fields.Length != keys.Length) if (fields.Length != keys.Length)
return new T[0]; return new T[0];
@ -213,7 +213,7 @@ namespace OpenSim.Data.SQLite
return result.ToArray(); return result.ToArray();
} }
public T[] Get(string where) public virtual T[] Get(string where)
{ {
using (SqliteCommand cmd = new SqliteCommand()) using (SqliteCommand cmd = new SqliteCommand())
{ {
@ -226,7 +226,7 @@ namespace OpenSim.Data.SQLite
} }
} }
public bool Store(T row) public virtual bool Store(T row)
{ {
using (SqliteCommand cmd = new SqliteCommand()) using (SqliteCommand cmd = new SqliteCommand())
{ {
@ -270,7 +270,7 @@ namespace OpenSim.Data.SQLite
return Delete(new string[] { field }, new string[] { key }); return Delete(new string[] { field }, new string[] { key });
} }
public bool Delete(string[] fields, string[] keys) public virtual bool Delete(string[] fields, string[] keys)
{ {
if (fields.Length != keys.Length) if (fields.Length != keys.Length)
return false; return false;

View File

@ -130,23 +130,79 @@ namespace OpenSim.Data.SQLite
} }
} }
public class SqliteItemHandler : SQLiteGenericTableHandler<XInventoryItem> public class SqliteItemHandler : SqliteInventoryHandler<XInventoryItem>
{ {
public SqliteItemHandler(string c, string t, string m) : public SqliteItemHandler(string c, string t, string m) :
base(c, t, m) base(c, t, m)
{ {
} }
public override bool Store(XInventoryItem item)
{
if (!base.Store(item))
return false;
IncrementFolderVersion(item.parentFolderID);
return true;
}
public override bool Delete(string field, string val)
{
XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val });
if (retrievedItems.Length == 0)
return false;
if (!base.Delete(field, val))
return false;
// Don't increment folder version here since Delete(string, string) calls Delete(string[], string[])
// IncrementFolderVersion(retrievedItems[0].parentFolderID);
return true;
}
public override bool Delete(string[] fields, string[] vals)
{
XInventoryItem[] retrievedItems = Get(fields, vals);
if (retrievedItems.Length == 0)
return false;
if (!base.Delete(fields, vals))
return false;
HashSet<UUID> deletedItemFolderUUIDs = new HashSet<UUID>();
Array.ForEach<XInventoryItem>(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID));
foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs)
IncrementFolderVersion(deletedItemFolderUUID);
return true;
}
public bool MoveItem(string id, string newParent) public bool MoveItem(string id, string newParent)
{ {
XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
if (retrievedItems.Length == 0)
return false;
UUID oldParent = retrievedItems[0].parentFolderID;
using (SqliteCommand cmd = new SqliteCommand()) using (SqliteCommand cmd = new SqliteCommand())
{ {
cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm); cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm);
cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent)); cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent));
cmd.Parameters.Add(new SqliteParameter(":InventoryID", id)); cmd.Parameters.Add(new SqliteParameter(":InventoryID", id));
return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true; if (ExecuteNonQuery(cmd, m_Connection) == 0)
return false;
} }
IncrementFolderVersion(oldParent);
IncrementFolderVersion(newParent);
return true;
} }
public XInventoryItem[] GetActiveGestures(UUID principalID) public XInventoryItem[] GetActiveGestures(UUID principalID)
@ -189,23 +245,80 @@ namespace OpenSim.Data.SQLite
} }
} }
public class SqliteFolderHandler : SQLiteGenericTableHandler<XInventoryFolder> public class SqliteFolderHandler : SqliteInventoryHandler<XInventoryFolder>
{ {
public SqliteFolderHandler(string c, string t, string m) : public SqliteFolderHandler(string c, string t, string m) :
base(c, t, m) base(c, t, m)
{ {
} }
public override bool Store(XInventoryFolder folder)
{
if (!base.Store(folder))
return false;
IncrementFolderVersion(folder.parentFolderID);
return true;
}
public bool MoveFolder(string id, string newParentFolderID) public bool MoveFolder(string id, string newParentFolderID)
{ {
XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id });
if (folders.Length == 0)
return false;
UUID oldParentFolderUUID = folders[0].parentFolderID;
using (SqliteCommand cmd = new SqliteCommand()) using (SqliteCommand cmd = new SqliteCommand())
{ {
cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm); cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm);
cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID)); cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID));
cmd.Parameters.Add(new SqliteParameter(":FolderID", id)); cmd.Parameters.Add(new SqliteParameter(":FolderID", id));
return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true; if (ExecuteNonQuery(cmd, m_Connection) == 0)
return false;
} }
IncrementFolderVersion(oldParentFolderUUID);
IncrementFolderVersion(newParentFolderID);
return true;
}
}
public class SqliteInventoryHandler<T> : SQLiteGenericTableHandler<T> where T: class, new()
{
public SqliteInventoryHandler(string c, string t, string m) : base(c, t, m) {}
protected bool IncrementFolderVersion(UUID folderID)
{
return IncrementFolderVersion(folderID.ToString());
}
protected bool IncrementFolderVersion(string folderID)
{
// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
// Util.PrintCallStack();
using (SqliteCommand cmd = new SqliteCommand())
{
cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID";
cmd.Parameters.Add(new SqliteParameter(":folderID", folderID));
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false;
}
}
return true;
} }
} }
} }

View File

@ -49,7 +49,7 @@ using OpenSim.Data.SQLite;
namespace OpenSim.Data.Tests namespace OpenSim.Data.Tests
{ {
[TestFixture(Description = "Asset store tests (SQLite)")] [TestFixture(Description = "Asset store tests (SQLite)")]
public class SQLiteAssetTests : AssetTests<SqliteConnection, SQLiteAssetData> public class SQLiteAssetTests : AssetTests<SqliteConnection, SQLiteAssetData>
{ {
} }

View File

@ -33,6 +33,7 @@ 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 log4net; using log4net;
using System.Data; using System.Data;
using System.Data.Common; using System.Data.Common;
@ -45,7 +46,7 @@ namespace OpenSim.Data.Tests
/// </summary> /// </summary>
/// <typeparam name="TConn"></typeparam> /// <typeparam name="TConn"></typeparam>
/// <typeparam name="TService"></typeparam> /// <typeparam name="TService"></typeparam>
public class BasicDataServiceTest<TConn, TService> public class BasicDataServiceTest<TConn, TService> : OpenSimTestCase
where TConn : DbConnection, new() where TConn : DbConnection, new()
where TService : class, new() where TService : class, new()
{ {

View File

@ -36,6 +36,7 @@ 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;
namespace OpenSim.Data.Tests namespace OpenSim.Data.Tests
{ {
@ -254,7 +255,7 @@ namespace OpenSim.Data.Tests
} }
[TestFixture] [TestFixture]
public class PropertyCompareConstraintTest public class PropertyCompareConstraintTest : OpenSimTestCase
{ {
public class HasInt public class HasInt
{ {

View File

@ -34,6 +34,7 @@ using System.Text;
using NUnit.Framework; using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Tests.Common;
namespace OpenSim.Data.Tests namespace OpenSim.Data.Tests
{ {
@ -158,7 +159,7 @@ namespace OpenSim.Data.Tests
} }
[TestFixture] [TestFixture]
public class PropertyScramblerTests public class PropertyScramblerTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestScramble() public void TestScramble()

View File

@ -83,7 +83,8 @@ namespace OpenSim.Framework.Console
= "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n"; = "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n";
public const string ItemHelpText public const string ItemHelpText
= "For more information, type 'help <item>' where <item> is one of the following:"; = @"For more information, type 'help all' to get a list of all commands,
or type help <item>' where <item> is one of the following:";
/// <value> /// <value>
/// Commands organized by keyword in a tree /// Commands organized by keyword in a tree
@ -117,6 +118,10 @@ namespace OpenSim.Framework.Console
help.Add(ItemHelpText); help.Add(ItemHelpText);
help.AddRange(CollectModulesHelp(tree)); help.AddRange(CollectModulesHelp(tree));
} }
else if (helpParts.Count == 1 && helpParts[0] == "all")
{
help.AddRange(CollectAllCommandsHelp());
}
else else
{ {
help.AddRange(CollectHelp(helpParts)); help.AddRange(CollectHelp(helpParts));
@ -125,6 +130,28 @@ namespace OpenSim.Framework.Console
return help; return help;
} }
/// <summary>
/// Collects the help from all commands and return in alphabetical order.
/// </summary>
/// <returns></returns>
private List<string> CollectAllCommandsHelp()
{
List<string> help = new List<string>();
lock (m_modulesCommands)
{
foreach (List<CommandInfo> commands in m_modulesCommands.Values)
{
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
help.AddRange(ourHelpText);
}
}
help.Sort();
return help;
}
/// <summary> /// <summary>
/// See if we can find the requested command in order to display longer help /// See if we can find the requested command in order to display longer help
/// </summary> /// </summary>
@ -711,7 +738,7 @@ namespace OpenSim.Framework.Console
/// </summary> /// </summary>
public void Prompt() public void Prompt()
{ {
string line = ReadLine(m_defaultPrompt + "# ", true, true); string line = ReadLine(DefaultPrompt + "# ", true, true);
if (line != String.Empty) if (line != String.Empty)
Output("Invalid command"); Output("Invalid command");

View File

@ -43,15 +43,7 @@ namespace OpenSim.Framework.Console
public object ConsoleScene { get; set; } public object ConsoleScene { get; set; }
/// <summary> public string DefaultPrompt { get; set; }
/// The default prompt text.
/// </summary>
public string DefaultPrompt
{
set { m_defaultPrompt = value; }
get { return m_defaultPrompt; }
}
protected string m_defaultPrompt;
public ConsoleBase(string defaultPrompt) public ConsoleBase(string defaultPrompt)
{ {

View File

@ -46,13 +46,18 @@ namespace OpenSim.Framework.Console
public ICommands Commands { get { return m_commands; } } public ICommands Commands { get { return m_commands; } }
public string DefaultPrompt { get; set; }
public void Prompt() {} public void Prompt() {}
public void RunCommand(string cmd) {} public void RunCommand(string cmd) {}
public string ReadLine(string p, bool isCommand, bool e) { return ""; } public string ReadLine(string p, bool isCommand, bool e) { return ""; }
public object ConsoleScene { get { return null; } } public object ConsoleScene {
get { return null; }
set {}
}
public void Output(string text, string level) {} public void Output(string text, string level) {}
public void Output(string text) {} public void Output(string text) {}

View File

@ -82,6 +82,11 @@ namespace OpenSim.Framework
ICommands Commands { get; } ICommands Commands { get; }
/// <summary>
/// The default prompt text.
/// </summary>
string DefaultPrompt { get; set; }
/// <summary> /// <summary>
/// Display a command prompt on the console and wait for user input /// Display a command prompt on the console and wait for user input
/// </summary> /// </summary>

View File

@ -32,7 +32,7 @@ namespace OpenSim.Framework
{ {
public interface IConsole public interface IConsole
{ {
object ConsoleScene { get; } object ConsoleScene { get; set; }
void Output(string text, string level); void Output(string text, string level);
void Output(string text); void Output(string text);

View File

@ -87,16 +87,7 @@ namespace OpenSim.Framework
protected string m_creatorId; protected string m_creatorId;
/// <value> /// <value>
/// The UUID for the creator. This may be different from the canonical CreatorId. This property is used /// The CreatorId expressed as a UUID.tely
/// for communication with the client over the Second Life protocol, since that protocol can only understand
/// UUIDs. As this is a basic framework class, this means that both the string creator id and the uuid
/// reference have to be settable separately
///
/// Database plugins don't need to set this, it will be set by
/// upstream code (or set by the get accessor if left unset).
///
/// XXX: An alternative to having a separate uuid property would be to hash the CreatorId appropriately
/// every time there was communication with a UUID-only client. This may be much more expensive.
/// </value> /// </value>
public UUID CreatorIdAsUuid public UUID CreatorIdAsUuid
{ {
@ -109,20 +100,18 @@ namespace OpenSim.Framework
return m_creatorIdAsUuid; return m_creatorIdAsUuid;
} }
set
{
m_creatorIdAsUuid = value;
}
} }
protected UUID m_creatorIdAsUuid = UUID.Zero; protected UUID m_creatorIdAsUuid = UUID.Zero;
protected string m_creatorData = string.Empty; /// <summary>
/// Extended creator information of the form <profile url>;<name>
/// </summary>
public string CreatorData // = <profile url>;<name> public string CreatorData // = <profile url>;<name>
{ {
get { return m_creatorData; } get { return m_creatorData; }
set { m_creatorData = value; } set { m_creatorData = value; }
} }
protected string m_creatorData = string.Empty;
/// <summary> /// <summary>
/// Used by the DB layer to retrieve / store the entire user identification. /// Used by the DB layer to retrieve / store the entire user identification.
@ -162,7 +151,6 @@ namespace OpenSim.Framework
name = parts[2]; name = parts[2];
m_creatorData += ';' + name; m_creatorData += ';' + name;
} }
} }
} }

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Framework.Monitoring
{
public class PercentageStat : Stat
{
public long Antecedent { get; set; }
public long Consequent { get; set; }
public override double Value
{
get
{
// Asking for an update here means that the updater cannot access this value without infinite recursion.
// XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
// called by the pull action and just return the value.
if (StatType == StatType.Pull)
PullAction(this);
long c = Consequent;
// Avoid any chance of a multi-threaded divide-by-zero
if (c == 0)
return 0;
return (double)Antecedent / c * 100;
}
set
{
throw new InvalidOperationException("Cannot set value on a PercentageStat");
}
}
public PercentageStat(
string shortName,
string name,
string description,
string category,
string container,
StatType type,
Action<Stat> pullAction,
StatVerbosity verbosity)
: base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {}
public override string ToConsoleString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat(
"{0}.{1}.{2} : {3:0.##}{4} ({5}/{6})",
Category, Container, ShortName, Value, UnitName, Antecedent, Consequent);
AppendMeasuresOfInterest(sb);
return sb.ToString();
}
}
}

View File

@ -0,0 +1,238 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Framework.Monitoring
{
/// <summary>
/// Holds individual statistic details
/// </summary>
public class Stat
{
/// <summary>
/// Category of this stat (e.g. cache, scene, etc).
/// </summary>
public string Category { get; private set; }
/// <summary>
/// Containing name for this stat.
/// FIXME: In the case of a scene, this is currently the scene name (though this leaves
/// us with a to-be-resolved problem of non-unique region names).
/// </summary>
/// <value>
/// The container.
/// </value>
public string Container { get; private set; }
public StatType StatType { get; private set; }
public MeasuresOfInterest MeasuresOfInterest { get; private set; }
/// <summary>
/// Action used to update this stat when the value is requested if it's a pull type.
/// </summary>
public Action<Stat> PullAction { get; private set; }
public StatVerbosity Verbosity { get; private set; }
public string ShortName { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public virtual string UnitName { get; private set; }
public virtual double Value
{
get
{
// Asking for an update here means that the updater cannot access this value without infinite recursion.
// XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
// called by the pull action and just return the value.
if (StatType == StatType.Pull)
PullAction(this);
return m_value;
}
set
{
m_value = value;
}
}
private double m_value;
/// <summary>
/// Historical samples for calculating measures of interest average.
/// </summary>
/// <remarks>
/// Will be null if no measures of interest require samples.
/// </remarks>
private static Queue<double> m_samples;
/// <summary>
/// Maximum number of statistical samples.
/// </summary>
/// <remarks>
/// At the moment this corresponds to 1 minute since the sampling rate is every 2.5 seconds as triggered from
/// the main Watchdog.
/// </remarks>
private static int m_maxSamples = 24;
public Stat(
string shortName,
string name,
string description,
string unitName,
string category,
string container,
StatType type,
Action<Stat> pullAction,
StatVerbosity verbosity)
: this(
shortName,
name,
description,
unitName,
category,
container,
type,
MeasuresOfInterest.None,
pullAction,
verbosity)
{
}
/// <summary>
/// Constructor
/// </summary>
/// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param>
/// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param>
/// <param name='description'>Description of stat</param>
/// <param name='unitName'>
/// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
/// e.g. " frames"
/// </param>
/// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param>
/// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param>
/// <param name='type'>Push or pull</param>
/// <param name='pullAction'>Pull stats need an action to update the stat on request. Push stats should set null here.</param>
/// <param name='moi'>Measures of interest</param>
/// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param>
public Stat(
string shortName,
string name,
string description,
string unitName,
string category,
string container,
StatType type,
MeasuresOfInterest moi,
Action<Stat> pullAction,
StatVerbosity verbosity)
{
if (StatsManager.SubCommands.Contains(category))
throw new Exception(
string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
ShortName = shortName;
Name = name;
Description = description;
UnitName = unitName;
Category = category;
Container = container;
StatType = type;
if (StatType == StatType.Push && pullAction != null)
throw new Exception("A push stat cannot have a pull action");
else
PullAction = pullAction;
MeasuresOfInterest = moi;
if ((moi & MeasuresOfInterest.AverageChangeOverTime) == MeasuresOfInterest.AverageChangeOverTime)
m_samples = new Queue<double>(m_maxSamples);
Verbosity = verbosity;
}
/// <summary>
/// Record a value in the sample set.
/// </summary>
/// <remarks>
/// Do not call this if MeasuresOfInterest.None
/// </remarks>
public void RecordValue()
{
double newValue = Value;
lock (m_samples)
{
if (m_samples.Count >= m_maxSamples)
m_samples.Dequeue();
m_samples.Enqueue(newValue);
}
}
public virtual string ToConsoleString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName);
AppendMeasuresOfInterest(sb);
return sb.ToString();
}
protected void AppendMeasuresOfInterest(StringBuilder sb)
{
if ((MeasuresOfInterest & MeasuresOfInterest.AverageChangeOverTime)
== MeasuresOfInterest.AverageChangeOverTime)
{
double totalChange = 0;
double? lastSample = null;
lock (m_samples)
{
foreach (double s in m_samples)
{
if (lastSample != null)
totalChange += s - (double)lastSample;
lastSample = s;
}
}
int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1;
sb.AppendFormat(", {0:0.##}{1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName);
}
}
}
}

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
namespace OpenSim.Framework.Monitoring namespace OpenSim.Framework.Monitoring
{ {
@ -246,6 +247,24 @@ namespace OpenSim.Framework.Monitoring
return false; return false;
} }
public static void RecordStats()
{
lock (RegisteredStats)
{
foreach (Dictionary<string, Dictionary<string, Stat>> category in RegisteredStats.Values)
{
foreach (Dictionary<string, Stat> container in category.Values)
{
foreach (Stat stat in container.Values)
{
if (stat.MeasuresOfInterest != MeasuresOfInterest.None)
stat.RecordValue();
}
}
}
}
}
} }
/// <summary> /// <summary>
@ -261,6 +280,16 @@ namespace OpenSim.Framework.Monitoring
Pull Pull
} }
/// <summary>
/// Measures of interest for this stat.
/// </summary>
[Flags]
public enum MeasuresOfInterest
{
None,
AverageChangeOverTime
}
/// <summary> /// <summary>
/// Verbosity of stat. /// Verbosity of stat.
/// </summary> /// </summary>
@ -272,154 +301,4 @@ namespace OpenSim.Framework.Monitoring
Debug, Debug,
Info Info
} }
/// <summary>
/// Holds individual static details
/// </summary>
public class Stat
{
/// <summary>
/// Category of this stat (e.g. cache, scene, etc).
/// </summary>
public string Category { get; private set; }
/// <summary>
/// Containing name for this stat.
/// FIXME: In the case of a scene, this is currently the scene name (though this leaves
/// us with a to-be-resolved problem of non-unique region names).
/// </summary>
/// <value>
/// The container.
/// </value>
public string Container { get; private set; }
public StatType StatType { get; private set; }
/// <summary>
/// Action used to update this stat when the value is requested if it's a pull type.
/// </summary>
public Action<Stat> PullAction { get; private set; }
public StatVerbosity Verbosity { get; private set; }
public string ShortName { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public virtual string UnitName { get; private set; }
public virtual double Value
{
get
{
// Asking for an update here means that the updater cannot access this value without infinite recursion.
// XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
// called by the pull action and just return the value.
if (StatType == StatType.Pull)
PullAction(this);
return m_value;
}
set
{
m_value = value;
}
}
private double m_value;
/// <summary>
/// Constructor
/// </summary>
/// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param>
/// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param>
/// <param name='description'>Description of stat</param>
/// <param name='unitName'>
/// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
/// e.g. " frames"
/// </param>
/// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param>
/// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param>
/// <param name='type'>Push or pull</param>
/// <param name='pullAction'>Pull stats need an action to update the stat on request. Push stats should set null here.</param>
/// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param>
public Stat(
string shortName,
string name,
string description,
string unitName,
string category,
string container,
StatType type,
Action<Stat> pullAction,
StatVerbosity verbosity)
{
if (StatsManager.SubCommands.Contains(category))
throw new Exception(
string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
ShortName = shortName;
Name = name;
Description = description;
UnitName = unitName;
Category = category;
Container = container;
StatType = type;
if (StatType == StatType.Push && pullAction != null)
throw new Exception("A push stat cannot have a pull action");
else
PullAction = pullAction;
Verbosity = verbosity;
}
public virtual string ToConsoleString()
{
return string.Format(
"{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName);
}
}
public class PercentageStat : Stat
{
public int Antecedent { get; set; }
public int Consequent { get; set; }
public override double Value
{
get
{
int c = Consequent;
// Avoid any chance of a multi-threaded divide-by-zero
if (c == 0)
return 0;
return (double)Antecedent / c * 100;
}
set
{
throw new Exception("Cannot set value on a PercentageStat");
}
}
public PercentageStat(
string shortName,
string name,
string description,
string category,
string container,
StatType type,
Action<Stat> pullAction,
StatVerbosity verbosity)
: base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {}
public override string ToConsoleString()
{
return string.Format(
"{0}.{1}.{2} : {3:0.##}{4} ({5}/{6})",
Category, Container, ShortName, Value, UnitName, Antecedent, Consequent);
}
}
} }

View File

@ -39,7 +39,7 @@ namespace OpenSim.Framework.Monitoring
public static class Watchdog public static class Watchdog
{ {
/// <summary>Timer interval in milliseconds for the watchdog timer</summary> /// <summary>Timer interval in milliseconds for the watchdog timer</summary>
const double WATCHDOG_INTERVAL_MS = 2500.0d; public const double WATCHDOG_INTERVAL_MS = 2500.0d;
/// <summary>Default timeout in milliseconds before a thread is considered dead</summary> /// <summary>Default timeout in milliseconds before a thread is considered dead</summary>
public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000; public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000;
@ -380,6 +380,8 @@ namespace OpenSim.Framework.Monitoring
if (MemoryWatchdog.Enabled) if (MemoryWatchdog.Enabled)
MemoryWatchdog.Update(); MemoryWatchdog.Update();
StatsManager.RecordStats();
m_watchdogTimer.Start(); m_watchdogTimer.Start();
} }
} }

View File

@ -154,6 +154,11 @@ namespace OpenSim.Framework.Serialization
EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "trashfolder.txt"] = (sbyte)AssetType.TrashFolder; EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "trashfolder.txt"] = (sbyte)AssetType.TrashFolder;
} }
public static string CreateOarLandDataPath(LandData ld)
{
return string.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH, ld.GlobalID);
}
/// <summary> /// <summary>
/// Create the filename used to store an object in an OpenSim Archive. /// Create the filename used to store an object in an OpenSim Archive.
/// </summary> /// </summary>

View File

@ -37,7 +37,7 @@ using OpenSim.Tests.Common;
namespace OpenSim.Framework.Serialization.Tests namespace OpenSim.Framework.Serialization.Tests
{ {
[TestFixture] [TestFixture]
public class LandDataSerializerTest public class LandDataSerializerTest : OpenSimTestCase
{ {
private LandData land; private LandData land;
private LandData landWithParcelAccessList; private LandData landWithParcelAccessList;

View File

@ -37,7 +37,7 @@ using OpenSim.Tests.Common;
namespace OpenSim.Framework.Serialization.Tests namespace OpenSim.Framework.Serialization.Tests
{ {
[TestFixture] [TestFixture]
public class RegionSettingsSerializerTests public class RegionSettingsSerializerTests : OpenSimTestCase
{ {
private string m_serializedRs = @"<?xml version=""1.0"" encoding=""utf-16""?> private string m_serializedRs = @"<?xml version=""1.0"" encoding=""utf-16""?>
<RegionSettings> <RegionSettings>

View File

@ -27,7 +27,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
@ -38,6 +37,8 @@ using log4net;
using log4net.Appender; using log4net.Appender;
using log4net.Core; using log4net.Core;
using log4net.Repository; using log4net.Repository;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring; using OpenSim.Framework.Monitoring;
@ -45,16 +46,12 @@ using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using Timer=System.Timers.Timer; using Timer=System.Timers.Timer;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Framework.Servers namespace OpenSim.Framework.Servers
{ {
/// <summary> /// <summary>
/// Common base for the main OpenSimServers (user, grid, inventory, region, etc) /// Common base for the main OpenSimServers (user, grid, inventory, region, etc)
/// </summary> /// </summary>
public abstract class BaseOpenSimServer public abstract class BaseOpenSimServer : ServerBase
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -64,27 +61,6 @@ namespace OpenSim.Framework.Servers
/// </summary> /// </summary>
private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
protected CommandConsole m_console;
protected OpenSimAppender m_consoleAppender;
protected IAppender m_logFileAppender = null;
/// <summary>
/// Time at which this server was started
/// </summary>
protected DateTime m_startuptime;
/// <summary>
/// Record the initial startup directory for info purposes
/// </summary>
protected string m_startupDirectory = Environment.CurrentDirectory;
/// <summary>
/// Server version information. Usually VersionInfo + information about git commit, operating system, etc.
/// </summary>
protected string m_version;
protected string m_pidFile = String.Empty;
/// <summary> /// <summary>
/// Random uuid for private data /// Random uuid for private data
/// </summary> /// </summary>
@ -96,30 +72,13 @@ namespace OpenSim.Framework.Servers
get { return m_httpServer; } get { return m_httpServer; }
} }
public BaseOpenSimServer() public BaseOpenSimServer() : base()
{ {
m_startuptime = DateTime.Now;
m_version = VersionInfo.Version;
// Random uuid for private data // Random uuid for private data
m_osSecret = UUID.Random().ToString(); m_osSecret = UUID.Random().ToString();
m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
m_periodicDiagnosticsTimer.Enabled = true; m_periodicDiagnosticsTimer.Enabled = true;
// This thread will go on to become the console listening thread
Thread.CurrentThread.Name = "ConsoleThread";
ILoggerRepository repository = LogManager.GetRepository();
IAppender[] appenders = repository.GetAppenders();
foreach (IAppender appender in appenders)
{
if (appender.Name == "LogFileAppender")
{
m_logFileAppender = appender;
}
}
} }
/// <summary> /// <summary>
@ -127,83 +86,18 @@ namespace OpenSim.Framework.Servers
/// </summary> /// </summary>
protected virtual void StartupSpecific() protected virtual void StartupSpecific()
{ {
if (m_console != null) if (m_console == null)
{ return;
ILoggerRepository repository = LogManager.GetRepository();
IAppender[] appenders = repository.GetAppenders();
foreach (IAppender appender in appenders) RegisterCommonCommands();
{
if (appender.Name == "Console")
{
m_consoleAppender = (OpenSimAppender)appender;
break;
}
}
if (null == m_consoleAppender) m_console.Commands.AddCommand("General", false, "quit",
{ "quit",
Notice("No appender named Console found (see the log4net config file for this executable)!"); "Quit the application", HandleQuit);
}
else
{
m_consoleAppender.Console = m_console;
// If there is no threshold set then the threshold is effectively everything. m_console.Commands.AddCommand("General", false, "shutdown",
if (null == m_consoleAppender.Threshold) "shutdown",
m_consoleAppender.Threshold = Level.All; "Quit the application", HandleQuit);
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
}
m_console.Commands.AddCommand("General", false, "quit",
"quit",
"Quit the application", HandleQuit);
m_console.Commands.AddCommand("General", false, "shutdown",
"shutdown",
"Quit the application", HandleQuit);
m_console.Commands.AddCommand("General", false, "set log level",
"set log level <level>",
"Set the console logging level", HandleLogLevel);
m_console.Commands.AddCommand("General", false, "show info",
"show info",
"Show general information about the server", HandleShow);
m_console.Commands.AddCommand("General", false, "show threads",
"show threads",
"Show thread status", HandleShow);
m_console.Commands.AddCommand("General", false, "show uptime",
"show uptime",
"Show server uptime", HandleShow);
m_console.Commands.AddCommand("General", false, "show version",
"show version",
"Show server version", HandleShow);
m_console.Commands.AddCommand("General", false, "threads abort",
"threads abort <thread-id>",
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
m_console.Commands.AddCommand("General", false, "threads show",
"threads show",
"Show thread status. Synonym for \"show threads\"",
(string module, string[] args) => Notice(GetThreadsReport()));
m_console.Commands.AddCommand("General", false, "force gc",
"force gc",
"Manually invoke runtime garbage collection. For debugging purposes",
HandleForceGc);
}
}
private void HandleForceGc(string module, string[] args)
{
MainConsole.Instance.Output("Manually invoking runtime garbage collection");
GC.Collect();
} }
/// <summary> /// <summary>
@ -235,67 +129,6 @@ namespace OpenSim.Framework.Servers
m_log.Debug(sb); m_log.Debug(sb);
} }
/// <summary>
/// Get a report about the registered threads in this server.
/// </summary>
protected string GetThreadsReport()
{
// This should be a constant field.
string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
StringBuilder sb = new StringBuilder();
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo();
sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
int timeNow = Environment.TickCount & Int32.MaxValue;
sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE");
sb.Append(Environment.NewLine);
foreach (Watchdog.ThreadWatchdogInfo twi in threads)
{
Thread t = twi.Thread;
sb.AppendFormat(
reportFormat,
t.ManagedThreadId,
t.Name,
timeNow - twi.LastTick,
timeNow - twi.FirstTick,
t.Priority,
t.ThreadState);
sb.Append("\n");
}
sb.Append("\n");
// For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
// zero active threads.
int totalThreads = Process.GetCurrentProcess().Threads.Count;
if (totalThreads > 0)
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
sb.Append("Main threadpool (excluding script engine pools)\n");
sb.Append(Util.GetThreadPoolReport());
return sb.ToString();
}
/// <summary>
/// Return a report about the uptime of this server
/// </summary>
/// <returns></returns>
protected string GetUptimeReport()
{
StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now));
sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime));
sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime));
return sb.ToString();
}
/// <summary> /// <summary>
/// Performs initialisation of the scene, such as loading configuration from disk. /// Performs initialisation of the scene, such as loading configuration from disk.
/// </summary> /// </summary>
@ -303,8 +136,6 @@ namespace OpenSim.Framework.Servers
{ {
m_log.Info("[STARTUP]: Beginning startup processing"); m_log.Info("[STARTUP]: Beginning startup processing");
EnhanceVersionInformation();
m_log.Info("[STARTUP]: OpenSimulator version: " + m_version + Environment.NewLine); m_log.Info("[STARTUP]: OpenSimulator version: " + m_version + Environment.NewLine);
// clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
// the clr version number doesn't match the project version number under Mono. // the clr version number doesn't match the project version number under Mono.
@ -340,256 +171,6 @@ namespace OpenSim.Framework.Servers
Shutdown(); Shutdown();
} }
private void HandleLogLevel(string module, string[] cmd)
{
if (null == m_consoleAppender)
{
Notice("No appender named Console found (see the log4net config file for this executable)!");
return;
}
if (cmd.Length > 3)
{
string rawLevel = cmd[3];
ILoggerRepository repository = LogManager.GetRepository();
Level consoleLevel = repository.LevelMap[rawLevel];
if (consoleLevel != null)
m_consoleAppender.Threshold = consoleLevel;
else
Notice(
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));
}
/// <summary>
/// Show help information
/// </summary>
/// <param name="helpArgs"></param>
protected virtual void ShowHelp(string[] helpArgs)
{
Notice("");
if (helpArgs.Length == 0)
{
Notice("set log level [level] - change the console logging level only. For example, off or debug.");
Notice("show info - show server information (e.g. startup path).");
Notice("show threads - list tracked threads");
Notice("show uptime - show server startup time and uptime.");
Notice("show version - show server version.");
Notice("");
return;
}
}
public virtual void HandleShow(string module, string[] cmd)
{
List<string> args = new List<string>(cmd);
args.RemoveAt(0);
string[] showParams = args.ToArray();
switch (showParams[0])
{
case "info":
ShowInfo();
break;
case "threads":
Notice(GetThreadsReport());
break;
case "uptime":
Notice(GetUptimeReport());
break;
case "version":
Notice(GetVersionText());
break;
}
}
public virtual void HandleThreadsAbort(string module, string[] cmd)
{
if (cmd.Length != 3)
{
MainConsole.Instance.Output("Usage: threads abort <thread-id>");
return;
}
int threadId;
if (!int.TryParse(cmd[2], out threadId))
{
MainConsole.Instance.Output("ERROR: Thread id must be an integer");
return;
}
if (Watchdog.AbortThread(threadId))
MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
else
MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
}
protected void ShowInfo()
{
Notice(GetVersionText());
Notice("Startup directory: " + m_startupDirectory);
if (null != m_consoleAppender)
Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold));
}
protected string GetVersionText()
{
return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion);
}
/// <summary>
/// Console output is only possible if a console has been established.
/// That is something that cannot be determined within this class. So
/// all attempts to use the console MUST be verified.
/// </summary>
/// <param name="msg"></param>
protected void Notice(string msg)
{
if (m_console != null)
{
m_console.Output(msg);
}
}
/// <summary>
/// Console output is only possible if a console has been established.
/// That is something that cannot be determined within this class. So
/// all attempts to use the console MUST be verified.
/// </summary>
/// <param name="format"></param>
/// <param name="components"></param>
protected void Notice(string format, params string[] components)
{
if (m_console != null)
m_console.OutputFormat(format, components);
}
/// <summary>
/// Enhance the version string with extra information if it's available.
/// </summary>
protected void EnhanceVersionInformation()
{
string buildVersion = string.Empty;
// The subversion information is deprecated and will be removed at a later date
// Add subversion revision information if available
// Try file "svn_revision" in the current directory first, then the .svn info.
// This allows to make the revision available in simulators not running from the source tree.
// FIXME: Making an assumption about the directory we're currently in - we do this all over the place
// elsewhere as well
string gitDir = "../.git/";
string gitRefPointerPath = gitDir + "HEAD";
string svnRevisionFileName = "svn_revision";
string svnFileName = ".svn/entries";
string manualVersionFileName = ".version";
string inputLine;
int strcmp;
if (File.Exists(manualVersionFileName))
{
using (StreamReader CommitFile = File.OpenText(manualVersionFileName))
buildVersion = CommitFile.ReadLine();
m_version += buildVersion ?? "";
}
else if (File.Exists(gitRefPointerPath))
{
// m_log.DebugFormat("[OPENSIM]: Found {0}", gitRefPointerPath);
string rawPointer = "";
using (StreamReader pointerFile = File.OpenText(gitRefPointerPath))
rawPointer = pointerFile.ReadLine();
// m_log.DebugFormat("[OPENSIM]: rawPointer [{0}]", rawPointer);
Match m = Regex.Match(rawPointer, "^ref: (.+)$");
if (m.Success)
{
// m_log.DebugFormat("[OPENSIM]: Matched [{0}]", m.Groups[1].Value);
string gitRef = m.Groups[1].Value;
string gitRefPath = gitDir + gitRef;
if (File.Exists(gitRefPath))
{
// m_log.DebugFormat("[OPENSIM]: Found gitRefPath [{0}]", gitRefPath);
using (StreamReader refFile = File.OpenText(gitRefPath))
{
string gitHash = refFile.ReadLine();
m_version += gitHash.Substring(0, 7);
}
}
}
}
else
{
// Remove the else logic when subversion mirror is no longer used
if (File.Exists(svnRevisionFileName))
{
StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
buildVersion = RevisionFile.ReadLine();
buildVersion.Trim();
RevisionFile.Close();
}
if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))
{
StreamReader EntriesFile = File.OpenText(svnFileName);
inputLine = EntriesFile.ReadLine();
while (inputLine != null)
{
// using the dir svn revision at the top of entries file
strcmp = String.Compare(inputLine, "dir");
if (strcmp == 0)
{
buildVersion = EntriesFile.ReadLine();
break;
}
else
{
inputLine = EntriesFile.ReadLine();
}
}
EntriesFile.Close();
}
m_version += string.IsNullOrEmpty(buildVersion) ? " " : ("." + buildVersion + " ").Substring(0, 6);
}
}
protected void CreatePIDFile(string path)
{
try
{
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
FileStream fs = File.Create(path);
Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
fs.Write(buf, 0, buf.Length);
fs.Close();
m_pidFile = path;
}
catch (Exception)
{
}
}
public string osSecret { public string osSecret {
// Secret uuid for the simulator // Secret uuid for the simulator
get { return m_osSecret; } get { return m_osSecret; }
@ -607,20 +188,5 @@ namespace OpenSim.Framework.Servers
return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
} }
} }
protected void RemovePIDFile()
{
if (m_pidFile != String.Empty)
{
try
{
File.Delete(m_pidFile);
m_pidFile = String.Empty;
}
catch (Exception)
{
}
}
}
} }
} }

View File

@ -719,8 +719,11 @@ namespace OpenSim.Framework.Servers.HttpServer
if (DebugLevel == 5) if (DebugLevel == 5)
{ {
const int sampleLength = 80; const int sampleLength = 80;
char[] sampleChars = new char[sampleLength]; char[] sampleChars = new char[sampleLength + 3];
reader.Read(sampleChars, 0, sampleLength); reader.Read(sampleChars, 0, sampleLength);
sampleChars[80] = '.';
sampleChars[81] = '.';
sampleChars[82] = '.';
output = new string(sampleChars); output = new string(sampleChars);
} }
else else
@ -728,7 +731,7 @@ namespace OpenSim.Framework.Servers.HttpServer
output = reader.ReadToEnd(); output = reader.ReadToEnd();
} }
m_log.DebugFormat("[BASE HTTP SERVER]: {0}...", output.Replace("\n", @"\n")); m_log.DebugFormat("[BASE HTTP SERVER]: {0}", output.Replace("\n", @"\n"));
} }
} }
@ -1279,59 +1282,6 @@ namespace OpenSim.Framework.Servers.HttpServer
map["login"] = OSD.FromString("false"); map["login"] = OSD.FromString("false");
return map; return map;
} }
/// <summary>
/// A specific agent handler was provided. Such a handler is expecetd to have an
/// intimate, and highly specific relationship with the client. Consequently,
/// nothing is done here.
/// </summary>
/// <param name="handler"></param>
/// <param name="request"></param>
/// <param name="response"></param>
private bool HandleAgentRequest(IHttpAgentHandler handler, OSHttpRequest request, OSHttpResponse response)
{
// In the case of REST, then handler is responsible for ALL aspects of
// the request/response handling. Nothing is done here, not even encoding.
try
{
return handler.Handle(request, response);
}
catch (Exception e)
{
// If the handler did in fact close the stream, then this will blow
// chunks. So that that doesn't disturb anybody we throw away any
// and all exceptions raised. We've done our best to release the
// client.
try
{
m_log.Warn("[HTTP-AGENT]: Error - " + e.Message);
response.SendChunked = false;
response.KeepAlive = true;
response.StatusCode = (int)OSHttpStatusCode.ServerErrorInternalError;
//response.OutputStream.Close();
try
{
response.Send();
//response.FreeContext();
}
catch (SocketException f)
{
// This has to be here to prevent a Linux/Mono crash
m_log.Warn(
String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f);
}
}
catch(Exception)
{
}
}
// Indicate that the request has been "handled"
return true;
}
public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
{ {

View File

@ -0,0 +1,677 @@
/*
* 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.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using log4net;
using log4net.Appender;
using log4net.Core;
using log4net.Repository;
using Nini.Config;
using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers
{
public class ServerBase
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public IConfigSource Config { get; protected set; }
/// <summary>
/// Console to be used for any command line output. Can be null, in which case there should be no output.
/// </summary>
protected ICommandConsole m_console;
protected OpenSimAppender m_consoleAppender;
protected FileAppender m_logFileAppender;
protected DateTime m_startuptime;
protected string m_startupDirectory = Environment.CurrentDirectory;
protected string m_pidFile = String.Empty;
/// <summary>
/// Server version information. Usually VersionInfo + information about git commit, operating system, etc.
/// </summary>
protected string m_version;
public ServerBase()
{
m_startuptime = DateTime.Now;
m_version = VersionInfo.Version;
EnhanceVersionInformation();
}
protected void CreatePIDFile(string path)
{
try
{
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
using (FileStream fs = File.Create(path))
{
Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
fs.Write(buf, 0, buf.Length);
}
m_pidFile = path;
m_log.InfoFormat("[SERVER BASE]: Created pid file {0}", m_pidFile);
}
catch (Exception e)
{
m_log.Warn(string.Format("[SERVER BASE]: Could not create PID file at {0} ", path), e);
}
}
protected void RemovePIDFile()
{
if (m_pidFile != String.Empty)
{
try
{
File.Delete(m_pidFile);
}
catch (Exception e)
{
m_log.Error(string.Format("[SERVER BASE]: Error whilst removing {0} ", m_pidFile), e);
}
m_pidFile = String.Empty;
}
}
public void RegisterCommonAppenders(IConfig startupConfig)
{
ILoggerRepository repository = LogManager.GetRepository();
IAppender[] appenders = repository.GetAppenders();
foreach (IAppender appender in appenders)
{
if (appender.Name == "Console")
{
m_consoleAppender = (OpenSimAppender)appender;
}
else if (appender.Name == "LogFileAppender")
{
m_logFileAppender = (FileAppender)appender;
}
}
if (null == m_consoleAppender)
{
Notice("No appender named Console found (see the log4net config file for this executable)!");
}
else
{
// FIXME: This should be done through an interface rather than casting.
m_consoleAppender.Console = (ConsoleBase)m_console;
// If there is no threshold set then the threshold is effectively everything.
if (null == m_consoleAppender.Threshold)
m_consoleAppender.Threshold = Level.All;
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
}
if (m_logFileAppender != null && startupConfig != null)
{
string cfgFileName = startupConfig.GetString("LogFile", null);
if (cfgFileName != null)
{
m_logFileAppender.File = cfgFileName;
m_logFileAppender.ActivateOptions();
}
m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File);
}
}
/// <summary>
/// Register common commands once m_console has been set if it is going to be set
/// </summary>
public void RegisterCommonCommands()
{
if (m_console == null)
return;
m_console.Commands.AddCommand(
"General", false, "show info", "show info", "Show general information about the server", HandleShow);
m_console.Commands.AddCommand(
"General", false, "show version", "show version", "Show server version", HandleShow);
m_console.Commands.AddCommand(
"General", false, "show uptime", "show uptime", "Show server uptime", HandleShow);
m_console.Commands.AddCommand(
"General", false, "get log level", "get log level", "Get the current console logging level",
(mod, cmd) => ShowLogLevel());
m_console.Commands.AddCommand(
"General", false, "set log level", "set log level <level>",
"Set the console logging level for this session.", HandleSetLogLevel);
m_console.Commands.AddCommand(
"General", false, "config set",
"config set <section> <key> <value>",
"Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
m_console.Commands.AddCommand(
"General", false, "config get",
"config get [<section>] [<key>]",
"Synonym for config show",
HandleConfig);
m_console.Commands.AddCommand(
"General", false, "config show",
"config show [<section>] [<key>]",
"Show config information",
"If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
+ "If a section is given but not a field, then all fields in that section are printed.",
HandleConfig);
m_console.Commands.AddCommand(
"General", false, "config save",
"config save <path>",
"Save current configuration to a file at the given path", HandleConfig);
m_console.Commands.AddCommand(
"General", false, "command-script",
"command-script <script>",
"Run a command script from file", HandleScript);
m_console.Commands.AddCommand(
"General", false, "show threads",
"show threads",
"Show thread status", HandleShow);
m_console.Commands.AddCommand(
"General", false, "threads abort",
"threads abort <thread-id>",
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
m_console.Commands.AddCommand(
"General", false, "threads show",
"threads show",
"Show thread status. Synonym for \"show threads\"",
(string module, string[] args) => Notice(GetThreadsReport()));
m_console.Commands.AddCommand(
"General", false, "force gc",
"force gc",
"Manually invoke runtime garbage collection. For debugging purposes",
HandleForceGc);
}
private void HandleForceGc(string module, string[] args)
{
Notice("Manually invoking runtime garbage collection");
GC.Collect();
}
public virtual void HandleShow(string module, string[] cmd)
{
List<string> args = new List<string>(cmd);
args.RemoveAt(0);
string[] showParams = args.ToArray();
switch (showParams[0])
{
case "info":
ShowInfo();
break;
case "version":
Notice(GetVersionText());
break;
case "uptime":
Notice(GetUptimeReport());
break;
case "threads":
Notice(GetThreadsReport());
break;
}
}
/// <summary>
/// Change and load configuration file data.
/// </summary>
/// <param name="module"></param>
/// <param name="cmd"></param>
private void HandleConfig(string module, string[] cmd)
{
List<string> args = new List<string>(cmd);
args.RemoveAt(0);
string[] cmdparams = args.ToArray();
if (cmdparams.Length > 0)
{
string firstParam = cmdparams[0].ToLower();
switch (firstParam)
{
case "set":
if (cmdparams.Length < 4)
{
Notice("Syntax: config set <section> <key> <value>");
Notice("Example: config set ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
}
else
{
IConfig c;
IConfigSource source = new IniConfigSource();
c = source.AddConfig(cmdparams[1]);
if (c != null)
{
string _value = String.Join(" ", cmdparams, 3, cmdparams.Length - 3);
c.Set(cmdparams[2], _value);
Config.Merge(source);
Notice("In section [{0}], set {1} = {2}", c.Name, cmdparams[2], _value);
}
}
break;
case "get":
case "show":
if (cmdparams.Length == 1)
{
foreach (IConfig config in Config.Configs)
{
Notice("[{0}]", config.Name);
string[] keys = config.GetKeys();
foreach (string key in keys)
Notice(" {0} = {1}", key, config.GetString(key));
}
}
else if (cmdparams.Length == 2 || cmdparams.Length == 3)
{
IConfig config = Config.Configs[cmdparams[1]];
if (config == null)
{
Notice("Section \"{0}\" does not exist.",cmdparams[1]);
break;
}
else
{
if (cmdparams.Length == 2)
{
Notice("[{0}]", config.Name);
foreach (string key in config.GetKeys())
Notice(" {0} = {1}", key, config.GetString(key));
}
else
{
Notice(
"config get {0} {1} : {2}",
cmdparams[1], cmdparams[2], config.GetString(cmdparams[2]));
}
}
}
else
{
Notice("Syntax: config {0} [<section>] [<key>]", firstParam);
Notice("Example: config {0} ScriptEngine.DotNetEngine NumberOfScriptThreads", firstParam);
}
break;
case "save":
if (cmdparams.Length < 2)
{
Notice("Syntax: config save <path>");
return;
}
string path = cmdparams[1];
Notice("Saving configuration file: {0}", path);
if (Config is IniConfigSource)
{
IniConfigSource iniCon = (IniConfigSource)Config;
iniCon.Save(path);
}
else if (Config is XmlConfigSource)
{
XmlConfigSource xmlCon = (XmlConfigSource)Config;
xmlCon.Save(path);
}
break;
}
}
}
private void HandleSetLogLevel(string module, string[] cmd)
{
if (cmd.Length != 4)
{
Notice("Usage: set log level <level>");
return;
}
if (null == m_consoleAppender)
{
Notice("No appender named Console found (see the log4net config file for this executable)!");
return;
}
string rawLevel = cmd[3];
ILoggerRepository repository = LogManager.GetRepository();
Level consoleLevel = repository.LevelMap[rawLevel];
if (consoleLevel != null)
m_consoleAppender.Threshold = consoleLevel;
else
Notice(
"{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
rawLevel);
ShowLogLevel();
}
private void ShowLogLevel()
{
Notice("Console log level is {0}", m_consoleAppender.Threshold);
}
protected virtual void HandleScript(string module, string[] parms)
{
if (parms.Length != 2)
{
Notice("Usage: command-script <path-to-script");
return;
}
RunCommandScript(parms[1]);
}
/// <summary>
/// Run an optional startup list of commands
/// </summary>
/// <param name="fileName"></param>
protected void RunCommandScript(string fileName)
{
if (m_console == null)
return;
if (File.Exists(fileName))
{
m_log.Info("[SERVER BASE]: Running " + fileName);
using (StreamReader readFile = File.OpenText(fileName))
{
string currentCommand;
while ((currentCommand = readFile.ReadLine()) != null)
{
currentCommand = currentCommand.Trim();
if (!(currentCommand == ""
|| currentCommand.StartsWith(";")
|| currentCommand.StartsWith("//")
|| currentCommand.StartsWith("#")))
{
m_log.Info("[SERVER BASE]: Running '" + currentCommand + "'");
m_console.RunCommand(currentCommand);
}
}
}
}
}
/// <summary>
/// Return a report about the uptime of this server
/// </summary>
/// <returns></returns>
protected string GetUptimeReport()
{
StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now));
sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime));
sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime));
return sb.ToString();
}
protected void ShowInfo()
{
Notice(GetVersionText());
Notice("Startup directory: " + m_startupDirectory);
if (null != m_consoleAppender)
Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold));
}
/// <summary>
/// Enhance the version string with extra information if it's available.
/// </summary>
protected void EnhanceVersionInformation()
{
string buildVersion = string.Empty;
// The subversion information is deprecated and will be removed at a later date
// Add subversion revision information if available
// Try file "svn_revision" in the current directory first, then the .svn info.
// This allows to make the revision available in simulators not running from the source tree.
// FIXME: Making an assumption about the directory we're currently in - we do this all over the place
// elsewhere as well
string gitDir = "../.git/";
string gitRefPointerPath = gitDir + "HEAD";
string svnRevisionFileName = "svn_revision";
string svnFileName = ".svn/entries";
string manualVersionFileName = ".version";
string inputLine;
int strcmp;
if (File.Exists(manualVersionFileName))
{
using (StreamReader CommitFile = File.OpenText(manualVersionFileName))
buildVersion = CommitFile.ReadLine();
m_version += buildVersion ?? "";
}
else if (File.Exists(gitRefPointerPath))
{
// m_log.DebugFormat("[SERVER BASE]: Found {0}", gitRefPointerPath);
string rawPointer = "";
using (StreamReader pointerFile = File.OpenText(gitRefPointerPath))
rawPointer = pointerFile.ReadLine();
// m_log.DebugFormat("[SERVER BASE]: rawPointer [{0}]", rawPointer);
Match m = Regex.Match(rawPointer, "^ref: (.+)$");
if (m.Success)
{
// m_log.DebugFormat("[SERVER BASE]: Matched [{0}]", m.Groups[1].Value);
string gitRef = m.Groups[1].Value;
string gitRefPath = gitDir + gitRef;
if (File.Exists(gitRefPath))
{
// m_log.DebugFormat("[SERVER BASE]: Found gitRefPath [{0}]", gitRefPath);
using (StreamReader refFile = File.OpenText(gitRefPath))
{
string gitHash = refFile.ReadLine();
m_version += gitHash.Substring(0, 7);
}
}
}
}
else
{
// Remove the else logic when subversion mirror is no longer used
if (File.Exists(svnRevisionFileName))
{
StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
buildVersion = RevisionFile.ReadLine();
buildVersion.Trim();
RevisionFile.Close();
}
if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))
{
StreamReader EntriesFile = File.OpenText(svnFileName);
inputLine = EntriesFile.ReadLine();
while (inputLine != null)
{
// using the dir svn revision at the top of entries file
strcmp = String.Compare(inputLine, "dir");
if (strcmp == 0)
{
buildVersion = EntriesFile.ReadLine();
break;
}
else
{
inputLine = EntriesFile.ReadLine();
}
}
EntriesFile.Close();
}
m_version += string.IsNullOrEmpty(buildVersion) ? " " : ("." + buildVersion + " ").Substring(0, 6);
}
}
protected string GetVersionText()
{
return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion);
}
/// <summary>
/// Get a report about the registered threads in this server.
/// </summary>
protected string GetThreadsReport()
{
// This should be a constant field.
string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
StringBuilder sb = new StringBuilder();
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo();
sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
int timeNow = Environment.TickCount & Int32.MaxValue;
sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE");
sb.Append(Environment.NewLine);
foreach (Watchdog.ThreadWatchdogInfo twi in threads)
{
Thread t = twi.Thread;
sb.AppendFormat(
reportFormat,
t.ManagedThreadId,
t.Name,
timeNow - twi.LastTick,
timeNow - twi.FirstTick,
t.Priority,
t.ThreadState);
sb.Append("\n");
}
sb.Append("\n");
// For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
// zero active threads.
int totalThreads = Process.GetCurrentProcess().Threads.Count;
if (totalThreads > 0)
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
sb.Append("Main threadpool (excluding script engine pools)\n");
sb.Append(Util.GetThreadPoolReport());
return sb.ToString();
}
public virtual void HandleThreadsAbort(string module, string[] cmd)
{
if (cmd.Length != 3)
{
MainConsole.Instance.Output("Usage: threads abort <thread-id>");
return;
}
int threadId;
if (!int.TryParse(cmd[2], out threadId))
{
MainConsole.Instance.Output("ERROR: Thread id must be an integer");
return;
}
if (Watchdog.AbortThread(threadId))
MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
else
MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
}
/// <summary>
/// Console output is only possible if a console has been established.
/// That is something that cannot be determined within this class. So
/// all attempts to use the console MUST be verified.
/// </summary>
/// <param name="msg"></param>
protected void Notice(string msg)
{
if (m_console != null)
{
m_console.Output(msg);
}
}
/// <summary>
/// Console output is only possible if a console has been established.
/// That is something that cannot be determined within this class. So
/// all attempts to use the console MUST be verified.
/// </summary>
/// <param name="format"></param>
/// <param name="components"></param>
protected void Notice(string format, params object[] components)
{
if (m_console != null)
m_console.OutputFormat(format, components);
}
}
}

View File

@ -35,11 +35,12 @@ using HttpServer;
using HttpServer.FormDecoders; using HttpServer.FormDecoders;
using NUnit.Framework; using NUnit.Framework;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Tests.Common;
namespace OpenSim.Framework.Servers.Tests namespace OpenSim.Framework.Servers.Tests
{ {
[TestFixture] [TestFixture]
public class OSHttpTests public class OSHttpTests : OpenSimTestCase
{ {
// we need an IHttpClientContext for our tests // we need an IHttpClientContext for our tests
public class TestHttpClientContext: IHttpClientContext public class TestHttpClientContext: IHttpClientContext

View File

@ -29,11 +29,12 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using NUnit.Framework; using NUnit.Framework;
using OpenSim.Tests.Common;
namespace OpenSim.Framework.Servers.Tests namespace OpenSim.Framework.Servers.Tests
{ {
[TestFixture] [TestFixture]
public class VersionInfoTests public class VersionInfoTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestVersionLength() public void TestVersionLength()

View File

@ -24,16 +24,17 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System.Collections.Generic; using System.Collections.Generic;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using NUnit.Framework; using NUnit.Framework;
using OpenSim.Tests.Common;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class AgentCircuitDataTest public class AgentCircuitDataTest : OpenSimTestCase
{ {
private UUID AgentId; private UUID AgentId;
private AvatarAppearance AvAppearance; private AvatarAppearance AvAppearance;

View File

@ -38,7 +38,7 @@ using Animation = OpenSim.Framework.Animation;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class AnimationTests public class AnimationTests : OpenSimTestCase
{ {
private Animation anim1 = null; private Animation anim1 = null;
private Animation anim2 = null; private Animation anim2 = null;

View File

@ -30,11 +30,12 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using NUnit.Framework; using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Tests.Common;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class AssetBaseTest public class AssetBaseTest : OpenSimTestCase
{ {
[Test] [Test]
public void TestContainsReferences() public void TestContainsReferences()

View File

@ -28,11 +28,12 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Tests.Common;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class CacheTests public class CacheTests : OpenSimTestCase
{ {
private Cache cache; private Cache cache;
private UUID cacheItemUUID; private UUID cacheItemUUID;

View File

@ -26,11 +26,12 @@
*/ */
using NUnit.Framework; using NUnit.Framework;
using OpenSim.Tests.Common;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class LocationTest public class LocationTest : OpenSimTestCase
{ {
[Test] [Test]
public void locationRegionHandleRegionHandle() public void locationRegionHandleRegionHandle()

View File

@ -32,11 +32,12 @@ using OpenMetaverse.StructuredData;
using System; using System;
using System.Globalization; using System.Globalization;
using System.Threading; using System.Threading;
using OpenSim.Tests.Common;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class MundaneFrameworkTests public class MundaneFrameworkTests : OpenSimTestCase
{ {
private bool m_RegionSettingsOnSaveEventFired; private bool m_RegionSettingsOnSaveEventFired;
private bool m_RegionLightShareDataOnSaveEventFired; private bool m_RegionLightShareDataOnSaveEventFired;

View File

@ -31,11 +31,12 @@ using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Tests.Common;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class PrimeNumberHelperTests public class PrimeNumberHelperTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestGetPrime() public void TestGetPrime()

View File

@ -33,7 +33,7 @@ using OpenSim.Tests.Common;
namespace OpenSim.Framework.Tests namespace OpenSim.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class UtilTests public class UtilTests : OpenSimTestCase
{ {
[Test] [Test]
public void VectorOperationTests() public void VectorOperationTests()

View File

@ -1741,12 +1741,16 @@ namespace OpenSim.Framework
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
{ {
threadPoolUsed = "SmartThreadPool"; // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
maxThreads = m_ThreadPool.MaxThreads; if (m_ThreadPool != null)
minThreads = m_ThreadPool.MinThreads; {
inUseThreads = m_ThreadPool.InUseThreads; threadPoolUsed = "SmartThreadPool";
allocatedThreads = m_ThreadPool.ActiveThreads; maxThreads = m_ThreadPool.MaxThreads;
waitingCallbacks = m_ThreadPool.WaitingCallbacks; minThreads = m_ThreadPool.MinThreads;
inUseThreads = m_ThreadPool.InUseThreads;
allocatedThreads = m_ThreadPool.ActiveThreads;
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
}
} }
else if ( else if (
FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem

View File

@ -188,7 +188,6 @@ namespace OpenSim
// Make sure command line options take precedence // Make sure command line options take precedence
m_config.Source.Merge(argvSource); m_config.Source.Merge(argvSource);
IConfig enVars = m_config.Source.Configs["Environment"]; IConfig enVars = m_config.Source.Configs["Environment"];
if( enVars != null ) if( enVars != null )

View File

@ -82,8 +82,8 @@ namespace OpenSim
{ {
base.ReadExtraConfigSettings(); base.ReadExtraConfigSettings();
IConfig startupConfig = m_config.Source.Configs["Startup"]; IConfig startupConfig = Config.Configs["Startup"];
IConfig networkConfig = m_config.Source.Configs["Network"]; IConfig networkConfig = Config.Configs["Network"];
int stpMaxThreads = 15; int stpMaxThreads = 15;
@ -106,22 +106,6 @@ namespace OpenSim
m_timeInterval = startupConfig.GetInt("timer_Interval", 1200); m_timeInterval = startupConfig.GetInt("timer_Interval", 1200);
} }
if (m_logFileAppender != null)
{
if (m_logFileAppender is log4net.Appender.FileAppender)
{
log4net.Appender.FileAppender appender =
(log4net.Appender.FileAppender)m_logFileAppender;
string fileName = startupConfig.GetString("LogFile", String.Empty);
if (fileName != String.Empty)
{
appender.File = fileName;
appender.ActivateOptions();
}
m_log.InfoFormat("[LOGGING]: Logging started to file {0}", appender.File);
}
}
string asyncCallMethodStr = startupConfig.GetString("async_call_method", String.Empty); string asyncCallMethodStr = startupConfig.GetString("async_call_method", String.Empty);
FireAndForgetMethod asyncCallMethod; FireAndForgetMethod asyncCallMethod;
if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod)) if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod))
@ -164,7 +148,7 @@ namespace OpenSim
break; break;
case "rest": case "rest":
m_console = new RemoteConsole("Region"); m_console = new RemoteConsole("Region");
((RemoteConsole)m_console).ReadConfig(m_config.Source); ((RemoteConsole)m_console).ReadConfig(Config);
break; break;
default: default:
m_console = new LocalConsole("Region"); m_console = new LocalConsole("Region");
@ -174,6 +158,7 @@ namespace OpenSim
MainConsole.Instance = m_console; MainConsole.Instance = m_console;
RegisterCommonAppenders(Config.Configs["Startup"]);
RegisterConsoleCommands(); RegisterConsoleCommands();
base.StartupSpecific(); base.StartupSpecific();
@ -372,26 +357,6 @@ namespace OpenSim
"restart", "restart",
"Restart all sims in this instance", RunCommand); "Restart all sims in this instance", RunCommand);
m_console.Commands.AddCommand("General", false, "config set",
"config set <section> <key> <value>",
"Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
m_console.Commands.AddCommand("General", false, "config get",
"config get [<section>] [<key>]",
"Synonym for config show",
HandleConfig);
m_console.Commands.AddCommand("General", false, "config show",
"config show [<section>] [<key>]",
"Show config information",
"If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
+ "If a section is given but not a field, then all fields in that section are printed.",
HandleConfig);
m_console.Commands.AddCommand("General", false, "config save",
"config save <path>",
"Save current configuration to a file at the given path", HandleConfig);
m_console.Commands.AddCommand("General", false, "command-script", m_console.Commands.AddCommand("General", false, "command-script",
"command-script <script>", "command-script <script>",
"Run a command script from file", RunCommand); "Run a command script from file", RunCommand);
@ -501,35 +466,6 @@ namespace OpenSim
MainConsole.Instance.Output(""); MainConsole.Instance.Output("");
} }
/// <summary>
/// Run an optional startup list of commands
/// </summary>
/// <param name="fileName"></param>
private void RunCommandScript(string fileName)
{
if (File.Exists(fileName))
{
m_log.Info("[COMMANDFILE]: Running " + fileName);
using (StreamReader readFile = File.OpenText(fileName))
{
string currentCommand;
while ((currentCommand = readFile.ReadLine()) != null)
{
currentCommand = currentCommand.Trim();
if (!(currentCommand == ""
|| currentCommand.StartsWith(";")
|| currentCommand.StartsWith("//")
|| currentCommand.StartsWith("#")))
{
m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'");
m_console.RunCommand(currentCommand);
}
}
}
}
}
/// <summary> /// <summary>
/// Opens a file and uses it as input to the console command parser. /// Opens a file and uses it as input to the console command parser.
/// </summary> /// </summary>
@ -634,111 +570,9 @@ namespace OpenSim
bool changed = PopulateRegionEstateInfo(regInfo); bool changed = PopulateRegionEstateInfo(regInfo);
IScene scene; IScene scene;
CreateRegion(regInfo, true, out scene); CreateRegion(regInfo, true, out scene);
if (changed) if (changed)
regInfo.EstateSettings.Save(); regInfo.EstateSettings.Save();
}
/// <summary>
/// Change and load configuration file data.
/// </summary>
/// <param name="module"></param>
/// <param name="cmd"></param>
private void HandleConfig(string module, string[] cmd)
{
List<string> args = new List<string>(cmd);
args.RemoveAt(0);
string[] cmdparams = args.ToArray();
if (cmdparams.Length > 0)
{
string firstParam = cmdparams[0].ToLower();
switch (firstParam)
{
case "set":
if (cmdparams.Length < 4)
{
Notice("Syntax: config set <section> <key> <value>");
Notice("Example: config set ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
}
else
{
IConfig c;
IConfigSource source = new IniConfigSource();
c = source.AddConfig(cmdparams[1]);
if (c != null)
{
string _value = String.Join(" ", cmdparams, 3, cmdparams.Length - 3);
c.Set(cmdparams[2], _value);
m_config.Source.Merge(source);
Notice("In section [{0}], set {1} = {2}", c.Name, cmdparams[2], _value);
}
}
break;
case "get":
case "show":
if (cmdparams.Length == 1)
{
foreach (IConfig config in m_config.Source.Configs)
{
Notice("[{0}]", config.Name);
string[] keys = config.GetKeys();
foreach (string key in keys)
Notice(" {0} = {1}", key, config.GetString(key));
}
}
else if (cmdparams.Length == 2 || cmdparams.Length == 3)
{
IConfig config = m_config.Source.Configs[cmdparams[1]];
if (config == null)
{
Notice("Section \"{0}\" does not exist.",cmdparams[1]);
break;
}
else
{
if (cmdparams.Length == 2)
{
Notice("[{0}]", config.Name);
foreach (string key in config.GetKeys())
Notice(" {0} = {1}", key, config.GetString(key));
}
else
{
Notice(
"config get {0} {1} : {2}",
cmdparams[1], cmdparams[2], config.GetString(cmdparams[2]));
}
}
}
else
{
Notice("Syntax: config {0} [<section>] [<key>]", firstParam);
Notice("Example: config {0} ScriptEngine.DotNetEngine NumberOfScriptThreads", firstParam);
}
break;
case "save":
if (cmdparams.Length < 2)
{
Notice("Syntax: config save <path>");
return;
}
if (Application.iniFilePath == cmdparams[1])
{
Notice("Path can not be " + Application.iniFilePath);
return;
}
Notice("Saving configuration file: " + cmdparams[1]);
m_config.Save(cmdparams[1]);
break;
}
}
} }
/// <summary> /// <summary>
@ -787,13 +621,6 @@ namespace OpenSim
switch (command) switch (command)
{ {
case "command-script":
if (cmdparams.Length > 0)
{
RunCommandScript(cmdparams[0]);
}
break;
case "backup": case "backup":
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store"); MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
SceneManager.BackupCurrentScene(); SceneManager.BackupCurrentScene();
@ -837,12 +664,20 @@ namespace OpenSim
if (!SceneManager.TrySetCurrentScene(newRegionName)) if (!SceneManager.TrySetCurrentScene(newRegionName))
MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName)); MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName));
else
RefreshPrompt();
} }
else else
{ {
MainConsole.Instance.Output("Usage: change region <region name>"); MainConsole.Instance.Output("Usage: change region <region name>");
} }
}
/// <summary>
/// Refreshs prompt with the current selection details.
/// </summary>
private void RefreshPrompt()
{
string regionName = (SceneManager.CurrentScene == null ? "root" : SceneManager.CurrentScene.RegionInfo.RegionName); string regionName = (SceneManager.CurrentScene == null ? "root" : SceneManager.CurrentScene.RegionInfo.RegionName);
MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName)); MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
@ -864,6 +699,18 @@ namespace OpenSim
m_console.ConsoleScene = SceneManager.CurrentScene; m_console.ConsoleScene = SceneManager.CurrentScene;
} }
protected override void HandleRestartRegion(RegionInfo whichRegion)
{
base.HandleRestartRegion(whichRegion);
// Where we are restarting multiple scenes at once, a previous call to RefreshPrompt may have set the
// m_console.ConsoleScene to null (indicating all scenes).
if (m_console.ConsoleScene != null && whichRegion.RegionName == ((Scene)m_console.ConsoleScene).Name)
SceneManager.TrySetCurrentScene(whichRegion.RegionName);
RefreshPrompt();
}
/// <summary> /// <summary>
/// Turn on some debugging values for OpenSim. /// Turn on some debugging values for OpenSim.
/// </summary> /// </summary>

View File

@ -100,13 +100,7 @@ namespace OpenSim
/// <value> /// <value>
/// The config information passed into the OpenSimulator region server. /// The config information passed into the OpenSimulator region server.
/// </value> /// </value>
public OpenSimConfigSource ConfigSource public OpenSimConfigSource ConfigSource { get; private set; }
{
get { return m_config; }
set { m_config = value; }
}
protected OpenSimConfigSource m_config;
public List<IClientNetworkServer> ClientServers public List<IClientNetworkServer> ClientServers
{ {
@ -146,13 +140,14 @@ namespace OpenSim
protected virtual void LoadConfigSettings(IConfigSource configSource) protected virtual void LoadConfigSettings(IConfigSource configSource)
{ {
m_configLoader = new ConfigurationLoader(); m_configLoader = new ConfigurationLoader();
m_config = m_configLoader.LoadConfigSettings(configSource, envConfigSource, out m_configSettings, out m_networkServersInfo); ConfigSource = m_configLoader.LoadConfigSettings(configSource, envConfigSource, out m_configSettings, out m_networkServersInfo);
Config = ConfigSource.Source;
ReadExtraConfigSettings(); ReadExtraConfigSettings();
} }
protected virtual void ReadExtraConfigSettings() protected virtual void ReadExtraConfigSettings()
{ {
IConfig networkConfig = m_config.Source.Configs["Network"]; IConfig networkConfig = Config.Configs["Network"];
if (networkConfig != null) if (networkConfig != null)
{ {
proxyUrl = networkConfig.GetString("proxy_url", ""); proxyUrl = networkConfig.GetString("proxy_url", "");
@ -185,7 +180,7 @@ namespace OpenSim
/// </summary> /// </summary>
protected override void StartupSpecific() protected override void StartupSpecific()
{ {
IConfig startupConfig = m_config.Source.Configs["Startup"]; IConfig startupConfig = Config.Configs["Startup"];
if (startupConfig != null) if (startupConfig != null)
{ {
string pidFile = startupConfig.GetString("PIDFile", String.Empty); string pidFile = startupConfig.GetString("PIDFile", String.Empty);
@ -196,7 +191,7 @@ namespace OpenSim
} }
// Load the simulation data service // Load the simulation data service
IConfig simDataConfig = m_config.Source.Configs["SimulationDataStore"]; IConfig simDataConfig = Config.Configs["SimulationDataStore"];
if (simDataConfig == null) if (simDataConfig == null)
throw new Exception("Configuration file is missing the [SimulationDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?"); throw new Exception("Configuration file is missing the [SimulationDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?");
@ -204,7 +199,7 @@ namespace OpenSim
if (String.IsNullOrEmpty(module)) if (String.IsNullOrEmpty(module))
throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [SimulationDataStore] section."); throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [SimulationDataStore] section.");
m_simulationDataService = ServerUtils.LoadPlugin<ISimulationDataService>(module, new object[] { m_config.Source }); m_simulationDataService = ServerUtils.LoadPlugin<ISimulationDataService>(module, new object[] { Config });
if (m_simulationDataService == null) if (m_simulationDataService == null)
throw new Exception( throw new Exception(
string.Format( string.Format(
@ -212,7 +207,7 @@ namespace OpenSim
module)); module));
// Load the estate data service // Load the estate data service
IConfig estateDataConfig = m_config.Source.Configs["EstateDataStore"]; IConfig estateDataConfig = Config.Configs["EstateDataStore"];
if (estateDataConfig == null) if (estateDataConfig == null)
throw new Exception("Configuration file is missing the [EstateDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?"); throw new Exception("Configuration file is missing the [EstateDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?");
@ -220,7 +215,7 @@ namespace OpenSim
if (String.IsNullOrEmpty(module)) if (String.IsNullOrEmpty(module))
throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [EstateDataStore] section"); throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [EstateDataStore] section");
m_estateDataService = ServerUtils.LoadPlugin<IEstateDataService>(module, new object[] { m_config.Source }); m_estateDataService = ServerUtils.LoadPlugin<IEstateDataService>(module, new object[] { Config });
if (m_estateDataService == null) if (m_estateDataService == null)
throw new Exception( throw new Exception(
string.Format( string.Format(
@ -242,7 +237,7 @@ namespace OpenSim
} }
} }
protected virtual void AddPluginCommands(CommandConsole console) protected virtual void AddPluginCommands(ICommandConsole console)
{ {
List<string> topics = GetHelpTopics(); List<string> topics = GetHelpTopics();
@ -304,7 +299,7 @@ namespace OpenSim
// Called from base.StartUp() // Called from base.StartUp()
m_httpServerPort = m_networkServersInfo.HttpListenerPort; m_httpServerPort = m_networkServersInfo.HttpListenerPort;
SceneManager.OnRestartSim += handleRestartRegion; SceneManager.OnRestartSim += HandleRestartRegion;
// Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is // Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is
// heavily used during initial startup. // heavily used during initial startup.
@ -369,7 +364,7 @@ namespace OpenSim
} }
IClientNetworkServer clientServer; IClientNetworkServer clientServer;
Scene scene = SetupScene(regionInfo, proxyOffset, m_config.Source, out clientServer); Scene scene = SetupScene(regionInfo, proxyOffset, Config, out clientServer);
m_log.Info("[MODULES]: Loading Region's modules (old style)"); m_log.Info("[MODULES]: Loading Region's modules (old style)");
@ -451,10 +446,10 @@ namespace OpenSim
string estateOwnerPassword = null; string estateOwnerPassword = null;
string rawEstateOwnerUuid = null; string rawEstateOwnerUuid = null;
if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null) if (Config.Configs[ESTATE_SECTION_NAME] != null)
{ {
string defaultEstateOwnerName string defaultEstateOwnerName
= m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerName", "").Trim(); = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerName", "").Trim();
string[] ownerNames = defaultEstateOwnerName.Split(' '); string[] ownerNames = defaultEstateOwnerName.Split(' ');
if (ownerNames.Length >= 2) if (ownerNames.Length >= 2)
@ -464,9 +459,9 @@ namespace OpenSim
} }
// Info to be used only on Standalone Mode // Info to be used only on Standalone Mode
rawEstateOwnerUuid = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerUUID", null); rawEstateOwnerUuid = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerUUID", null);
estateOwnerEMail = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerEMail", null); estateOwnerEMail = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerEMail", null);
estateOwnerPassword = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerPassword", null); estateOwnerPassword = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerPassword", null);
} }
MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName); MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
@ -713,7 +708,7 @@ namespace OpenSim
return new Scene( return new Scene(
regionInfo, circuitManager, sceneGridService, regionInfo, circuitManager, sceneGridService,
simDataService, estateDataService, false, simDataService, estateDataService, false,
m_config.Source, m_version); Config, m_version);
} }
protected void ShutdownClientServer(RegionInfo whichRegion) protected void ShutdownClientServer(RegionInfo whichRegion)
@ -740,9 +735,11 @@ namespace OpenSim
} }
} }
public void handleRestartRegion(RegionInfo whichRegion) protected virtual void HandleRestartRegion(RegionInfo whichRegion)
{ {
m_log.Info("[OPENSIM]: Got restart signal from SceneManager"); m_log.InfoFormat(
"[OPENSIM]: Got restart signal from SceneManager for region {0} ({1},{2})",
whichRegion.RegionName, whichRegion.RegionLocX, whichRegion.RegionLocY);
ShutdownClientServer(whichRegion); ShutdownClientServer(whichRegion);
IScene scene; IScene scene;
@ -754,7 +751,7 @@ namespace OpenSim
protected override PhysicsScene GetPhysicsScene(string osSceneIdentifier) protected override PhysicsScene GetPhysicsScene(string osSceneIdentifier)
{ {
return GetPhysicsScene( return GetPhysicsScene(
m_configSettings.PhysicsEngine, m_configSettings.MeshEngineName, m_config.Source, osSceneIdentifier); m_configSettings.PhysicsEngine, m_configSettings.MeshEngineName, Config, osSceneIdentifier);
} }
/// <summary> /// <summary>
@ -888,7 +885,6 @@ namespace OpenSim
m_log.Info("[SHUTDOWN]: Closing all threads"); m_log.Info("[SHUTDOWN]: Closing all threads");
m_log.Info("[SHUTDOWN]: Killing listener thread"); m_log.Info("[SHUTDOWN]: Killing listener thread");
m_log.Info("[SHUTDOWN]: Killing clients"); m_log.Info("[SHUTDOWN]: Killing clients");
// TODO: implement this
m_log.Info("[SHUTDOWN]: Closing console and terminating"); m_log.Info("[SHUTDOWN]: Closing console and terminating");
try try
@ -897,7 +893,7 @@ namespace OpenSim
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[SHUTDOWN]: Ignoring failure during shutdown - {0}", e); m_log.Error("[SHUTDOWN]: Ignoring failure during shutdown - ", e);
} }
} }
@ -991,9 +987,9 @@ namespace OpenSim
string defaultEstateName = null; string defaultEstateName = null;
if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null) if (Config.Configs[ESTATE_SECTION_NAME] != null)
{ {
defaultEstateName = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateName", null); defaultEstateName = Config.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateName", null);
if (defaultEstateName != null) if (defaultEstateName != null)
{ {
@ -1076,28 +1072,14 @@ namespace OpenSim
MainConsole.Instance.Output("Joining the estate failed. Please try again."); MainConsole.Instance.Output("Joining the estate failed. Please try again.");
} }
} }
} }
return true; // need to update the database return true; // need to update the database
} }
} }
public class OpenSimConfigSource public class OpenSimConfigSource
{ {
public IConfigSource Source; public IConfigSource Source;
public void Save(string path)
{
if (Source is IniConfigSource)
{
IniConfigSource iniCon = (IniConfigSource) Source;
iniCon.Save(path);
}
else if (Source is XmlConfigSource)
{
XmlConfigSource xmlCon = (XmlConfigSource) Source;
xmlCon.Save(path);
}
}
} }
} }

View File

@ -44,7 +44,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.ClientStack.Linden.Tests namespace OpenSim.Region.ClientStack.Linden.Tests
{ {
[TestFixture] [TestFixture]
public class EventQueueTests public class EventQueueTests : OpenSimTestCase
{ {
private TestScene m_scene; private TestScene m_scene;

View File

@ -5320,9 +5320,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory); AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory);
AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory); AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory);
AddLocalPacketHandler(PacketType.RezScript, HandleRezScript); AddLocalPacketHandler(PacketType.RezScript, HandleRezScript);
AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest, false); AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest);
AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest, false); AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest);
AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest, false); AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest);
AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest);
AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);

View File

@ -70,6 +70,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void AddScene(IScene scene) public void AddScene(IScene scene)
{ {
m_udpServer.AddScene(scene); m_udpServer.AddScene(scene);
StatsManager.RegisterStat(
new Stat(
"IncomingPacketsProcessedCount",
"Number of inbound UDP packets processed",
"Number of inbound UDP packets processed",
"",
"clientstack",
scene.Name,
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = m_udpServer.IncomingPacketsProcessed,
StatVerbosity.Debug));
} }
public bool HandlesRegion(Location x) public bool HandlesRegion(Location x)
@ -170,6 +183,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private Pool<IncomingPacket> m_incomingPacketPool; private Pool<IncomingPacket> m_incomingPacketPool;
/// <summary>
/// Stat for number of packets in the main pool awaiting use.
/// </summary>
private Stat m_poolCountStat;
/// <summary>
/// Stat for number of packets in the inbound packet pool awaiting use.
/// </summary>
private Stat m_incomingPacketPoolStat; private Stat m_incomingPacketPoolStat;
private int m_defaultRTO = 0; private int m_defaultRTO = 0;
@ -342,20 +363,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
m_incomingPacketPoolStat
= new Stat(
"IncomingPacketPoolCount",
"Objects within incoming packet pool",
"The number of objects currently stored within the incoming packet pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => stat.Value = m_incomingPacketPool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_incomingPacketPoolStat);
return true; return true;
} }
@ -378,6 +385,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return false; return false;
} }
/// <summary>
/// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
/// stats.
/// </summary>
private void EnablePoolStats()
{
m_poolCountStat
= new Stat(
"UDPPacketBufferPoolCount",
"Objects within the UDPPacketBuffer pool",
"The number of objects currently stored within the UDPPacketBuffer pool",
"",
"clientstack",
m_scene.Name,
StatType.Pull,
stat => stat.Value = Pool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_poolCountStat);
m_incomingPacketPoolStat
= new Stat(
"IncomingPacketPoolCount",
"Objects within incoming packet pool",
"The number of objects currently stored within the incoming packet pool",
"",
"clientstack",
m_scene.Name,
StatType.Pull,
stat => stat.Value = m_incomingPacketPool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_incomingPacketPoolStat);
}
/// <summary>
/// Disables pool stats.
/// </summary>
private void DisablePoolStats()
{
StatsManager.DeregisterStat(m_poolCountStat);
m_poolCountStat = null;
StatsManager.DeregisterStat(m_incomingPacketPoolStat);
m_incomingPacketPoolStat = null;
}
/// <summary> /// <summary>
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
/// </summary> /// </summary>
@ -417,6 +471,65 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = (Scene)scene; m_scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle); m_location = new Location(m_scene.RegionInfo.RegionHandle);
// XXX: These stats are also pool stats but we register them separately since they are currently not
// turned on and off by EnablePools()/DisablePools()
StatsManager.RegisterStat(
new PercentageStat(
"PacketsReused",
"Packets reused",
"Number of packets reused out of all requests to the packet pool",
"clientstack",
m_scene.Name,
StatType.Pull,
stat =>
{ PercentageStat pstat = (PercentageStat)stat;
pstat.Consequent = PacketPool.Instance.PacketsRequested;
pstat.Antecedent = PacketPool.Instance.PacketsReused; },
StatVerbosity.Debug));
StatsManager.RegisterStat(
new PercentageStat(
"PacketDataBlocksReused",
"Packet data blocks reused",
"Number of data blocks reused out of all requests to the packet pool",
"clientstack",
m_scene.Name,
StatType.Pull,
stat =>
{ PercentageStat pstat = (PercentageStat)stat;
pstat.Consequent = PacketPool.Instance.BlocksRequested;
pstat.Antecedent = PacketPool.Instance.BlocksReused; },
StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"PacketsPoolCount",
"Objects within the packet pool",
"The number of objects currently stored within the packet pool",
"",
"clientstack",
m_scene.Name,
StatType.Pull,
stat => stat.Value = PacketPool.Instance.PacketsPooled,
StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"PacketDataBlocksPoolCount",
"Objects within the packet data block pool",
"The number of objects currently stored within the packet data block pool",
"",
"clientstack",
m_scene.Name,
StatType.Pull,
stat => stat.Value = PacketPool.Instance.BlocksPooled,
StatVerbosity.Debug));
// We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
// scene name
if (UsePools)
EnablePoolStats();
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
"Debug", "Debug",
false, false,
@ -505,12 +618,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (enabled == "on") if (enabled == "on")
{ {
if (EnablePools()) if (EnablePools())
{
EnablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name); MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
}
} }
else if (enabled == "off") else if (enabled == "off")
{ {
if (DisablePools()) if (DisablePools())
{
DisablePoolStats();
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name); MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
}
} }
else else
{ {
@ -1556,6 +1675,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int npacksSent = 0; private int npacksSent = 0;
private int npackNotSent = 0; private int npackNotSent = 0;
/// <summary>
/// Number of inbound packets processed since startup.
/// </summary>
public long IncomingPacketsProcessed { get; private set; }
private void MonitoredClientOutgoingPacketHandler(IClientAPI client) private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
{ {
nticks++; nticks++;
@ -1615,7 +1739,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
npacksSent++; npacksSent++;
} }
else else
{
npackNotSent++; npackNotSent++;
}
watch2.Stop(); watch2.Stop();
avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks); avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
@ -1623,7 +1749,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{
m_log.WarnFormat("[LLUDPSERVER]: Client is not connected"); m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
}
} }
} }
catch (Exception ex) catch (Exception ex)
@ -1687,6 +1815,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
packet.Type, client.Name, m_scene.RegionInfo.RegionName); packet.Type, client.Name, m_scene.RegionInfo.RegionName);
} }
IncomingPacketsProcessed++;
} }
protected void LogoutHandler(IClientAPI client) protected void LogoutHandler(IClientAPI client)

View File

@ -60,16 +60,16 @@ namespace OpenMetaverse
/// <summary>Flag to process packets asynchronously or synchronously</summary> /// <summary>Flag to process packets asynchronously or synchronously</summary>
private bool m_asyncPacketHandling; private bool m_asyncPacketHandling;
/// <summary>
/// Pool to use for handling data. May be null if UsePools = false;
/// </summary>
protected OpenSim.Framework.Pool<UDPPacketBuffer> m_pool;
/// <summary> /// <summary>
/// Are we to use object pool(s) to reduce memory churn when receiving data? /// Are we to use object pool(s) to reduce memory churn when receiving data?
/// </summary> /// </summary>
public bool UsePools { get; protected set; } public bool UsePools { get; protected set; }
/// <summary>
/// Pool to use for handling data. May be null if UsePools = false;
/// </summary>
protected OpenSim.Framework.Pool<UDPPacketBuffer> Pool { get; private set; }
/// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
public bool IsRunningInbound { get; private set; } public bool IsRunningInbound { get; private set; }
@ -77,8 +77,6 @@ namespace OpenMetaverse
/// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks> /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks>
public bool IsRunningOutbound { get; private set; } public bool IsRunningOutbound { get; private set; }
private Stat m_poolCountStat;
/// <summary> /// <summary>
/// Default constructor /// Default constructor
/// </summary> /// </summary>
@ -182,21 +180,7 @@ namespace OpenMetaverse
{ {
if (!UsePools) if (!UsePools)
{ {
m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); Pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
m_poolCountStat
= new Stat(
"UDPPacketBufferPoolCount",
"Objects within the UDPPacketBuffer pool",
"The number of objects currently stored within the UDPPacketBuffer pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => stat.Value = m_pool.Count,
StatVerbosity.Debug);
StatsManager.RegisterStat(m_poolCountStat);
UsePools = true; UsePools = true;
@ -211,7 +195,6 @@ namespace OpenMetaverse
if (UsePools) if (UsePools)
{ {
UsePools = false; UsePools = false;
StatsManager.DeregisterStat(m_poolCountStat);
// We won't null out the pool to avoid a race condition with code that may be in the middle of using it. // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
@ -226,7 +209,7 @@ namespace OpenMetaverse
UDPPacketBuffer buf; UDPPacketBuffer buf;
if (UsePools) if (UsePools)
buf = m_pool.GetObject(); buf = Pool.GetObject();
else else
buf = new UDPPacketBuffer(); buf = new UDPPacketBuffer();
@ -309,7 +292,7 @@ namespace OpenMetaverse
finally finally
{ {
if (UsePools) if (UsePools)
m_pool.ReturnObject(buffer); Pool.ReturnObject(buffer);
// Synchronous mode waits until the packet callback completes // Synchronous mode waits until the packet callback completes
// before starting the receive to fetch another packet // before starting the receive to fetch another packet

View File

@ -41,29 +41,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private static readonly PacketPool instance = new PacketPool(); private static readonly PacketPool instance = new PacketPool();
private bool packetPoolEnabled = true;
private bool dataBlockPoolEnabled = true;
private PercentageStat m_packetsReusedStat = new PercentageStat(
"PacketsReused",
"Packets reused",
"Number of packets reused out of all requests to the packet pool",
"clientstack",
"packetpool",
StatType.Push,
null,
StatVerbosity.Debug);
private PercentageStat m_blocksReusedStat = new PercentageStat(
"PacketDataBlocksReused",
"Packet data blocks reused",
"Number of data blocks reused out of all requests to the packet pool",
"clientstack",
"packetpool",
StatType.Push,
null,
StatVerbosity.Debug);
/// <summary> /// <summary>
/// Pool of packets available for reuse. /// Pool of packets available for reuse.
/// </summary> /// </summary>
@ -76,46 +53,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
get { return instance; } get { return instance; }
} }
public bool RecyclePackets public bool RecyclePackets { get; set; }
public bool RecycleDataBlocks { get; set; }
/// <summary>
/// The number of packets pooled
/// </summary>
public int PacketsPooled
{ {
set { packetPoolEnabled = value; } get
get { return packetPoolEnabled; } {
lock (pool)
return pool.Count;
}
} }
public bool RecycleDataBlocks /// <summary>
/// The number of blocks pooled.
/// </summary>
public int BlocksPooled
{ {
set { dataBlockPoolEnabled = value; } get
get { return dataBlockPoolEnabled; } {
lock (DataBlocks)
return DataBlocks.Count;
}
} }
/// <summary>
/// Number of packets requested.
/// </summary>
public long PacketsRequested { get; private set; }
/// <summary>
/// Number of packets reused.
/// </summary>
public long PacketsReused { get; private set; }
/// <summary>
/// Number of packet blocks requested.
/// </summary>
public long BlocksRequested { get; private set; }
/// <summary>
/// Number of packet blocks reused.
/// </summary>
public long BlocksReused { get; private set; }
private PacketPool() private PacketPool()
{ {
StatsManager.RegisterStat(m_packetsReusedStat); // defaults
StatsManager.RegisterStat(m_blocksReusedStat); RecyclePackets = true;
RecycleDataBlocks = true;
StatsManager.RegisterStat(
new Stat(
"PacketsPoolCount",
"Objects within the packet pool",
"The number of objects currently stored within the packet pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => { lock (pool) { stat.Value = pool.Count; } },
StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"PacketDataBlocksPoolCount",
"Objects within the packet data block pool",
"The number of objects currently stored within the packet data block pool",
"",
"clientstack",
"packetpool",
StatType.Pull,
stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } },
StatVerbosity.Debug));
} }
/// <summary> /// <summary>
@ -125,11 +115,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns> /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns>
public Packet GetPacket(PacketType type) public Packet GetPacket(PacketType type)
{ {
m_packetsReusedStat.Consequent++; PacketsRequested++;
Packet packet; Packet packet;
if (!packetPoolEnabled) if (!RecyclePackets)
return Packet.BuildPacket(type); return Packet.BuildPacket(type);
lock (pool) lock (pool)
@ -146,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type); // m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
// Recycle old packages // Recycle old packages
m_packetsReusedStat.Antecedent++; PacketsReused++;
packet = pool[type].Pop(); packet = pool[type].Pop();
} }
@ -215,7 +205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="packet"></param> /// <param name="packet"></param>
public void ReturnPacket(Packet packet) public void ReturnPacket(Packet packet)
{ {
if (dataBlockPoolEnabled) if (RecycleDataBlocks)
{ {
switch (packet.Type) switch (packet.Type)
{ {
@ -239,7 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
if (packetPoolEnabled) if (RecyclePackets)
{ {
switch (packet.Type) switch (packet.Type)
{ {
@ -277,7 +267,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
lock (DataBlocks) lock (DataBlocks)
{ {
m_blocksReusedStat.Consequent++; BlocksRequested++;
Stack<Object> s; Stack<Object> s;
@ -285,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (s.Count > 0) if (s.Count > 0)
{ {
m_blocksReusedStat.Antecedent++; BlocksReused++;
return (T)s.Pop(); return (T)s.Pop();
} }
} }

View File

@ -43,7 +43,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.ClientStack.LindenUDP.Tests namespace OpenSim.Region.ClientStack.LindenUDP.Tests
{ {
[TestFixture] [TestFixture]
public class LLImageManagerTests public class LLImageManagerTests : OpenSimTestCase
{ {
private AssetBase m_testImageAsset; private AssetBase m_testImageAsset;
private Scene scene; private Scene scene;

View File

@ -39,7 +39,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
/// Tests for the LL packet handler /// Tests for the LL packet handler
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class PacketHandlerTests public class PacketHandlerTests : OpenSimTestCase
{ {
// [Test] // [Test]
// /// <summary> // /// <summary>

View File

@ -47,7 +47,7 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
/// At the moment we're only test the in-memory part of the FlotsamAssetCache. This is a considerable weakness. /// At the moment we're only test the in-memory part of the FlotsamAssetCache. This is a considerable weakness.
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class FlotsamAssetCacheTests public class FlotsamAssetCacheTests : OpenSimTestCase
{ {
protected TestScene m_scene; protected TestScene m_scene;
protected FlotsamAssetCache m_cache; protected FlotsamAssetCache m_cache;

View File

@ -39,7 +39,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{ {
[TestFixture] [TestFixture]
public class AvatarFactoryModuleTests public class AvatarFactoryModuleTests : OpenSimTestCase
{ {
/// <summary> /// <summary>
/// Only partial right now since we don't yet test that it's ended up in the avatar appearance service. /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service.

View File

@ -40,7 +40,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
{ {
[TestFixture] [TestFixture]
public class FriendsModuleTests public class FriendsModuleTests : OpenSimTestCase
{ {
private FriendsModule m_fm; private FriendsModule m_fm;
private TestScene m_scene; private TestScene m_scene;

View File

@ -411,18 +411,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
// m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId);
item.CreatorIdAsUuid = ospResolvedId; // item.CreatorIdAsUuid = ospResolvedId;
// 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();
item.CreatorData = string.Empty; item.CreatorData = string.Empty;
} }
else if (item.CreatorData == null || item.CreatorData == String.Empty) else if (item.CreatorData == null || item.CreatorData == String.Empty)
{ {
item.CreatorId = m_userInfo.PrincipalID.ToString(); item.CreatorId = m_userInfo.PrincipalID.ToString();
item.CreatorIdAsUuid = new UUID(item.CreatorId); // item.CreatorIdAsUuid = new UUID(item.CreatorId);
} }
item.Owner = m_userInfo.PrincipalID; item.Owner = m_userInfo.PrincipalID;

View File

@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
item1.ID = UUID.Parse("00000000-0000-0000-0000-000000000020"); item1.ID = UUID.Parse("00000000-0000-0000-0000-000000000020");
item1.AssetID = asset1.FullID; item1.AssetID = asset1.FullID;
item1.GroupID = UUID.Random(); item1.GroupID = UUID.Random();
item1.CreatorIdAsUuid = m_uaLL1.PrincipalID; item1.CreatorId = m_uaLL1.PrincipalID.ToString();
item1.Owner = m_uaLL1.PrincipalID; item1.Owner = m_uaLL1.PrincipalID;
item1.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID; item1.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID;
scene.AddInventoryItem(item1); scene.AddInventoryItem(item1);
@ -157,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
coaItem.ID = UUID.Parse("00000000-0000-0000-0000-000000000180"); coaItem.ID = UUID.Parse("00000000-0000-0000-0000-000000000180");
coaItem.AssetID = coaAsset.FullID; coaItem.AssetID = coaAsset.FullID;
coaItem.GroupID = UUID.Random(); coaItem.GroupID = UUID.Random();
coaItem.CreatorIdAsUuid = m_uaLL1.PrincipalID; coaItem.CreatorId = m_uaLL1.PrincipalID.ToString();
coaItem.Owner = m_uaLL1.PrincipalID; coaItem.Owner = m_uaLL1.PrincipalID;
coaItem.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID; coaItem.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID;
scene.AddInventoryItem(coaItem); scene.AddInventoryItem(coaItem);

View File

@ -49,7 +49,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
{ {
[TestFixture] [TestFixture]
public class InventoryAccessModuleTests public class InventoryAccessModuleTests : OpenSimTestCase
{ {
protected TestScene m_scene; protected TestScene m_scene;
protected BasicInventoryAccessModule m_iam; protected BasicInventoryAccessModule m_iam;

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
{
public class BasePresenceServiceConnector : IPresenceService
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected bool m_Enabled;
protected PresenceDetector m_PresenceDetector;
/// <summary>
/// Underlying presence service. Do not use directly.
/// </summary>
public IPresenceService m_PresenceService;
public Type ReplaceableInterface
{
get { return null; }
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
// m_log.DebugFormat(
// "[LOCAL PRESENCE CONNECTOR]: Registering IPresenceService to scene {0}", scene.RegionInfo.RegionName);
scene.RegisterModuleInterface<IPresenceService>(this);
m_PresenceDetector.AddRegion(scene);
m_log.InfoFormat("[BASE PRESENCE SERVICE CONNECTOR]: Enabled for region {0}", scene.Name);
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_PresenceDetector.RemoveRegion(scene);
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
}
public void PostInitialise()
{
}
public void Close()
{
}
#region IPresenceService
public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
{
m_log.Warn("[BASE PRESENCE SERVICE CONNECTOR]: LoginAgent connector not implemented at the simulators");
return false;
}
public bool LogoutAgent(UUID sessionID)
{
return m_PresenceService.LogoutAgent(sessionID);
}
public bool LogoutRegionAgents(UUID regionID)
{
return m_PresenceService.LogoutRegionAgents(regionID);
}
public bool ReportAgent(UUID sessionID, UUID regionID)
{
return m_PresenceService.ReportAgent(sessionID, regionID);
}
public PresenceInfo GetAgent(UUID sessionID)
{
return m_PresenceService.GetAgent(sessionID);
}
public PresenceInfo[] GetAgents(string[] userIDs)
{
// Don't bother potentially making a useless network call if we not going to ask for any users anyway.
if (userIDs.Length == 0)
return new PresenceInfo[0];
return m_PresenceService.GetAgents(userIDs);
}
#endregion
}
}

View File

@ -24,53 +24,29 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Server.Base; using OpenSim.Server.Base;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
using OpenMetaverse;
using log4net;
using Mono.Addins;
using Nini.Config;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalPresenceServicesConnector")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalPresenceServicesConnector")]
public class LocalPresenceServicesConnector : ISharedRegionModule, IPresenceService public class LocalPresenceServicesConnector : BasePresenceServiceConnector, ISharedRegionModule, IPresenceService
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false;
private PresenceDetector m_PresenceDetector;
/// <summary>
/// Underlying presence service. Do not use directly.
/// </summary>
public IPresenceService m_PresenceService;
public LocalPresenceServicesConnector()
{
}
public LocalPresenceServicesConnector(IConfigSource source)
{
Initialise(source);
}
#region ISharedRegionModule #region ISharedRegionModule
public Type ReplaceableInterface
{
get { return null; }
}
public string Name public string Name
{ {
get { return "LocalPresenceServicesConnector"; } get { return "LocalPresenceServicesConnector"; }
@ -121,44 +97,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
} }
} }
public void PostInitialise()
{
}
public void Close()
{
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
// m_log.DebugFormat(
// "[LOCAL PRESENCE CONNECTOR]: Registering IPresenceService to scene {0}", scene.RegionInfo.RegionName);
scene.RegisterModuleInterface<IPresenceService>(this);
m_PresenceDetector.AddRegion(scene);
m_log.InfoFormat("[LOCAL PRESENCE CONNECTOR]: Enabled local presence for region {0}", scene.RegionInfo.RegionName);
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_PresenceDetector.RemoveRegion(scene);
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
}
#endregion #endregion
#region IPresenceService #region IPresenceService
@ -195,11 +133,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
return m_PresenceService.GetAgents(userIDs); return m_PresenceService.GetAgents(userIDs);
} }
public PresenceInfo VerifyAgent(UUID s_sessionID)
{
return m_PresenceService.VerifyAgent(s_sessionID);
}
#endregion #endregion
} }

View File

@ -43,22 +43,12 @@ using Nini.Config;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemotePresenceServicesConnector")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemotePresenceServicesConnector")]
public class RemotePresenceServicesConnector : ISharedRegionModule, IPresenceService public class RemotePresenceServicesConnector : BasePresenceServiceConnector, ISharedRegionModule
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region ISharedRegionModule #region ISharedRegionModule
private bool m_Enabled = false;
private PresenceDetector m_PresenceDetector;
private IPresenceService m_RemoteConnector;
public Type ReplaceableInterface
{
get { return null; }
}
public string Name public string Name
{ {
get { return "RemotePresenceServicesConnector"; } get { return "RemotePresenceServicesConnector"; }
@ -72,7 +62,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
string name = moduleConfig.GetString("PresenceServices", ""); string name = moduleConfig.GetString("PresenceServices", "");
if (name == Name) if (name == Name)
{ {
m_RemoteConnector = new PresenceServicesConnector(source); m_PresenceService = new PresenceServicesConnector(source);
m_Enabled = true; m_Enabled = true;
@ -81,86 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
m_log.Info("[REMOTE PRESENCE CONNECTOR]: Remote presence enabled"); m_log.Info("[REMOTE PRESENCE CONNECTOR]: Remote presence enabled");
} }
} }
}
public void PostInitialise()
{
}
public void Close()
{
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
scene.RegisterModuleInterface<IPresenceService>(this);
m_PresenceDetector.AddRegion(scene);
m_log.InfoFormat("[REMOTE PRESENCE CONNECTOR]: Enabled remote presence for region {0}", scene.RegionInfo.RegionName);
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_PresenceDetector.RemoveRegion(scene);
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
} }
#endregion #endregion
#region IPresenceService
public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
{
m_log.Warn("[REMOTE PRESENCE CONNECTOR]: LoginAgent connector not implemented at the simulators");
return false;
}
public bool LogoutAgent(UUID sessionID)
{
return m_RemoteConnector.LogoutAgent(sessionID);
}
public bool LogoutRegionAgents(UUID regionID)
{
return m_RemoteConnector.LogoutRegionAgents(regionID);
}
public bool ReportAgent(UUID sessionID, UUID regionID)
{
return m_RemoteConnector.ReportAgent(sessionID, regionID);
}
public PresenceInfo GetAgent(UUID sessionID)
{
return m_RemoteConnector.GetAgent(sessionID);
}
public PresenceInfo[] GetAgents(string[] userIDs)
{
return m_RemoteConnector.GetAgents(userIDs);
}
public PresenceInfo VerifyAgent(UUID sessionID)
{
return m_RemoteConnector.VerifyAgent(sessionID);
}
#endregion
} }
} }

View File

@ -35,7 +35,6 @@ using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using Nini.Config; using Nini.Config;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
@ -44,7 +43,7 @@ using OpenSim.Tests.Common;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests
{ {
[TestFixture] [TestFixture]
public class PresenceConnectorsTests public class PresenceConnectorsTests : OpenSimTestCase
{ {
LocalPresenceServicesConnector m_LocalConnector; LocalPresenceServicesConnector m_LocalConnector;
private void SetUp() private void SetUp()
@ -56,7 +55,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests
config.Configs["PresenceService"].Set("LocalServiceModule", "OpenSim.Services.PresenceService.dll:PresenceService"); config.Configs["PresenceService"].Set("LocalServiceModule", "OpenSim.Services.PresenceService.dll:PresenceService");
config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
m_LocalConnector = new LocalPresenceServicesConnector(config); m_LocalConnector = new LocalPresenceServicesConnector();
m_LocalConnector.Initialise(config);
// Let's stick in a test presence // Let's stick in a test presence
m_LocalConnector.m_PresenceService.LoginAgent(UUID.Zero.ToString(), UUID.Zero, UUID.Zero); m_LocalConnector.m_PresenceService.LoginAgent(UUID.Zero.ToString(), UUID.Zero, UUID.Zero);

View File

@ -552,13 +552,22 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Validate User and Group UUID's // Validate User and Group UUID's
if (!ResolveUserUuid(scene, parcel.OwnerID)) if (parcel.IsGroupOwned)
parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
if (!ResolveGroupUuid(parcel.GroupID))
{ {
parcel.GroupID = UUID.Zero; if (!ResolveGroupUuid(parcel.GroupID))
parcel.IsGroupOwned = false; {
parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
parcel.GroupID = UUID.Zero;
parcel.IsGroupOwned = false;
}
}
else
{
if (!ResolveUserUuid(scene, parcel.OwnerID))
parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
if (!ResolveGroupUuid(parcel.GroupID))
parcel.GroupID = UUID.Zero;
} }
List<LandAccessEntry> accessList = new List<LandAccessEntry>(); List<LandAccessEntry> accessList = new List<LandAccessEntry>();
@ -571,8 +580,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
parcel.ParcelAccessList = accessList; parcel.ParcelAccessList = accessList;
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}", // "[ARCHIVER]: Adding parcel {0}, local id {1}, owner {2}, group {3}, isGroupOwned {4}, area {5}",
// parcel.Name, parcel.LocalID, parcel.Area); // parcel.Name, parcel.LocalID, parcel.OwnerID, parcel.GroupID, parcel.IsGroupOwned, parcel.Area);
landData.Add(parcel); landData.Add(parcel);
} }

View File

@ -167,7 +167,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
} }
scenesGroup.CalcSceneLocations(); scenesGroup.CalcSceneLocations();
m_archiveWriter = new TarArchiveWriter(m_saveStream); m_archiveWriter = new TarArchiveWriter(m_saveStream);
try try
@ -216,7 +215,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
} }
} }
private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids) private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids)
{ {
m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName);
@ -540,7 +538,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
} }
protected void Save(Scene scene, List<SceneObjectGroup> sceneObjects, string regionDir) protected void Save(Scene scene, List<SceneObjectGroup> sceneObjects, string regionDir)
{ {
if (regionDir != string.Empty) if (regionDir != string.Empty)
@ -560,8 +557,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
foreach (ILandObject lo in landObjects) foreach (ILandObject lo in landObjects)
{ {
LandData landData = lo.LandData; LandData landData = lo.LandData;
string landDataPath = String.Format("{0}{1}{2}.xml", string landDataPath
regionDir, ArchiveConstants.LANDDATA_PATH, landData.GlobalID.ToString()); = String.Format("{0}{1}", regionDir, ArchiveConstants.CreateOarLandDataPath(landData));
m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options)); m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
} }
@ -605,7 +602,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
CloseArchive(String.Empty); CloseArchive(String.Empty);
} }
/// <summary> /// <summary>
/// Closes the archive and notifies that we're done. /// Closes the archive and notifies that we're done.
/// </summary> /// </summary>
@ -629,6 +625,5 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage); m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage);
} }
} }
} }

View File

@ -31,16 +31,19 @@ using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using log4net.Config; using log4net.Config;
using Nini.Config;
using NUnit.Framework; using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Assets; using OpenMetaverse.Assets;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization;
using OpenSim.Framework.Serialization.External; using OpenSim.Framework.Serialization.External;
using OpenSim.Region.CoreModules.World.Land;
using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.CoreModules.World.Terrain; using OpenSim.Region.CoreModules.World.Terrain;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants;
@ -69,9 +72,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
{ {
base.SetUp(); base.SetUp();
// FIXME: Do something about this - relying on statics in unit tests causes trouble sooner or later
new SceneManager();
m_archiverModule = new ArchiverModule(); m_archiverModule = new ArchiverModule();
m_serialiserModule = new SerialiserModule(); m_serialiserModule = new SerialiserModule();
TerrainModule terrainModule = new TerrainModule(); TerrainModule terrainModule = new TerrainModule();
@ -128,6 +128,53 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName }; return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
} }
private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid)
{
SceneObjectPart part1 = CreateSceneObjectPart1();
sog1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(sog1, false);
AssetNotecard nc = new AssetNotecard();
nc.BodyText = "Hello World!";
nc.Encode();
ncAssetUuid = UUID.Random();
UUID ncItemUuid = UUID.Random();
AssetBase ncAsset
= AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
m_scene.AssetService.Store(ncAsset);
TaskInventoryItem ncItem
= new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
SceneObjectPart part2 = CreateSceneObjectPart2();
sog2 = new SceneObjectGroup(part2);
part2.Inventory.AddInventoryItem(ncItem, true);
scene.AddNewSceneObject(sog2, false);
}
private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid)
{
using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName))
{
using (BinaryReader br = new BinaryReader(resource))
{
// FIXME: Use the inspector instead
soundData = br.ReadBytes(99999999);
soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
string soundAssetFileName
= ArchiveConstants.ASSETS_PATH + soundUuid
+ ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
tar.WriteFile(soundAssetFileName, soundData);
/*
AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
scene.AssetService.Store(soundAsset);
asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
*/
}
}
}
/// <summary> /// <summary>
/// Test saving an OpenSim Region Archive. /// Test saving an OpenSim Region Archive.
/// </summary> /// </summary>
@ -204,30 +251,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// TODO: Test presence of more files and contents of files. // TODO: Test presence of more files and contents of files.
} }
private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid)
{
SceneObjectPart part1 = CreateSceneObjectPart1();
sog1 = new SceneObjectGroup(part1);
scene.AddNewSceneObject(sog1, false);
AssetNotecard nc = new AssetNotecard();
nc.BodyText = "Hello World!";
nc.Encode();
ncAssetUuid = UUID.Random();
UUID ncItemUuid = UUID.Random();
AssetBase ncAsset
= AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
m_scene.AssetService.Store(ncAsset);
TaskInventoryItem ncItem
= new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
SceneObjectPart part2 = CreateSceneObjectPart2();
sog2 = new SceneObjectGroup(part2);
part2.Inventory.AddInventoryItem(ncItem, true);
scene.AddNewSceneObject(sog2, false);
}
/// <summary> /// <summary>
/// Test saving an OpenSim Region Archive with the no assets option /// Test saving an OpenSim Region Archive with the no assets option
/// </summary> /// </summary>
@ -308,59 +331,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// TODO: Test presence of more files and contents of files. // TODO: Test presence of more files and contents of files.
} }
/// <summary>
/// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g.
/// 2 can come after 3).
/// </summary>
[Test]
public void TestLoadOarUnorderedParts()
{
TestHelpers.InMethod();
UUID ownerId = TestHelpers.ParseTail(0xaaaa);
MemoryStream archiveWriteStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
tar.WriteFile(
ArchiveConstants.CONTROL_FILE_PATH,
new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
SceneObjectPart sop2
= SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId);
SceneObjectPart sop3
= SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId);
// Add the parts so they will be written out in reverse order to the oar
sog1.AddPart(sop3);
sop3.LinkNum = 3;
sog1.AddPart(sop2);
sop2.LinkNum = 2;
tar.WriteFile(
ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition),
SceneObjectSerializer.ToXml2Format(sog1));
tar.Close();
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
lock (this)
{
m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
m_archiverModule.DearchiveRegion(archiveReadStream);
}
Assert.That(m_lastErrorMessage, Is.Null);
SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2");
Assert.That(part2.LinkNum, Is.EqualTo(2));
SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3");
Assert.That(part3.LinkNum, Is.EqualTo(3));
}
/// <summary> /// <summary>
/// Test loading an OpenSim Region Archive. /// Test loading an OpenSim Region Archive.
/// </summary> /// </summary>
@ -435,50 +405,57 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
TestLoadedRegion(part1, soundItemName, soundData); TestLoadedRegion(part1, soundItemName, soundData);
} }
private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid) /// <summary>
/// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g.
/// 2 can come after 3).
/// </summary>
[Test]
public void TestLoadOarUnorderedParts()
{ {
using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) TestHelpers.InMethod();
UUID ownerId = TestHelpers.ParseTail(0xaaaa);
MemoryStream archiveWriteStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
tar.WriteFile(
ArchiveConstants.CONTROL_FILE_PATH,
new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
SceneObjectPart sop2
= SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId);
SceneObjectPart sop3
= SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId);
// Add the parts so they will be written out in reverse order to the oar
sog1.AddPart(sop3);
sop3.LinkNum = 3;
sog1.AddPart(sop2);
sop2.LinkNum = 2;
tar.WriteFile(
ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition),
SceneObjectSerializer.ToXml2Format(sog1));
tar.Close();
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
lock (this)
{ {
using (BinaryReader br = new BinaryReader(resource)) m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
{ m_archiverModule.DearchiveRegion(archiveReadStream);
// FIXME: Use the inspector instead
soundData = br.ReadBytes(99999999);
soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
string soundAssetFileName
= ArchiveConstants.ASSETS_PATH + soundUuid
+ ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
tar.WriteFile(soundAssetFileName, soundData);
/*
AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
scene.AssetService.Store(soundAsset);
asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
*/
}
} }
}
private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData) Assert.That(m_lastErrorMessage, Is.Null);
{
SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2");
Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical"); Assert.That(part2.LinkNum, Is.EqualTo(2));
Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
Assert.That(
object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
Assert.That(
object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition));
TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3");
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); Assert.That(part3.LinkNum, Is.EqualTo(3));
AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels");
} }
/// <summary> /// <summary>
@ -538,8 +515,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
SerialiserModule serialiserModule = new SerialiserModule(); SerialiserModule serialiserModule = new SerialiserModule();
TerrainModule terrainModule = new TerrainModule(); TerrainModule terrainModule = new TerrainModule();
m_sceneHelpers = new SceneHelpers(); SceneHelpers m_sceneHelpers2 = new SceneHelpers();
TestScene scene2 = m_sceneHelpers.SetupScene(); TestScene scene2 = m_sceneHelpers2.SetupScene();
SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule);
// Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is
@ -562,6 +539,71 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
} }
} }
/// <summary>
/// Test OAR loading where the land parcel is group deeded.
/// </summary>
/// <remarks>
/// In this situation, the owner ID is set to the group ID.
/// </remarks>
[Test]
public void TestLoadOarDeededLand()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
UUID landID = TestHelpers.ParseTail(0x10);
MockGroupsServicesConnector groupsService = new MockGroupsServicesConnector();
IConfigSource configSource = new IniConfigSource();
IConfig config = configSource.AddConfig("Groups");
config.Set("Enabled", true);
config.Set("Module", "GroupsModule");
config.Set("DebugEnabled", true);
SceneHelpers.SetupSceneModules(
m_scene, configSource, new object[] { new GroupsModule(), groupsService, new LandManagementModule() });
// Create group in scene for loading
// FIXME: For now we'll put up with the issue that we'll get a group ID that varies across tests.
UUID groupID
= groupsService.CreateGroup(UUID.Zero, "group1", "", true, UUID.Zero, 3, true, true, true, UUID.Zero);
// Construct OAR
MemoryStream oarStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(oarStream);
tar.WriteDir(ArchiveConstants.LANDDATA_PATH);
tar.WriteFile(
ArchiveConstants.CONTROL_FILE_PATH,
new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
LandObject lo = new LandObject(groupID, true, null);
lo.SetLandBitmap(lo.BasicFullRegionLandBitmap());
LandData ld = lo.LandData;
ld.GlobalID = landID;
string ldPath = ArchiveConstants.CreateOarLandDataPath(ld);
tar.WriteFile(ldPath, LandDataSerializer.Serialize(ld, null));
tar.Close();
oarStream = new MemoryStream(oarStream.ToArray());
// Load OAR
lock (this)
{
m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
m_archiverModule.DearchiveRegion(oarStream);
}
ILandObject rLo = m_scene.LandChannel.GetLandObject(16, 16);
LandData rLd = rLo.LandData;
Assert.That(rLd.GlobalID, Is.EqualTo(landID));
Assert.That(rLd.OwnerID, Is.EqualTo(groupID));
Assert.That(rLd.GroupID, Is.EqualTo(groupID));
Assert.That(rLd.IsGroupOwned, Is.EqualTo(true));
}
/// <summary> /// <summary>
/// Test loading the region settings of an OpenSim Region Archive. /// Test loading the region settings of an OpenSim Region Archive.
/// </summary> /// </summary>
@ -781,9 +823,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
} }
} }
// Save OAR // Save OAR
MemoryStream archiveWriteStream = new MemoryStream(); MemoryStream archiveWriteStream = new MemoryStream();
m_scene.EventManager.OnOarFileSaved += SaveCompleted; m_scene.EventManager.OnOarFileSaved += SaveCompleted;
@ -800,7 +840,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// Check that the OAR contains the expected data // Check that the OAR contains the expected data
Assert.That(m_lastRequestId, Is.EqualTo(requestId)); Assert.That(m_lastRequestId, Is.EqualTo(requestId));
byte[] archive = archiveWriteStream.ToArray(); byte[] archive = archiveWriteStream.ToArray();
@ -892,7 +931,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
} }
ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup(); ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();
SceneManager.Instance.ForEachScene(delegate(Scene scene) m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene)
{ {
scenesGroup.AddScene(scene); scenesGroup.AddScene(scene);
}); });
@ -950,13 +989,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// Delete the current objects, to test that they're loaded from the OAR and didn't // Delete the current objects, to test that they're loaded from the OAR and didn't
// just remain in the scene. // just remain in the scene.
SceneManager.Instance.ForEachScene(delegate(Scene scene) m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene)
{ {
scene.DeleteAllSceneObjects(); scene.DeleteAllSceneObjects();
}); });
// Create a "hole", to test that that the corresponding region isn't loaded from the OAR // Create a "hole", to test that that the corresponding region isn't loaded from the OAR
SceneManager.Instance.CloseScene(SceneManager.Instance.Scenes[1]); m_sceneHelpers.SceneManager.CloseScene(SceneManager.Instance.Scenes[1]);
// Check thay the OAR file contains the expected data // Check thay the OAR file contains the expected data
@ -971,10 +1010,32 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
Assert.That(m_lastErrorMessage, Is.Null); Assert.That(m_lastErrorMessage, Is.Null);
Assert.AreEqual(3, SceneManager.Instance.Scenes.Count); Assert.AreEqual(3, m_sceneHelpers.SceneManager.Scenes.Count);
TestLoadedRegion(part1, soundItemName, soundData); TestLoadedRegion(part1, soundItemName, soundData);
} }
private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData)
{
SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical");
Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
Assert.That(
object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
Assert.That(
object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition));
TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels");
}
} }
} }

View File

@ -53,6 +53,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
protected EstateManagementCommands m_commands; protected EstateManagementCommands m_commands;
/// <summary>
/// If false, region restart requests from the client are blocked even if they are otherwise legitimate.
/// </summary>
public bool AllowRegionRestartFromClient { get; set; }
private EstateTerrainXferHandler TerrainUploader; private EstateTerrainXferHandler TerrainUploader;
public TelehubManager m_Telehub; public TelehubManager m_Telehub;
@ -60,6 +65,53 @@ namespace OpenSim.Region.CoreModules.World.Estate
public event ChangeDelegate OnEstateInfoChange; public event ChangeDelegate OnEstateInfoChange;
public event MessageDelegate OnEstateMessage; public event MessageDelegate OnEstateMessage;
#region Region Module interface
public string Name { get { return "EstateManagementModule"; } }
public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source)
{
AllowRegionRestartFromClient = true;
IConfig config = source.Configs["EstateManagement"];
if (config != null)
AllowRegionRestartFromClient = config.GetBoolean("AllowRegionRestartFromClient", true);
}
public void AddRegion(Scene scene)
{
Scene = scene;
Scene.RegisterModuleInterface<IEstateModule>(this);
Scene.EventManager.OnNewClient += EventManager_OnNewClient;
Scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight;
m_Telehub = new TelehubManager(scene);
m_commands = new EstateManagementCommands(this);
m_commands.Initialise();
}
public void RemoveRegion(Scene scene) {}
public void RegionLoaded(Scene scene)
{
// Sets up the sun module based no the saved Estate and Region Settings
// DO NOT REMOVE or the sun will stop working
scene.TriggerEstateSunUpdate();
UserManager = scene.RequestModuleInterface<IUserManagement>();
}
public void Close()
{
m_commands.Close();
}
#endregion
#region Packet Data Responders #region Packet Data Responders
private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice) private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice)
@ -184,6 +236,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
Scene.RegionInfo.RegionSettings.TerrainTexture4 = texture; Scene.RegionInfo.RegionSettings.TerrainTexture4 = texture;
break; break;
} }
Scene.RegionInfo.RegionSettings.Save(); Scene.RegionInfo.RegionSettings.Save();
TriggerRegionInfoChange(); TriggerRegionInfoChange();
sendRegionInfoPacketToAll(); sendRegionInfoPacketToAll();
@ -215,6 +268,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
Scene.RegionInfo.RegionSettings.Elevation2NE = highValue; Scene.RegionInfo.RegionSettings.Elevation2NE = highValue;
break; break;
} }
Scene.RegionInfo.RegionSettings.Save(); Scene.RegionInfo.RegionSettings.Save();
TriggerRegionInfoChange(); TriggerRegionInfoChange();
sendRegionHandshakeToAll(); sendRegionHandshakeToAll();
@ -255,6 +309,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds) private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds)
{ {
if (!AllowRegionRestartFromClient)
{
remoteClient.SendAlertMessage("Region restart has been disabled on this simulator.");
return;
}
IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>();
if (restartModule != null) if (restartModule != null)
{ {
@ -271,6 +331,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
} }
restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true); restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
m_log.InfoFormat(
"User {0} requested restart of region {1} in {2} seconds",
remoteClient.Name, Scene.Name, times.Count != 0 ? times[0] : 0);
} }
} }
@ -295,7 +359,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
if ((estateAccessType & 4) != 0) // User add if ((estateAccessType & 4) != 0) // User add
{ {
if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
{ {
if ((estateAccessType & 1) != 0) // All estates if ((estateAccessType & 1) != 0) // All estates
{ {
@ -325,9 +389,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
} }
} }
if ((estateAccessType & 8) != 0) // User remove if ((estateAccessType & 8) != 0) // User remove
{ {
if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
{ {
if ((estateAccessType & 1) != 0) // All estates if ((estateAccessType & 1) != 0) // All estates
{ {
@ -356,9 +421,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
} }
} }
if ((estateAccessType & 16) != 0) // Group add if ((estateAccessType & 16) != 0) // Group add
{ {
if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
{ {
if ((estateAccessType & 1) != 0) // All estates if ((estateAccessType & 1) != 0) // All estates
{ {
@ -387,9 +453,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
} }
} }
if ((estateAccessType & 32) != 0) // Group remove if ((estateAccessType & 32) != 0) // Group remove
{ {
if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
{ {
if ((estateAccessType & 1) != 0) // All estates if ((estateAccessType & 1) != 0) // All estates
{ {
@ -418,9 +485,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
} }
} }
if ((estateAccessType & 64) != 0) // Ban add if ((estateAccessType & 64) != 0) // Ban add
{ {
if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || Scene.Permissions.BypassPermissions()) if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false))
{ {
EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans; EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans;
@ -495,9 +563,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
} }
} }
if ((estateAccessType & 128) != 0) // Ban remove if ((estateAccessType & 128) != 0) // Ban remove
{ {
if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || Scene.Permissions.BypassPermissions()) if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false))
{ {
EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans; EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans;
@ -550,9 +619,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
} }
} }
if ((estateAccessType & 256) != 0) // Manager add if ((estateAccessType & 256) != 0) // Manager add
{ {
if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
{ {
if ((estateAccessType & 1) != 0) // All estates if ((estateAccessType & 1) != 0) // All estates
{ {
@ -581,9 +651,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
} }
} }
if ((estateAccessType & 512) != 0) // Manager remove if ((estateAccessType & 512) != 0) // Manager remove
{ {
if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
{ {
if ((estateAccessType & 1) != 0) // All estates if ((estateAccessType & 1) != 0) // All estates
{ {
@ -614,7 +685,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
} }
} }
public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) public void handleOnEstateManageTelehub(IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1)
{ {
SceneObjectPart part; SceneObjectPart part;
@ -1072,45 +1143,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
#endregion #endregion
#region Region Module interface
public string Name { get { return "EstateManagementModule"; } }
public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source) {}
public void AddRegion(Scene scene)
{
Scene = scene;
Scene.RegisterModuleInterface<IEstateModule>(this);
Scene.EventManager.OnNewClient += EventManager_OnNewClient;
Scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight;
m_Telehub = new TelehubManager(scene);
m_commands = new EstateManagementCommands(this);
m_commands.Initialise();
}
public void RemoveRegion(Scene scene) {}
public void RegionLoaded(Scene scene)
{
// Sets up the sun module based no the saved Estate and Region Settings
// DO NOT REMOVE or the sun will stop working
scene.TriggerEstateSunUpdate();
UserManager = scene.RequestModuleInterface<IUserManagement>();
}
public void Close()
{
m_commands.Close();
}
#endregion
#region Other Functions #region Other Functions
public void changeWaterHeight(float height) public void changeWaterHeight(float height)

View File

@ -1390,10 +1390,11 @@ namespace OpenSim.Region.CoreModules.World.Land
public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
{ {
// m_log.DebugFormat(
// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name);
for (int i = 0; i < data.Count; i++) for (int i = 0; i < data.Count; i++)
{
IncomingLandObjectFromStorage(data[i]); IncomingLandObjectFromStorage(data[i]);
}
} }
public void IncomingLandObjectFromStorage(LandData data) public void IncomingLandObjectFromStorage(LandData data)

View File

@ -727,9 +727,10 @@ namespace OpenSim.Region.CoreModules.World.Land
int ty = min_y * 4; int ty = min_y * 4;
if (ty > ((int)Constants.RegionSize - 1)) if (ty > ((int)Constants.RegionSize - 1))
ty = ((int)Constants.RegionSize - 1); ty = ((int)Constants.RegionSize - 1);
LandData.AABBMin = LandData.AABBMin =
new Vector3((float) (min_x * 4), (float) (min_y * 4), new Vector3(
(float) m_scene.Heightmap[tx, ty]); (float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
tx = max_x * 4; tx = max_x * 4;
if (tx > ((int)Constants.RegionSize - 1)) if (tx > ((int)Constants.RegionSize - 1))
@ -737,9 +738,11 @@ namespace OpenSim.Region.CoreModules.World.Land
ty = max_y * 4; ty = max_y * 4;
if (ty > ((int)Constants.RegionSize - 1)) if (ty > ((int)Constants.RegionSize - 1))
ty = ((int)Constants.RegionSize - 1); ty = ((int)Constants.RegionSize - 1);
LandData.AABBMax =
new Vector3((float) (max_x * 4), (float) (max_y * 4), LandData.AABBMax
(float) m_scene.Heightmap[tx, ty]); = new Vector3(
(float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
LandData.Area = tempArea; LandData.Area = tempArea;
} }

View File

@ -41,7 +41,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.World.Land.Tests namespace OpenSim.Region.CoreModules.World.Land.Tests
{ {
[TestFixture] [TestFixture]
public class PrimCountModuleTests public class PrimCountModuleTests : OpenSimTestCase
{ {
protected UUID m_userId = new UUID("00000000-0000-0000-0000-100000000000"); protected UUID m_userId = new UUID("00000000-0000-0000-0000-100000000000");
protected UUID m_groupId = new UUID("00000000-0000-0000-8888-000000000000"); protected UUID m_groupId = new UUID("00000000-0000-0000-8888-000000000000");

View File

@ -44,7 +44,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
{ {
[TestFixture] [TestFixture]
public class MoapTests public class MoapTests : OpenSimTestCase
{ {
protected TestScene m_scene; protected TestScene m_scene;
protected MoapModule m_module; protected MoapModule m_module;

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Timers; using System.Timers;
using System.Threading; using System.Threading;
@ -264,6 +265,9 @@ namespace OpenSim.Region.CoreModules.World.Region
for (int i = 4 ; i < args.Length ; i++) for (int i = 4 ; i < args.Length ; i++)
times.Add(Convert.ToInt32(args[i])); times.Add(Convert.ToInt32(args[i]));
MainConsole.Instance.OutputFormat(
"Region {0} scheduled for restart in {1} seconds", m_Scene.Name, times.Sum());
ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice); ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
} }
} }

View File

@ -39,7 +39,7 @@ using OpenSim.Tests.Common;
namespace OpenSim.Region.CoreModules.World.Serialiser.Tests namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
{ {
[TestFixture] [TestFixture]
public class SerialiserTests public class SerialiserTests : OpenSimTestCase
{ {
private string xml = @" private string xml = @"
<SceneObjectGroup> <SceneObjectGroup>

View File

@ -43,8 +43,8 @@ namespace OpenSim.Region.CoreModules.World.Sound
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SoundModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SoundModule")]
public class SoundModule : INonSharedRegionModule, ISoundModule public class SoundModule : INonSharedRegionModule, ISoundModule
{ {
private static readonly ILog m_log = LogManager.GetLogger( // private static readonly ILog m_log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); // MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene; private Scene m_scene;

View File

@ -30,11 +30,12 @@ using NUnit.Framework;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes; using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
namespace OpenSim.Region.CoreModules.World.Terrain.Tests namespace OpenSim.Region.CoreModules.World.Terrain.Tests
{ {
[TestFixture] [TestFixture]
public class TerrainTest public class TerrainTest : OpenSimTestCase
{ {
[Test] [Test]
public void BrushTest() public void BrushTest()

View File

@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
m_windConfig = config.Configs["Wind"]; m_windConfig = config.Configs["Wind"];
string desiredWindPlugin = m_dWindPluginName; // string desiredWindPlugin = m_dWindPluginName;
if (m_windConfig != null) if (m_windConfig != null)
{ {

View File

@ -115,19 +115,15 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
m_Clients.Add(remoteClient.AgentId); m_Clients.Add(remoteClient.AgentId);
} }
Util.FireAndForget(delegate try
{ {
try OnMapNameRequest(remoteClient, mapName, flags);
{ }
OnMapNameRequest(remoteClient, mapName, flags); finally
} {
finally lock (m_Clients)
{ m_Clients.Remove(remoteClient.AgentId);
lock (m_Clients) }
m_Clients.Remove(remoteClient.AgentId);
}
});
} }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)

View File

@ -740,7 +740,12 @@ namespace OpenSim.Region.Framework.Scenes
// //
// Out of memory // Out of memory
// Operating system has killed the plugin // Operating system has killed the plugin
m_sceneGraph.UnRecoverableError += RestartNow; m_sceneGraph.UnRecoverableError
+= () =>
{
m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name);
RestartNow();
};
RegisterDefaultSceneEvents(); RegisterDefaultSceneEvents();
@ -1134,16 +1139,10 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
m_log.Error("[REGION]: Closing"); m_log.InfoFormat("[REGION]: Restarting region {0}", Name);
Close(); Close();
if (PhysicsScene != null)
{
PhysicsScene.Dispose();
}
m_log.Error("[REGION]: Firing Region Restart Message");
base.Restart(); base.Restart();
} }

View File

@ -100,23 +100,25 @@ namespace OpenSim.Region.Framework.Scenes
} }
private readonly List<Scene> m_localScenes = new List<Scene>(); private readonly List<Scene> m_localScenes = new List<Scene>();
private Scene m_currentScene = null;
public List<Scene> Scenes public List<Scene> Scenes
{ {
get { return new List<Scene>(m_localScenes); } get { return new List<Scene>(m_localScenes); }
} }
public Scene CurrentScene /// <summary>
{ /// Scene selected from the console.
get { return m_currentScene; } /// </summary>
} /// <value>
/// If null, then all scenes are considered selected (signalled as "Root" on the console).
/// </value>
public Scene CurrentScene { get; private set; }
public Scene CurrentOrFirstScene public Scene CurrentOrFirstScene
{ {
get get
{ {
if (m_currentScene == null) if (CurrentScene == null)
{ {
lock (m_localScenes) lock (m_localScenes)
{ {
@ -128,7 +130,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
return m_currentScene; return CurrentScene;
} }
} }
} }
@ -141,6 +143,13 @@ namespace OpenSim.Region.Framework.Scenes
public void Close() public void Close()
{ {
lock (m_localScenes)
{
for (int i = 0; i < m_localScenes.Count; i++)
{
m_localScenes[i].Close();
}
}
} }
public void Close(Scene cscene) public void Close(Scene cscene)
@ -171,8 +180,7 @@ namespace OpenSim.Region.Framework.Scenes
public void HandleRestart(RegionInfo rdata) public void HandleRestart(RegionInfo rdata)
{ {
m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); Scene restartedScene = null;
int RegionSceneElement = -1;
lock (m_localScenes) lock (m_localScenes)
{ {
@ -180,19 +188,18 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName)
{ {
RegionSceneElement = i; restartedScene = m_localScenes[i];
m_localScenes.RemoveAt(i);
break;
} }
} }
// Now we make sure the region is no longer known about by the SceneManager
// Prevents duplicates.
if (RegionSceneElement >= 0)
{
m_localScenes.RemoveAt(RegionSceneElement);
}
} }
// If the currently selected scene has been restarted, then we can't reselect here since we the scene
// hasn't yet been recreated. We will have to leave this to the caller.
if (CurrentScene == restartedScene)
CurrentScene = null;
// Send signal to main that we're restarting this sim. // Send signal to main that we're restarting this sim.
OnRestartSim(rdata); OnRestartSim(rdata);
} }
@ -334,14 +341,14 @@ namespace OpenSim.Region.Framework.Scenes
private void ForEachCurrentScene(Action<Scene> func) private void ForEachCurrentScene(Action<Scene> func)
{ {
if (m_currentScene == null) if (CurrentScene == null)
{ {
lock (m_localScenes) lock (m_localScenes)
m_localScenes.ForEach(func); m_localScenes.ForEach(func);
} }
else else
{ {
func(m_currentScene); func(CurrentScene);
} }
} }
@ -361,7 +368,7 @@ namespace OpenSim.Region.Framework.Scenes
|| (String.Compare(regionName, "..") == 0) || (String.Compare(regionName, "..") == 0)
|| (String.Compare(regionName, "/") == 0)) || (String.Compare(regionName, "/") == 0))
{ {
m_currentScene = null; CurrentScene = null;
return true; return true;
} }
else else
@ -372,7 +379,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0)
{ {
m_currentScene = scene; CurrentScene = scene;
return true; return true;
} }
} }
@ -392,7 +399,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (scene.RegionInfo.RegionID == regionID) if (scene.RegionInfo.RegionID == regionID)
{ {
m_currentScene = scene; CurrentScene = scene;
return true; return true;
} }
} }

View File

@ -1698,8 +1698,16 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", // "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
// Name, pos, m_scene.RegionInfo.RegionName); // Name, pos, m_scene.RegionInfo.RegionName);
if (pos.X < 0 || pos.X >= Constants.RegionSize // Allow move to another sub-region within a megaregion
|| pos.Y < 0 || pos.Y >= Constants.RegionSize Vector2 regionSize;
IRegionCombinerModule regionCombinerModule = m_scene.RequestModuleInterface<IRegionCombinerModule>();
if (regionCombinerModule != null)
regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
else
regionSize = new Vector2(Constants.RegionSize);
if (pos.X < 0 || pos.X >= regionSize.X
|| pos.Y < 0 || pos.Y >= regionSize.Y
|| pos.Z < 0) || pos.Z < 0)
return; return;
@ -1713,7 +1721,16 @@ namespace OpenSim.Region.Framework.Scenes
// pos.Z = AbsolutePosition.Z; // pos.Z = AbsolutePosition.Z;
// } // }
float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; // Get terrain height for sub-region in a megaregion if necessary
int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X);
int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y);
UUID target_regionID = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y).RegionID;
Scene targetScene = m_scene;
if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene))
targetScene = m_scene;
float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)];
pos.Z = Math.Max(terrainHeight, pos.Z); pos.Z = Math.Max(terrainHeight, pos.Z);
// Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is

View File

@ -37,7 +37,7 @@ using OpenSim.Tests.Common;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
[TestFixture] [TestFixture]
public class BorderTests public class BorderTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestCross() public void TestCross()

View File

@ -41,7 +41,7 @@ using OpenSim.Tests.Common;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
[TestFixture, LongRunning] [TestFixture, LongRunning]
public class EntityManagerTests public class EntityManagerTests : OpenSimTestCase
{ {
static public Random random; static public Random random;
SceneObjectGroup found; SceneObjectGroup found;

View File

@ -40,7 +40,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
[TestFixture] [TestFixture]
public class SceneGraphTests public class SceneGraphTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestDuplicateObject() public void TestDuplicateObject()

View File

@ -0,0 +1,58 @@
/*
* 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.Threading;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Scenes.Tests
{
[TestFixture]
public class SceneManagerTests : OpenSimTestCase
{
[Test]
public void TestClose()
{
TestHelpers.InMethod();
SceneHelpers sh = new SceneHelpers();
Scene scene = sh.SetupScene();
sh.SceneManager.Close();
Assert.That(scene.ShuttingDown, Is.True);
}
}
}

View File

@ -29,6 +29,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using Nini.Config;
using NUnit.Framework; using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
@ -182,6 +183,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
/// <summary> /// <summary>
/// Test deleting an object from a scene. /// Test deleting an object from a scene.
/// </summary> /// </summary>
/// <remarks>
/// This is the most basic form of delete. For all more sophisticated forms of derez (done asynchrnously
/// and where object can be taken to user inventory, etc.), see SceneObjectDeRezTests.
/// </remarks>
[Test] [Test]
public void TestDeleteSceneObject() public void TestDeleteSceneObject()
{ {
@ -200,100 +205,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(retrievedPart, Is.Null); Assert.That(retrievedPart, Is.Null);
} }
/// <summary>
/// Test deleting an object asynchronously
/// </summary>
[Test]
public void TestDeleteSceneObjectAsync()
{
TestHelpers.InMethod();
//log4net.Config.XmlConfigurator.Configure();
UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
TestScene scene = new SceneHelpers().SetupScene();
// Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
sogd.Enabled = false;
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { so.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero);
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
Assert.That(retrievedPart, Is.Not.Null);
Assert.That(so.IsDeleted, Is.False);
sogd.InventoryDeQueueAndDelete();
Assert.That(so.IsDeleted, Is.True);
SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId);
Assert.That(retrievedPart2, Is.Null);
}
/// <summary>
/// Test deleting an object asynchronously to user inventory.
/// </summary>
// [Test]
public void TestDeleteSceneObjectAsyncToUserInventory()
{
TestHelpers.InMethod();
TestHelpers.EnableLogging();
UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
string myObjectName = "Fred";
TestScene scene = new SceneHelpers().SetupScene();
// Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
sogd.Enabled = false;
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, myObjectName, agentId);
// Assert.That(
// scene.CommsManager.UserAdminService.AddUser(
// "Bob", "Hoskins", "test", "test@test.com", 1000, 1000, agentId),
// Is.EqualTo(agentId));
UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, agentId);
InventoryFolderBase folder1
= UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1");
IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
scene.DeRezObjects(client, new List<uint>() { so.LocalId }, UUID.Zero, DeRezAction.Take, folder1.ID);
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
Assert.That(retrievedPart, Is.Not.Null);
Assert.That(so.IsDeleted, Is.False);
sogd.InventoryDeQueueAndDelete();
Assert.That(so.IsDeleted, Is.True);
SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId);
Assert.That(retrievedPart2, Is.Null);
// SceneSetupHelpers.DeleteSceneObjectAsync(scene, part, DeRezAction.Take, userInfo.RootFolder.ID, client);
InventoryItemBase retrievedItem
= UserInventoryHelpers.GetInventoryItem(
scene.InventoryService, ua.PrincipalID, "folder1/" + myObjectName);
// Check that we now have the taken part in our inventory
Assert.That(retrievedItem, Is.Not.Null);
// Check that the taken part has actually disappeared
// SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
// Assert.That(retrievedPart, Is.Null);
}
/// <summary> /// <summary>
/// Changing a scene object uuid changes the root part uuid. This is a valid operation if the object is not /// Changing a scene object uuid changes the root part uuid. This is a valid operation if the object is not
/// in a scene and is useful if one wants to supply a UUID directly rather than use the one generated by /// in a scene and is useful if one wants to supply a UUID directly rather than use the one generated by

View File

@ -33,22 +33,24 @@ using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Communications; using OpenSim.Framework.Communications;
using OpenSim.Region.CoreModules.Framework.InventoryAccess;
using OpenSim.Region.CoreModules.World.Permissions; using OpenSim.Region.CoreModules.World.Permissions;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
/// <summary> /// <summary>
/// Tests derez of scene objects by users. /// Tests derez of scene objects.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This is at a level above the SceneObjectBasicTests, which act on the scene directly. /// This is at a level above the SceneObjectBasicTests, which act on the scene directly.
/// TODO: These tests are very incomplete - they only test for a few conditions. /// TODO: These tests are incomplete - need to test more kinds of derez (e.g. return object).
/// </remarks> /// </remarks>
[TestFixture] [TestFixture]
public class SceneObjectDeRezTests public class SceneObjectDeRezTests : OpenSimTestCase
{ {
/// <summary> /// <summary>
/// Test deleting an object from a scene. /// Test deleting an object from a scene.
@ -76,14 +78,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
= new SceneObjectPart(userId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero); = new SceneObjectPart(userId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero);
part.Name = "obj1"; part.Name = "obj1";
scene.AddNewSceneObject(new SceneObjectGroup(part), false); scene.AddNewSceneObject(new SceneObjectGroup(part), false);
List<uint> localIds = new List<uint>(); List<uint> localIds = new List<uint>();
localIds.Add(part.LocalId); localIds.Add(part.LocalId);
scene.DeRezObjects(client, localIds, UUID.Zero, DeRezAction.Delete, UUID.Zero); scene.DeRezObjects(client, localIds, UUID.Zero, DeRezAction.Delete, UUID.Zero);
// Check that object isn't deleted until we crank the sogd handle.
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
Assert.That(retrievedPart, Is.Not.Null);
Assert.That(retrievedPart.ParentGroup.IsDeleted, Is.False);
sogd.InventoryDeQueueAndDelete(); sogd.InventoryDeQueueAndDelete();
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(part.LocalId);
Assert.That(retrievedPart, Is.Null); Assert.That(retrievedPart2, Is.Null);
} }
/// <summary> /// <summary>
@ -125,5 +133,66 @@ namespace OpenSim.Region.Framework.Scenes.Tests
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
Assert.That(retrievedPart.UUID, Is.EqualTo(part.UUID)); Assert.That(retrievedPart.UUID, Is.EqualTo(part.UUID));
} }
/// <summary>
/// Test deleting an object asynchronously to user inventory.
/// </summary>
[Test]
public void TestDeleteSceneObjectAsyncToUserInventory()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
string myObjectName = "Fred";
TestScene scene = new SceneHelpers().SetupScene();
IConfigSource configSource = new IniConfigSource();
IConfig config = configSource.AddConfig("Modules");
config.Set("InventoryAccessModule", "BasicInventoryAccessModule");
SceneHelpers.SetupSceneModules(
scene, configSource, new object[] { new BasicInventoryAccessModule() });
SceneHelpers.SetupSceneModules(scene, new object[] { });
// Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
sogd.Enabled = false;
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, myObjectName, agentId);
UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, agentId);
InventoryFolderBase folder1
= UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1");
IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
scene.DeRezObjects(client, new List<uint>() { so.LocalId }, UUID.Zero, DeRezAction.Take, folder1.ID);
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
Assert.That(retrievedPart, Is.Not.Null);
Assert.That(so.IsDeleted, Is.False);
sogd.InventoryDeQueueAndDelete();
Assert.That(so.IsDeleted, Is.True);
SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId);
Assert.That(retrievedPart2, Is.Null);
// SceneSetupHelpers.DeleteSceneObjectAsync(scene, part, DeRezAction.Take, userInfo.RootFolder.ID, client);
InventoryItemBase retrievedItem
= UserInventoryHelpers.GetInventoryItem(
scene.InventoryService, ua.PrincipalID, "folder1/" + myObjectName);
// Check that we now have the taken part in our inventory
Assert.That(retrievedItem, Is.Not.Null);
// Check that the taken part has actually disappeared
// SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
// Assert.That(retrievedPart, Is.Null);
}
} }
} }

View File

@ -40,7 +40,7 @@ using log4net;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
[TestFixture] [TestFixture]
public class SceneObjectLinkingTests public class SceneObjectLinkingTests : OpenSimTestCase
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

View File

@ -41,7 +41,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
/// Basic scene object resize tests /// Basic scene object resize tests
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class SceneObjectResizeTests public class SceneObjectResizeTests : OpenSimTestCase
{ {
/// <summary> /// <summary>
/// Test resizing an object /// Test resizing an object

View File

@ -40,7 +40,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
[TestFixture] [TestFixture]
public class SceneObjectScriptTests public class SceneObjectScriptTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestAddScript() public void TestAddScript()

View File

@ -42,14 +42,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
/// Spatial scene object tests (will eventually cover root and child part position, rotation properties, etc.) /// Spatial scene object tests (will eventually cover root and child part position, rotation properties, etc.)
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class SceneObjectSpatialTests public class SceneObjectSpatialTests : OpenSimTestCase
{ {
TestScene m_scene; TestScene m_scene;
UUID m_ownerId = TestHelpers.ParseTail(0x1); UUID m_ownerId = TestHelpers.ParseTail(0x1);
[SetUp] [SetUp]
public void SetUp() public override void SetUp()
{ {
base.SetUp();
m_scene = new SceneHelpers().SetupScene(); m_scene = new SceneHelpers().SetupScene();
} }

View File

@ -42,7 +42,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
/// Basic scene object status tests /// Basic scene object status tests
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class SceneObjectStatusTests public class SceneObjectStatusTests : OpenSimTestCase
{ {
private TestScene m_scene; private TestScene m_scene;
private UUID m_ownerId = TestHelpers.ParseTail(0x1); private UUID m_ownerId = TestHelpers.ParseTail(0x1);

View File

@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
/// Scene presence animation tests /// Scene presence animation tests
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class ScenePresenceAnimationTests public class ScenePresenceAnimationTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestFlyingAnimation() public void TestFlyingAnimation()

View File

@ -42,7 +42,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
[TestFixture] [TestFixture]
public class ScenePresenceAutopilotTests public class ScenePresenceAutopilotTests : OpenSimTestCase
{ {
private TestScene m_scene; private TestScene m_scene;

View File

@ -43,7 +43,7 @@ using System.Threading;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
[TestFixture] [TestFixture]
public class ScenePresenceSitTests public class ScenePresenceSitTests : OpenSimTestCase
{ {
private TestScene m_scene; private TestScene m_scene;
private ScenePresence m_sp; private ScenePresence m_sp;

View File

@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
/// Teleport tests in a standalone OpenSim /// Teleport tests in a standalone OpenSim
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class ScenePresenceTeleportTests public class ScenePresenceTeleportTests : OpenSimTestCase
{ {
[TestFixtureSetUp] [TestFixtureSetUp]
public void FixtureInit() public void FixtureInit()

View File

@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
/// Scene presence tests /// Scene presence tests
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class SceneTests public class SceneTests : OpenSimTestCase
{ {
/// <summary> /// <summary>
/// Very basic scene update test. Should become more elaborate with time. /// Very basic scene update test. Should become more elaborate with time.

View File

@ -50,7 +50,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Tests namespace OpenSim.Region.Framework.Tests
{ {
[TestFixture] [TestFixture]
public class TaskInventoryTests public class TaskInventoryTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestAddTaskInventoryItem() public void TestAddTaskInventoryItem()

View File

@ -38,7 +38,7 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
[TestFixture] [TestFixture]
public class UuidGathererTests public class UuidGathererTests : OpenSimTestCase
{ {
protected IAssetService m_assetService; protected IAssetService m_assetService;
protected UuidGatherer m_uuidGatherer; protected UuidGatherer m_uuidGatherer;

View File

@ -36,7 +36,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
{ {
UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID);
void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish);
/// <summary>
/// Get the group record.
/// </summary>
/// <returns></returns>
/// <param name='RequestingAgentID'>The UUID of the user making the request.</param>
/// <param name='GroupID'>
/// The ID of the record to retrieve.
/// GroupName may be specified instead, in which case this parameter will be UUID.Zero
/// </param>
/// <param name='GroupName'>
/// The name of the group to retrieve.
/// GroupID may be specified instead, in which case this parmeter will be null.
/// </param>
GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName);
List<DirGroupsReplyData> FindGroups(UUID RequestingAgentID, string search); List<DirGroupsReplyData> FindGroups(UUID RequestingAgentID, string search);
List<GroupMembersData> GetGroupMembers(UUID RequestingAgentID, UUID GroupID); List<GroupMembersData> GetGroupMembers(UUID RequestingAgentID, UUID GroupID);

View File

@ -42,7 +42,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
/// Basic groups module tests /// Basic groups module tests
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class GroupsModuleTests public class GroupsModuleTests : OpenSimTestCase
{ {
[Test] [Test]
public void TestBasic() public void TestBasic()

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