Merge branch 'master' of /home/opensim/var/repo/opensim
Conflicts: OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.csintegration
commit
1140cb613b
|
@ -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">
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
|
||||||
try
|
|
||||||
{
|
|
||||||
cmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
public class MySqlFolderHandler : MySqlInventoryHandler<XInventoryFolder>
|
||||||
{
|
|
||||||
// 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>
|
|
||||||
{
|
{
|
||||||
// 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();
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>();
|
||||||
{
|
|
||||||
string dllName = String.Empty;
|
|
||||||
string connString = String.Empty;
|
|
||||||
|
|
||||||
//
|
public NullXGroupData(string connectionString, string realm) {}
|
||||||
// Try reading the [DatabaseService] section first, if it exists
|
|
||||||
//
|
public bool StoreGroup(XGroup group)
|
||||||
IConfig dbConfig = config.Configs["DatabaseService"];
|
|
||||||
if (dbConfig != null)
|
|
||||||
{
|
{
|
||||||
dllName = dbConfig.GetString("StorageProvider", String.Empty);
|
lock (m_groups)
|
||||||
connString = dbConfig.GetString("ConnectionString", String.Empty);
|
{
|
||||||
|
m_groups[group.groupID] = group.Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
return true;
|
||||||
// Try reading the more specific [InventoryService] section, if it exists
|
}
|
||||||
//
|
|
||||||
IConfig inventoryConfig = config.Configs["InventoryService"];
|
public XGroup[] GetGroups(string field, string val)
|
||||||
if (inventoryConfig != null)
|
|
||||||
{
|
{
|
||||||
dllName = inventoryConfig.GetString("StorageProvider", dllName);
|
return GetGroups(new string[] { field }, new string[] { val });
|
||||||
connString = inventoryConfig.GetString("ConnectionString", connString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
public XGroup[] GetGroups(string[] fields, string[] vals)
|
||||||
// We tried, but this doesn't exist. We can't proceed.
|
{
|
||||||
//
|
lock (m_groups)
|
||||||
if (dllName.Equals(String.Empty))
|
{
|
||||||
throw new Exception("No InventoryService configuration");
|
List<XGroup> origGroups = Get<XGroup>(fields, vals, m_groups.Values.ToList());
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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) {}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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,34 +86,10 @@ 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)
|
|
||||||
{
|
|
||||||
Notice("No appender named Console found (see the log4net config file for this executable)!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_consoleAppender.Console = 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_console.Commands.AddCommand("General", false, "quit",
|
m_console.Commands.AddCommand("General", false, "quit",
|
||||||
"quit",
|
"quit",
|
||||||
|
@ -163,47 +98,6 @@ namespace OpenSim.Framework.Servers
|
||||||
m_console.Commands.AddCommand("General", false, "shutdown",
|
m_console.Commands.AddCommand("General", false, "shutdown",
|
||||||
"shutdown",
|
"shutdown",
|
||||||
"Quit the application", HandleQuit);
|
"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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -1740,6 +1740,9 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
||||||
|
{
|
||||||
|
// ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
|
||||||
|
if (m_ThreadPool != null)
|
||||||
{
|
{
|
||||||
threadPoolUsed = "SmartThreadPool";
|
threadPoolUsed = "SmartThreadPool";
|
||||||
maxThreads = m_ThreadPool.MaxThreads;
|
maxThreads = m_ThreadPool.MaxThreads;
|
||||||
|
@ -1748,6 +1751,7 @@ namespace OpenSim.Framework
|
||||||
allocatedThreads = m_ThreadPool.ActiveThreads;
|
allocatedThreads = m_ThreadPool.ActiveThreads;
|
||||||
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
|
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
|
FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
|
||||||
|| FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
|
|| FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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,113 +570,11 @@ 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>
|
||||||
/// Load, Unload, and list Region modules in use
|
/// Load, Unload, and list Region modules in use
|
||||||
/// </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>
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -1085,19 +1081,5 @@ namespace OpenSim
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,13 +618,19 @@ 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
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
||||||
|
@ -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,9 +1749,11 @@ 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)
|
||||||
{
|
{
|
||||||
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
|
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -552,13 +552,22 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
|
|
||||||
// Validate User and Group UUID's
|
// Validate User and Group UUID's
|
||||||
|
|
||||||
|
if (parcel.IsGroupOwned)
|
||||||
|
{
|
||||||
|
if (!ResolveGroupUuid(parcel.GroupID))
|
||||||
|
{
|
||||||
|
parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
|
parcel.GroupID = UUID.Zero;
|
||||||
|
parcel.IsGroupOwned = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!ResolveUserUuid(scene, parcel.OwnerID))
|
if (!ResolveUserUuid(scene, parcel.OwnerID))
|
||||||
parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
|
parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
|
|
||||||
if (!ResolveGroupUuid(parcel.GroupID))
|
if (!ResolveGroupUuid(parcel.GroupID))
|
||||||
{
|
|
||||||
parcel.GroupID = UUID.Zero;
|
parcel.GroupID = UUID.Zero;
|
||||||
parcel.IsGroupOwned = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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();
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
UUID ownerId = TestHelpers.ParseTail(0xaaaa);
|
||||||
AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
|
|
||||||
scene.AssetService.Store(soundAsset);
|
MemoryStream archiveWriteStream = new MemoryStream();
|
||||||
asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -1390,11 +1390,12 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,8 +115,6 @@ 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);
|
||||||
|
@ -126,8 +124,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
lock (m_Clients)
|
lock (m_Clients)
|
||||||
m_Clients.Remove(remoteClient.AgentId);
|
m_Clients.Remove(remoteClient.AgentId);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
|
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,18 +188,17 @@ 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
|
// If the currently selected scene has been restarted, then we can't reselect here since we the scene
|
||||||
// Prevents duplicates.
|
// hasn't yet been recreated. We will have to leave this to the caller.
|
||||||
|
if (CurrentScene == restartedScene)
|
||||||
if (RegionSceneElement >= 0)
|
CurrentScene = null;
|
||||||
{
|
|
||||||
m_localScenes.RemoveAt(RegionSceneElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -54,13 +54,62 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
|
|
||||||
private bool m_debugEnabled = false;
|
private bool m_debugEnabled = false;
|
||||||
|
|
||||||
public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome |
|
public const GroupPowers DefaultEveryonePowers
|
||||||
GroupPowers.Accountable |
|
= GroupPowers.AllowSetHome
|
||||||
GroupPowers.JoinChat |
|
| GroupPowers.Accountable
|
||||||
GroupPowers.AllowVoiceChat |
|
| GroupPowers.JoinChat
|
||||||
GroupPowers.ReceiveNotices |
|
| GroupPowers.AllowVoiceChat
|
||||||
GroupPowers.StartProposal |
|
| GroupPowers.ReceiveNotices
|
||||||
GroupPowers.VoteOnProposal;
|
| GroupPowers.StartProposal
|
||||||
|
| GroupPowers.VoteOnProposal;
|
||||||
|
|
||||||
|
// Would this be cleaner as (GroupPowers)ulong.MaxValue?
|
||||||
|
public const GroupPowers DefaultOwnerPowers
|
||||||
|
= GroupPowers.Accountable
|
||||||
|
| GroupPowers.AllowEditLand
|
||||||
|
| GroupPowers.AllowFly
|
||||||
|
| GroupPowers.AllowLandmark
|
||||||
|
| GroupPowers.AllowRez
|
||||||
|
| GroupPowers.AllowSetHome
|
||||||
|
| GroupPowers.AllowVoiceChat
|
||||||
|
| GroupPowers.AssignMember
|
||||||
|
| GroupPowers.AssignMemberLimited
|
||||||
|
| GroupPowers.ChangeActions
|
||||||
|
| GroupPowers.ChangeIdentity
|
||||||
|
| GroupPowers.ChangeMedia
|
||||||
|
| GroupPowers.ChangeOptions
|
||||||
|
| GroupPowers.CreateRole
|
||||||
|
| GroupPowers.DeedObject
|
||||||
|
| GroupPowers.DeleteRole
|
||||||
|
| GroupPowers.Eject
|
||||||
|
| GroupPowers.FindPlaces
|
||||||
|
| GroupPowers.Invite
|
||||||
|
| GroupPowers.JoinChat
|
||||||
|
| GroupPowers.LandChangeIdentity
|
||||||
|
| GroupPowers.LandDeed
|
||||||
|
| GroupPowers.LandDivideJoin
|
||||||
|
| GroupPowers.LandEdit
|
||||||
|
| GroupPowers.LandEjectAndFreeze
|
||||||
|
| GroupPowers.LandGardening
|
||||||
|
| GroupPowers.LandManageAllowed
|
||||||
|
| GroupPowers.LandManageBanned
|
||||||
|
| GroupPowers.LandManagePasses
|
||||||
|
| GroupPowers.LandOptions
|
||||||
|
| GroupPowers.LandRelease
|
||||||
|
| GroupPowers.LandSetSale
|
||||||
|
| GroupPowers.ModerateChat
|
||||||
|
| GroupPowers.ObjectManipulate
|
||||||
|
| GroupPowers.ObjectSetForSale
|
||||||
|
| GroupPowers.ReceiveNotices
|
||||||
|
| GroupPowers.RemoveMember
|
||||||
|
| GroupPowers.ReturnGroupOwned
|
||||||
|
| GroupPowers.ReturnGroupSet
|
||||||
|
| GroupPowers.ReturnNonGroup
|
||||||
|
| GroupPowers.RoleProperties
|
||||||
|
| GroupPowers.SendNotices
|
||||||
|
| GroupPowers.SetLandingPoint
|
||||||
|
| GroupPowers.StartProposal
|
||||||
|
| GroupPowers.VoteOnProposal;
|
||||||
|
|
||||||
private bool m_connectorEnabled = false;
|
private bool m_connectorEnabled = false;
|
||||||
|
|
||||||
|
@ -219,59 +268,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
param["AllowPublish"] = allowPublish == true ? 1 : 0;
|
param["AllowPublish"] = allowPublish == true ? 1 : 0;
|
||||||
param["MaturePublish"] = maturePublish == true ? 1 : 0;
|
param["MaturePublish"] = maturePublish == true ? 1 : 0;
|
||||||
param["FounderID"] = founderID.ToString();
|
param["FounderID"] = founderID.ToString();
|
||||||
param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString();
|
param["EveryonePowers"] = ((ulong)DefaultEveryonePowers).ToString();
|
||||||
param["OwnerRoleID"] = OwnerRoleID.ToString();
|
param["OwnerRoleID"] = OwnerRoleID.ToString();
|
||||||
|
param["OwnersPowers"] = ((ulong)DefaultOwnerPowers).ToString();
|
||||||
// Would this be cleaner as (GroupPowers)ulong.MaxValue;
|
|
||||||
GroupPowers OwnerPowers = GroupPowers.Accountable
|
|
||||||
| GroupPowers.AllowEditLand
|
|
||||||
| GroupPowers.AllowFly
|
|
||||||
| GroupPowers.AllowLandmark
|
|
||||||
| GroupPowers.AllowRez
|
|
||||||
| GroupPowers.AllowSetHome
|
|
||||||
| GroupPowers.AllowVoiceChat
|
|
||||||
| GroupPowers.AssignMember
|
|
||||||
| GroupPowers.AssignMemberLimited
|
|
||||||
| GroupPowers.ChangeActions
|
|
||||||
| GroupPowers.ChangeIdentity
|
|
||||||
| GroupPowers.ChangeMedia
|
|
||||||
| GroupPowers.ChangeOptions
|
|
||||||
| GroupPowers.CreateRole
|
|
||||||
| GroupPowers.DeedObject
|
|
||||||
| GroupPowers.DeleteRole
|
|
||||||
| GroupPowers.Eject
|
|
||||||
| GroupPowers.FindPlaces
|
|
||||||
| GroupPowers.Invite
|
|
||||||
| GroupPowers.JoinChat
|
|
||||||
| GroupPowers.LandChangeIdentity
|
|
||||||
| GroupPowers.LandDeed
|
|
||||||
| GroupPowers.LandDivideJoin
|
|
||||||
| GroupPowers.LandEdit
|
|
||||||
| GroupPowers.LandEjectAndFreeze
|
|
||||||
| GroupPowers.LandGardening
|
|
||||||
| GroupPowers.LandManageAllowed
|
|
||||||
| GroupPowers.LandManageBanned
|
|
||||||
| GroupPowers.LandManagePasses
|
|
||||||
| GroupPowers.LandOptions
|
|
||||||
| GroupPowers.LandRelease
|
|
||||||
| GroupPowers.LandSetSale
|
|
||||||
| GroupPowers.ModerateChat
|
|
||||||
| GroupPowers.ObjectManipulate
|
|
||||||
| GroupPowers.ObjectSetForSale
|
|
||||||
| GroupPowers.ReceiveNotices
|
|
||||||
| GroupPowers.RemoveMember
|
|
||||||
| GroupPowers.ReturnGroupOwned
|
|
||||||
| GroupPowers.ReturnGroupSet
|
|
||||||
| GroupPowers.ReturnNonGroup
|
|
||||||
| GroupPowers.RoleProperties
|
|
||||||
| GroupPowers.SendNotices
|
|
||||||
| GroupPowers.SetLandingPoint
|
|
||||||
| GroupPowers.StartProposal
|
|
||||||
| GroupPowers.VoteOnProposal;
|
|
||||||
param["OwnersPowers"] = ((ulong)OwnerPowers).ToString();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param);
|
Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param);
|
||||||
|
|
||||||
|
@ -612,8 +611,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
return Roles;
|
return Roles;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GroupRolesData> GetGroupRoles(UUID requestingAgentID, UUID GroupID)
|
public List<GroupRolesData> GetGroupRoles(UUID requestingAgentID, UUID GroupID)
|
||||||
|
@ -676,7 +673,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
return members;
|
return members;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GroupRoleMembersData> GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID)
|
public List<GroupRoleMembersData> GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID)
|
||||||
|
@ -727,9 +723,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
values.Add(data);
|
values.Add(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values;
|
|
||||||
|
|
||||||
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
|
public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
|
||||||
{
|
{
|
||||||
Hashtable param = new Hashtable();
|
Hashtable param = new Hashtable();
|
||||||
|
@ -737,7 +734,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
|
|
||||||
Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param);
|
Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param);
|
||||||
|
|
||||||
|
|
||||||
if (respData.Contains("error"))
|
if (respData.Contains("error"))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -761,6 +757,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket)
|
public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket)
|
||||||
{
|
{
|
||||||
string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, "");
|
string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, "");
|
||||||
|
@ -777,8 +774,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||||
XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param);
|
XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GroupSessionTracking
|
#region GroupSessionTracking
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue