Merge branch 'master' into 0.7.2-post-fixes
commit
8c4dd6b330
|
@ -117,6 +117,7 @@ what it is today.
|
||||||
* nornalbion
|
* nornalbion
|
||||||
* Omar Vera Ustariz (IBM)
|
* Omar Vera Ustariz (IBM)
|
||||||
* openlifegrid.com
|
* openlifegrid.com
|
||||||
|
* Oren Hurvitz (Kitely)
|
||||||
* otakup0pe
|
* otakup0pe
|
||||||
* ralphos
|
* ralphos
|
||||||
* RemedyTomm
|
* RemedyTomm
|
||||||
|
|
|
@ -709,6 +709,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
// ok, client wants us to use an explicit UUID
|
// ok, client wants us to use an explicit UUID
|
||||||
// regardless of what the avatar name provided
|
// regardless of what the avatar name provided
|
||||||
userID = new UUID((string) requestData["estate_owner_uuid"]);
|
userID = new UUID((string) requestData["estate_owner_uuid"]);
|
||||||
|
|
||||||
|
// Check that the specified user exists
|
||||||
|
Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
|
||||||
|
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
||||||
|
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID);
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
throw new Exception("Specified user was not found.");
|
||||||
}
|
}
|
||||||
else if (requestData.ContainsKey("estate_owner_first") & requestData.ContainsKey("estate_owner_last"))
|
else if (requestData.ContainsKey("estate_owner_first") & requestData.ContainsKey("estate_owner_last"))
|
||||||
{
|
{
|
||||||
|
@ -720,6 +728,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
||||||
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
|
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
|
||||||
ownerFirst, ownerLast);
|
ownerFirst, ownerLast);
|
||||||
|
|
||||||
|
// Check that the specified user exists
|
||||||
|
if (user == null)
|
||||||
|
throw new Exception("Specified user was not found.");
|
||||||
|
|
||||||
userID = user.PrincipalID;
|
userID = user.PrincipalID;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -728,21 +741,30 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new estate with the name provided
|
// Create a new estate with the name provided
|
||||||
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, true);
|
region.EstateSettings = m_application.EstateDataService.CreateNewEstate();
|
||||||
|
|
||||||
region.EstateSettings.EstateName = (string) requestData["estate_name"];
|
region.EstateSettings.EstateName = (string) requestData["estate_name"];
|
||||||
region.EstateSettings.EstateOwner = userID;
|
region.EstateSettings.EstateOwner = userID;
|
||||||
// Persistence does not seem to effect the need to save a new estate
|
// Persistence does not seem to effect the need to save a new estate
|
||||||
region.EstateSettings.Save();
|
region.EstateSettings.Save();
|
||||||
|
|
||||||
|
if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID))
|
||||||
|
throw new Exception("Failed to join estate.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int estateID = estateIDs[0];
|
int estateID = estateIDs[0];
|
||||||
|
|
||||||
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID);
|
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false);
|
||||||
|
|
||||||
if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID))
|
if (region.EstateSettings.EstateID != estateID)
|
||||||
throw new Exception("Failed to join estate.");
|
{
|
||||||
|
// The region is already part of an estate, but not the one we want.
|
||||||
|
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID);
|
||||||
|
|
||||||
|
if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID))
|
||||||
|
throw new Exception("Failed to join estate.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the region and perform any initial initialization
|
// Create the region and perform any initial initialization
|
||||||
|
|
|
@ -169,7 +169,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
|
||||||
float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]);
|
float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]);
|
||||||
float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]);
|
float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]);
|
||||||
Vector3 vector = new Vector3(x, y, z);
|
Vector3 vector = new Vector3(x, y, z);
|
||||||
presence.MoveToTarget(vector, false);
|
presence.MoveToTarget(vector, false, false);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -148,55 +148,10 @@ namespace OpenSim.Data.MSSQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (insertEstate && create)
|
if (insertEstate && create)
|
||||||
{
|
{
|
||||||
List<string> names = new List<string>(FieldList);
|
DoCreate(es);
|
||||||
|
LinkRegion(regionID, (int)es.EstateID);
|
||||||
names.Remove("EstateID");
|
|
||||||
|
|
||||||
sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
|
|
||||||
|
|
||||||
//_Log.Debug("[DB ESTATE]: SQL: " + sql);
|
|
||||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
|
||||||
using (SqlCommand insertCommand = new SqlCommand(sql, conn))
|
|
||||||
{
|
|
||||||
insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
|
|
||||||
|
|
||||||
foreach (string name in names)
|
|
||||||
{
|
|
||||||
insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
|
|
||||||
}
|
|
||||||
SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
|
|
||||||
idParameter.Direction = ParameterDirection.Output;
|
|
||||||
insertCommand.Parameters.Add(idParameter);
|
|
||||||
conn.Open();
|
|
||||||
insertCommand.ExecuteNonQuery();
|
|
||||||
|
|
||||||
es.EstateID = Convert.ToUInt32(idParameter.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
sql = "INSERT INTO [estate_map] ([RegionID] ,[EstateID]) VALUES (@RegionID, @EstateID)";
|
|
||||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
|
||||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
|
||||||
{
|
|
||||||
|
|
||||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID));
|
|
||||||
cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
|
|
||||||
// This will throw on dupe key
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
cmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO check if this is needed??
|
|
||||||
es.Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadBanList(es);
|
LoadBanList(es);
|
||||||
|
@ -210,6 +165,53 @@ namespace OpenSim.Data.MSSQL
|
||||||
return es;
|
return es;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EstateSettings CreateNewEstate()
|
||||||
|
{
|
||||||
|
EstateSettings es = new EstateSettings();
|
||||||
|
es.OnSave += StoreEstateSettings;
|
||||||
|
|
||||||
|
DoCreate(es);
|
||||||
|
|
||||||
|
LoadBanList(es);
|
||||||
|
|
||||||
|
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
|
||||||
|
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
|
||||||
|
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
|
||||||
|
|
||||||
|
return es;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoCreate(EstateSettings es)
|
||||||
|
{
|
||||||
|
List<string> names = new List<string>(FieldList);
|
||||||
|
|
||||||
|
names.Remove("EstateID");
|
||||||
|
|
||||||
|
string sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
|
||||||
|
|
||||||
|
//_Log.Debug("[DB ESTATE]: SQL: " + sql);
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand insertCommand = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
|
||||||
|
|
||||||
|
foreach (string name in names)
|
||||||
|
{
|
||||||
|
insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
|
||||||
|
}
|
||||||
|
SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
|
||||||
|
idParameter.Direction = ParameterDirection.Output;
|
||||||
|
insertCommand.Parameters.Add(idParameter);
|
||||||
|
conn.Open();
|
||||||
|
insertCommand.ExecuteNonQuery();
|
||||||
|
|
||||||
|
es.EstateID = Convert.ToUInt32(idParameter.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO check if this is needed??
|
||||||
|
es.Save();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stores the estate settings.
|
/// Stores the estate settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -498,24 +500,43 @@ namespace OpenSim.Data.MSSQL
|
||||||
|
|
||||||
public bool LinkRegion(UUID regionID, int estateID)
|
public bool LinkRegion(UUID regionID, int estateID)
|
||||||
{
|
{
|
||||||
string sql = "insert into estate_map values (@RegionID, @EstateID)";
|
string deleteSQL = "delete from estate_map where RegionID = @RegionID";
|
||||||
|
string insertSQL = "insert into estate_map values (@RegionID, @EstateID)";
|
||||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
|
SqlTransaction transaction = conn.BeginTransaction();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(deleteSQL, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("@RegionID", regionID);
|
cmd.Transaction = transaction;
|
||||||
|
cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (SqlCommand cmd = new SqlCommand(insertSQL, conn))
|
||||||
|
{
|
||||||
|
cmd.Transaction = transaction;
|
||||||
|
cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
|
||||||
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||||
|
|
||||||
int ret = cmd.ExecuteNonQuery();
|
int ret = cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
transaction.Commit();
|
||||||
|
else
|
||||||
|
transaction.Rollback();
|
||||||
|
|
||||||
return (ret != 0);
|
return (ret != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
|
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
|
||||||
|
transaction.Rollback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -218,23 +218,27 @@ namespace OpenSim.Data.MSSQL
|
||||||
if (words.Length > 2)
|
if (words.Length > 2)
|
||||||
return new UserAccountData[0];
|
return new UserAccountData[0];
|
||||||
|
|
||||||
|
string sql = "";
|
||||||
|
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (SqlCommand cmd = new SqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
if (words.Length == 1)
|
if (words.Length == 1)
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @search or [LastName] like @search)", m_Realm);
|
sql = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @search or [LastName] like @search)", m_Realm);
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("@search", "%" + words[0] + "%"));
|
cmd.Parameters.Add(m_database.CreateParameter("@search", "%" + words[0] + "%"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @searchFirst or [LastName] like @searchLast)", m_Realm);
|
sql = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @searchFirst or [LastName] like @searchLast)", m_Realm);
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("@searchFirst", "%" + words[0] + "%"));
|
cmd.Parameters.Add(m_database.CreateParameter("@searchFirst", "%" + words[0] + "%"));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("@searchLast", "%" + words[1] + "%"));
|
cmd.Parameters.Add(m_database.CreateParameter("@searchLast", "%" + words[1] + "%"));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("@ScopeID", scopeID.ToString()));
|
cmd.Parameters.Add(m_database.CreateParameter("@ScopeID", scopeID.ToString()));
|
||||||
}
|
}
|
||||||
|
cmd.Connection = conn;
|
||||||
|
cmd.CommandText = sql;
|
||||||
|
conn.Open();
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,4 +19,32 @@ IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[userf
|
||||||
INSERT INTO Friends (PrincipalID, Friend, Flags, Offered)
|
INSERT INTO Friends (PrincipalID, Friend, Flags, Offered)
|
||||||
SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends;
|
SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends;
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 3
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
CREATE TABLE [Tmp_Friends]
|
||||||
|
([PrincipalID] varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||||
|
[Friend] varchar(255) NOT NULL,
|
||||||
|
[Flags] char(16) NOT NULL DEFAULT '0',
|
||||||
|
[Offered] varchar(32) NOT NULL DEFAULT 0)
|
||||||
|
ON [PRIMARY]
|
||||||
|
|
||||||
|
|
||||||
|
IF EXISTS(SELECT * FROM dbo.Friends)
|
||||||
|
EXEC('INSERT INTO dbo.Tmp_Friends (PrincipalID, Friend, Flags, Offered)
|
||||||
|
SELECT CONVERT(varchar(255),PrincipalID), Friend, Flags, Offered FROM dbo.Friends WITH (HOLDLOCK TABLOCKX)')
|
||||||
|
|
||||||
|
DROP TABLE dbo.Friends
|
||||||
|
|
||||||
|
EXECUTE sp_rename N'dbo.Tmp_Friends', N'Friends', 'OBJECT'
|
||||||
|
|
||||||
|
ALTER TABLE dbo.Friends ADD
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[PrincipalID] ASC, [Friend] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
|
@ -244,4 +244,36 @@ ALTER TABLE inventoryitems
|
||||||
ADD CONSTRAINT DF_inventoryitems_creatorID
|
ADD CONSTRAINT DF_inventoryitems_creatorID
|
||||||
DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID
|
DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID
|
||||||
|
|
||||||
|
:GO
|
||||||
|
|
||||||
|
:VERSION 9
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
# CreatorID goes up to VARCHAR(255)
|
||||||
|
|
||||||
|
exec sp_rename 'inventoryitems.CreatorID', 'cr_old', 'COLUMN'
|
||||||
|
|
||||||
|
:GO
|
||||||
|
|
||||||
|
alter table inventoryitems
|
||||||
|
add creatorID varchar(255) NULL
|
||||||
|
|
||||||
|
:GO
|
||||||
|
|
||||||
|
update inventoryitems set creatorID = cr_old
|
||||||
|
|
||||||
|
alter table inventoryitems
|
||||||
|
drop CONSTRAINT DF_inventoryitems_creatorID
|
||||||
|
:GO
|
||||||
|
|
||||||
|
alter table inventoryitems
|
||||||
|
drop column cr_old
|
||||||
|
:GO
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
ALTER TABLE inventoryitems
|
||||||
|
ADD CONSTRAINT DF_inventoryitems_creatorID
|
||||||
|
DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID
|
||||||
|
|
||||||
:GO
|
:GO
|
|
@ -1,23 +0,0 @@
|
||||||
<Addin id="OpenSim.Data.MSSQL" version="0.1">
|
|
||||||
<Runtime>
|
|
||||||
<Import assembly="OpenSim.Data.MSSQL.dll"/>
|
|
||||||
</Runtime>
|
|
||||||
<Dependencies>
|
|
||||||
<Addin id="OpenSim.Data" version="0.5" />
|
|
||||||
</Dependencies>
|
|
||||||
<Extension path = "/OpenSim/GridData">
|
|
||||||
<Plugin id="MSSQLGridData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLGridData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/LogData">
|
|
||||||
<Plugin id="MSSQLLogData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLLogData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/AssetData">
|
|
||||||
<Plugin id="MSSQLAssetData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLAssetData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/InventoryData">
|
|
||||||
<Plugin id="MSSQLInventoryData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLInventoryData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/UserData">
|
|
||||||
<Plugin id="MSSQLUserData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLUserData" />
|
|
||||||
</Extension>
|
|
||||||
</Addin>
|
|
|
@ -149,6 +149,22 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EstateSettings CreateNewEstate()
|
||||||
|
{
|
||||||
|
EstateSettings es = new EstateSettings();
|
||||||
|
es.OnSave += StoreEstateSettings;
|
||||||
|
|
||||||
|
DoCreate(es);
|
||||||
|
|
||||||
|
LoadBanList(es);
|
||||||
|
|
||||||
|
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
|
||||||
|
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
|
||||||
|
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
|
||||||
|
|
||||||
|
return es;
|
||||||
|
}
|
||||||
|
|
||||||
private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create)
|
private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create)
|
||||||
{
|
{
|
||||||
EstateSettings es = new EstateSettings();
|
EstateSettings es = new EstateSettings();
|
||||||
|
@ -188,54 +204,8 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
if (!found && create)
|
if (!found && create)
|
||||||
{
|
{
|
||||||
// Migration case
|
DoCreate(es);
|
||||||
List<string> names = new List<string>(FieldList);
|
LinkRegion(regionID, (int)es.EstateID);
|
||||||
|
|
||||||
names.Remove("EstateID");
|
|
||||||
|
|
||||||
string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")";
|
|
||||||
|
|
||||||
using (MySqlCommand cmd2 = dbcon.CreateCommand())
|
|
||||||
{
|
|
||||||
cmd2.CommandText = sql;
|
|
||||||
cmd2.Parameters.Clear();
|
|
||||||
|
|
||||||
foreach (string name in FieldList)
|
|
||||||
{
|
|
||||||
if (m_FieldMap[name].GetValue(es) is bool)
|
|
||||||
{
|
|
||||||
if ((bool)m_FieldMap[name].GetValue(es))
|
|
||||||
cmd2.Parameters.AddWithValue("?" + name, "1");
|
|
||||||
else
|
|
||||||
cmd2.Parameters.AddWithValue("?" + name, "0");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd2.ExecuteNonQuery();
|
|
||||||
|
|
||||||
cmd2.CommandText = "select LAST_INSERT_ID() as id";
|
|
||||||
cmd2.Parameters.Clear();
|
|
||||||
|
|
||||||
using (IDataReader r = cmd2.ExecuteReader())
|
|
||||||
{
|
|
||||||
r.Read();
|
|
||||||
es.EstateID = Convert.ToUInt32(r["id"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd2.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
|
|
||||||
cmd2.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
|
||||||
cmd2.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
|
|
||||||
|
|
||||||
// This will throw on dupe key
|
|
||||||
try { cmd2.ExecuteNonQuery(); }
|
|
||||||
catch (Exception) { }
|
|
||||||
|
|
||||||
es.Save();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +217,54 @@ namespace OpenSim.Data.MySQL
|
||||||
return es;
|
return es;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DoCreate(EstateSettings es)
|
||||||
|
{
|
||||||
|
// Migration case
|
||||||
|
List<string> names = new List<string>(FieldList);
|
||||||
|
|
||||||
|
names.Remove("EstateID");
|
||||||
|
|
||||||
|
string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")";
|
||||||
|
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
using (MySqlCommand cmd2 = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd2.CommandText = sql;
|
||||||
|
cmd2.Parameters.Clear();
|
||||||
|
|
||||||
|
foreach (string name in FieldList)
|
||||||
|
{
|
||||||
|
if (m_FieldMap[name].GetValue(es) is bool)
|
||||||
|
{
|
||||||
|
if ((bool)m_FieldMap[name].GetValue(es))
|
||||||
|
cmd2.Parameters.AddWithValue("?" + name, "1");
|
||||||
|
else
|
||||||
|
cmd2.Parameters.AddWithValue("?" + name, "0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd2.ExecuteNonQuery();
|
||||||
|
|
||||||
|
cmd2.CommandText = "select LAST_INSERT_ID() as id";
|
||||||
|
cmd2.Parameters.Clear();
|
||||||
|
|
||||||
|
using (IDataReader r = cmd2.ExecuteReader())
|
||||||
|
{
|
||||||
|
r.Read();
|
||||||
|
es.EstateID = Convert.ToUInt32(r["id"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
es.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void StoreEstateSettings(EstateSettings es)
|
public void StoreEstateSettings(EstateSettings es)
|
||||||
{
|
{
|
||||||
string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")";
|
string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")";
|
||||||
|
@ -477,7 +495,6 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dbcon.Close();
|
dbcon.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +524,6 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dbcon.Close();
|
dbcon.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,16 +535,34 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
MySqlTransaction transaction = dbcon.BeginTransaction();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Delete any existing association of this region with an estate.
|
||||||
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.Transaction = transaction;
|
||||||
|
cmd.CommandText = "delete from estate_map where RegionID = ?RegionID";
|
||||||
|
cmd.Parameters.AddWithValue("?RegionID", regionID);
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
{
|
{
|
||||||
|
cmd.Transaction = transaction;
|
||||||
cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
|
cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
|
||||||
cmd.Parameters.AddWithValue("?RegionID", regionID);
|
cmd.Parameters.AddWithValue("?RegionID", regionID);
|
||||||
cmd.Parameters.AddWithValue("?EstateID", estateID);
|
cmd.Parameters.AddWithValue("?EstateID", estateID);
|
||||||
|
|
||||||
int ret = cmd.ExecuteNonQuery();
|
int ret = cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
transaction.Commit();
|
||||||
|
else
|
||||||
|
transaction.Rollback();
|
||||||
|
|
||||||
dbcon.Close();
|
dbcon.Close();
|
||||||
|
|
||||||
return (ret != 0);
|
return (ret != 0);
|
||||||
|
@ -537,6 +571,7 @@ namespace OpenSim.Data.MySQL
|
||||||
catch (MySqlException ex)
|
catch (MySqlException ex)
|
||||||
{
|
{
|
||||||
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
|
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
|
||||||
|
transaction.Rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
dbcon.Close();
|
dbcon.Close();
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
<Addin id="OpenSim.Data.MySQL" version="0.1">
|
|
||||||
<Runtime>
|
|
||||||
<Import assembly="OpenSim.Data.MySQL.dll"/>
|
|
||||||
</Runtime>
|
|
||||||
<Dependencies>
|
|
||||||
<Addin id="OpenSim.Data" version="0.5" />
|
|
||||||
</Dependencies>
|
|
||||||
<Extension path = "/OpenSim/GridData">
|
|
||||||
<Plugin id="MySQLGridData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLGridData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/LogData">
|
|
||||||
<Plugin id="MySQLLogData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLLogData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/AssetData">
|
|
||||||
<Plugin id="MySQLAssetData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLAssetData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/InventoryData">
|
|
||||||
<Plugin id="MySQLInventoryData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLInventoryData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/UserData">
|
|
||||||
<Plugin id="MySQLUserData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLUserData" />
|
|
||||||
</Extension>
|
|
||||||
</Addin>
|
|
|
@ -84,6 +84,11 @@ namespace OpenSim.Data.Null
|
||||||
{
|
{
|
||||||
return new EstateSettings();
|
return new EstateSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EstateSettings CreateNewEstate()
|
||||||
|
{
|
||||||
|
return new EstateSettings();
|
||||||
|
}
|
||||||
|
|
||||||
public List<EstateSettings> LoadEstateSettingsAll()
|
public List<EstateSettings> LoadEstateSettingsAll()
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,8 +77,10 @@ namespace OpenSim.Data.Null
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||||
{
|
{
|
||||||
return null;
|
RegionSettings rs = new RegionSettings();
|
||||||
|
rs.RegionUUID = regionUUID;
|
||||||
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
<Addin id="OpenSim.Data.SQLite" version="0.1">
|
|
||||||
<Runtime>
|
|
||||||
<Import assembly="OpenSim.Data.SQLite.dll"/>
|
|
||||||
</Runtime>
|
|
||||||
<Dependencies>
|
|
||||||
<Addin id="OpenSim.Data" version="0.5" />
|
|
||||||
</Dependencies>
|
|
||||||
<Extension path = "/OpenSim/GridData">
|
|
||||||
<Plugin id="SQLiteGridData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteGridData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/AssetData">
|
|
||||||
<Plugin id="SQLiteAssetData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteAssetData" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/InventoryData">
|
|
||||||
<Plugin id="SQLiteInventoryData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteInventoryStore" />
|
|
||||||
</Extension>
|
|
||||||
<Extension path = "/OpenSim/UserData">
|
|
||||||
<Plugin id="SQLiteUserData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteUserData" />
|
|
||||||
</Extension>
|
|
||||||
</Addin>
|
|
|
@ -151,59 +151,8 @@ namespace OpenSim.Data.SQLite
|
||||||
}
|
}
|
||||||
else if (create)
|
else if (create)
|
||||||
{
|
{
|
||||||
r.Close();
|
DoCreate(es);
|
||||||
|
LinkRegion(regionID, (int)es.EstateID);
|
||||||
List<string> names = new List<string>(FieldList);
|
|
||||||
|
|
||||||
names.Remove("EstateID");
|
|
||||||
|
|
||||||
string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
|
|
||||||
|
|
||||||
cmd.CommandText = sql;
|
|
||||||
cmd.Parameters.Clear();
|
|
||||||
|
|
||||||
foreach (string name in FieldList)
|
|
||||||
{
|
|
||||||
if (m_FieldMap[name].GetValue(es) is bool)
|
|
||||||
{
|
|
||||||
if ((bool)m_FieldMap[name].GetValue(es))
|
|
||||||
cmd.Parameters.AddWithValue(":"+name, "1");
|
|
||||||
else
|
|
||||||
cmd.Parameters.AddWithValue(":"+name, "0");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
|
||||||
|
|
||||||
cmd.CommandText = "select LAST_INSERT_ROWID() as id";
|
|
||||||
cmd.Parameters.Clear();
|
|
||||||
|
|
||||||
r = cmd.ExecuteReader();
|
|
||||||
|
|
||||||
r.Read();
|
|
||||||
|
|
||||||
es.EstateID = Convert.ToUInt32(r["id"]);
|
|
||||||
|
|
||||||
r.Close();
|
|
||||||
|
|
||||||
cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
|
|
||||||
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
|
|
||||||
cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
|
|
||||||
|
|
||||||
// This will throw on dupe key
|
|
||||||
try
|
|
||||||
{
|
|
||||||
cmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
es.Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadBanList(es);
|
LoadBanList(es);
|
||||||
|
@ -214,6 +163,67 @@ namespace OpenSim.Data.SQLite
|
||||||
return es;
|
return es;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EstateSettings CreateNewEstate()
|
||||||
|
{
|
||||||
|
EstateSettings es = new EstateSettings();
|
||||||
|
es.OnSave += StoreEstateSettings;
|
||||||
|
|
||||||
|
DoCreate(es);
|
||||||
|
|
||||||
|
LoadBanList(es);
|
||||||
|
|
||||||
|
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
|
||||||
|
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
|
||||||
|
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
|
||||||
|
|
||||||
|
return es;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoCreate(EstateSettings es)
|
||||||
|
{
|
||||||
|
List<string> names = new List<string>(FieldList);
|
||||||
|
|
||||||
|
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
|
||||||
|
IDataReader r = null;
|
||||||
|
|
||||||
|
names.Remove("EstateID");
|
||||||
|
|
||||||
|
string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
|
||||||
|
|
||||||
|
cmd.CommandText = sql;
|
||||||
|
cmd.Parameters.Clear();
|
||||||
|
|
||||||
|
foreach (string name in FieldList)
|
||||||
|
{
|
||||||
|
if (m_FieldMap[name].GetValue(es) is bool)
|
||||||
|
{
|
||||||
|
if ((bool)m_FieldMap[name].GetValue(es))
|
||||||
|
cmd.Parameters.AddWithValue(":"+name, "1");
|
||||||
|
else
|
||||||
|
cmd.Parameters.AddWithValue(":"+name, "0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
|
cmd.CommandText = "select LAST_INSERT_ROWID() as id";
|
||||||
|
cmd.Parameters.Clear();
|
||||||
|
|
||||||
|
r = cmd.ExecuteReader();
|
||||||
|
|
||||||
|
r.Read();
|
||||||
|
|
||||||
|
es.EstateID = Convert.ToUInt32(r["id"]);
|
||||||
|
|
||||||
|
r.Close();
|
||||||
|
|
||||||
|
es.Save();
|
||||||
|
}
|
||||||
|
|
||||||
public void StoreEstateSettings(EstateSettings es)
|
public void StoreEstateSettings(EstateSettings es)
|
||||||
{
|
{
|
||||||
List<string> fields = new List<string>(FieldList);
|
List<string> fields = new List<string>(FieldList);
|
||||||
|
@ -440,16 +450,36 @@ namespace OpenSim.Data.SQLite
|
||||||
|
|
||||||
public bool LinkRegion(UUID regionID, int estateID)
|
public bool LinkRegion(UUID regionID, int estateID)
|
||||||
{
|
{
|
||||||
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
|
SqliteTransaction transaction = m_connection.BeginTransaction();
|
||||||
|
|
||||||
cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
|
// Delete any existing estate mapping for this region.
|
||||||
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
|
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
|
||||||
cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
|
{
|
||||||
|
cmd.CommandText = "delete from estate_map where RegionID = :RegionID";
|
||||||
|
cmd.Transaction = transaction;
|
||||||
|
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
|
||||||
|
|
||||||
if (cmd.ExecuteNonQuery() == 0)
|
cmd.ExecuteNonQuery();
|
||||||
return false;
|
}
|
||||||
|
|
||||||
return true;
|
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
|
||||||
|
cmd.Transaction = transaction;
|
||||||
|
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
|
||||||
|
cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
|
||||||
|
|
||||||
|
if (cmd.ExecuteNonQuery() == 0)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transaction.Commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UUID> GetRegions(int estateID)
|
public List<UUID> GetRegions(int estateID)
|
||||||
|
|
|
@ -167,6 +167,7 @@ namespace OpenSim.Framework
|
||||||
get { return m_metadata.FullID; }
|
get { return m_metadata.FullID; }
|
||||||
set { m_metadata.FullID = value; }
|
set { m_metadata.FullID = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Asset MetaData ID (transferring from UUID to string ID)
|
/// Asset MetaData ID (transferring from UUID to string ID)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -225,6 +225,8 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void ResetAppearance()
|
public virtual void ResetAppearance()
|
||||||
{
|
{
|
||||||
|
// m_log.WarnFormat("[AVATAR APPEARANCE]: Reset appearance");
|
||||||
|
|
||||||
m_serial = 0;
|
m_serial = 0;
|
||||||
|
|
||||||
SetDefaultTexture();
|
SetDefaultTexture();
|
||||||
|
@ -391,10 +393,14 @@ namespace OpenSim.Framework
|
||||||
public List<AvatarAttachment> GetAttachments()
|
public List<AvatarAttachment> GetAttachments()
|
||||||
{
|
{
|
||||||
List<AvatarAttachment> alist = new List<AvatarAttachment>();
|
List<AvatarAttachment> alist = new List<AvatarAttachment>();
|
||||||
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
|
||||||
|
lock (m_attachments)
|
||||||
{
|
{
|
||||||
foreach (AvatarAttachment attach in kvp.Value)
|
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
||||||
alist.Add(new AvatarAttachment(attach));
|
{
|
||||||
|
foreach (AvatarAttachment attach in kvp.Value)
|
||||||
|
alist.Add(new AvatarAttachment(attach));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return alist;
|
return alist;
|
||||||
|
@ -406,10 +412,13 @@ namespace OpenSim.Framework
|
||||||
// "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}",
|
// "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}",
|
||||||
// attach.ItemID, attach.AssetID, attach.AttachPoint);
|
// attach.ItemID, attach.AssetID, attach.AttachPoint);
|
||||||
|
|
||||||
if (!m_attachments.ContainsKey(attach.AttachPoint))
|
lock (m_attachments)
|
||||||
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
{
|
||||||
|
if (!m_attachments.ContainsKey(attach.AttachPoint))
|
||||||
m_attachments[attach.AttachPoint].Add(attach);
|
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
||||||
|
|
||||||
|
m_attachments[attach.AttachPoint].Add(attach);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ReplaceAttachment(AvatarAttachment attach)
|
internal void ReplaceAttachment(AvatarAttachment attach)
|
||||||
|
@ -418,8 +427,11 @@ namespace OpenSim.Framework
|
||||||
// "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
|
// "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
|
||||||
// attach.ItemID, attach.AssetID, attach.AttachPoint);
|
// attach.ItemID, attach.AssetID, attach.AttachPoint);
|
||||||
|
|
||||||
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
lock (m_attachments)
|
||||||
m_attachments[attach.AttachPoint].Add(attach);
|
{
|
||||||
|
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
||||||
|
m_attachments[attach.AttachPoint].Add(attach);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -448,10 +460,13 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
if (item == UUID.Zero)
|
if (item == UUID.Zero)
|
||||||
{
|
{
|
||||||
if (m_attachments.ContainsKey(attachpoint))
|
lock (m_attachments)
|
||||||
{
|
{
|
||||||
m_attachments.Remove(attachpoint);
|
if (m_attachments.ContainsKey(attachpoint))
|
||||||
return true;
|
{
|
||||||
|
m_attachments.Remove(attachpoint);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -494,11 +509,14 @@ namespace OpenSim.Framework
|
||||||
/// <returns>Returns null if this item is not attached.</returns>
|
/// <returns>Returns null if this item is not attached.</returns>
|
||||||
public AvatarAttachment GetAttachmentForItem(UUID itemID)
|
public AvatarAttachment GetAttachmentForItem(UUID itemID)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
lock (m_attachments)
|
||||||
{
|
{
|
||||||
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
|
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
||||||
if (index >= 0)
|
{
|
||||||
return kvp.Value[index];
|
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
|
||||||
|
if (index >= 0)
|
||||||
|
return kvp.Value[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -506,11 +524,14 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public int GetAttachpoint(UUID itemID)
|
public int GetAttachpoint(UUID itemID)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
lock (m_attachments)
|
||||||
{
|
{
|
||||||
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
|
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
||||||
if (index >= 0)
|
{
|
||||||
return kvp.Key;
|
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
|
||||||
|
if (index >= 0)
|
||||||
|
return kvp.Key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -518,27 +539,32 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public bool DetachAttachment(UUID itemID)
|
public bool DetachAttachment(UUID itemID)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
lock (m_attachments)
|
||||||
{
|
{
|
||||||
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
|
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
||||||
if (index >= 0)
|
|
||||||
{
|
{
|
||||||
// Remove it from the list of attachments at that attach point
|
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
|
||||||
m_attachments[kvp.Key].RemoveAt(index);
|
if (index >= 0)
|
||||||
|
{
|
||||||
// And remove the list if there are no more attachments here
|
// Remove it from the list of attachments at that attach point
|
||||||
if (m_attachments[kvp.Key].Count == 0)
|
m_attachments[kvp.Key].RemoveAt(index);
|
||||||
m_attachments.Remove(kvp.Key);
|
|
||||||
|
// And remove the list if there are no more attachments here
|
||||||
return true;
|
if (m_attachments[kvp.Key].Count == 0)
|
||||||
|
m_attachments.Remove(kvp.Key);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearAttachments()
|
public void ClearAttachments()
|
||||||
{
|
{
|
||||||
m_attachments.Clear();
|
lock (m_attachments)
|
||||||
|
m_attachments.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Packing Functions
|
#region Packing Functions
|
||||||
|
@ -576,7 +602,8 @@ namespace OpenSim.Framework
|
||||||
data["visualparams"] = visualparams;
|
data["visualparams"] = visualparams;
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
OSDArray attachs = new OSDArray(m_attachments.Count);
|
List<AvatarAttachment> attachments = GetAttachments();
|
||||||
|
OSDArray attachs = new OSDArray(attachments.Count);
|
||||||
foreach (AvatarAttachment attach in GetAttachments())
|
foreach (AvatarAttachment attach in GetAttachments())
|
||||||
attachs.Add(attach.Pack());
|
attachs.Add(attach.Pack());
|
||||||
data["attachments"] = attachs;
|
data["attachments"] = attachs;
|
||||||
|
|
|
@ -441,7 +441,6 @@ namespace OpenSim.Framework
|
||||||
args["controllers"] = controls;
|
args["controllers"] = controls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
|
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
|
||||||
args["callback_uri"] = OSD.FromString(CallbackURI);
|
args["callback_uri"] = OSD.FromString(CallbackURI);
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,11 @@ namespace OpenSim.Framework.Console
|
||||||
// private readonly object m_syncRoot = new object();
|
// private readonly object m_syncRoot = new object();
|
||||||
private const string LOGLEVEL_NONE = "(none)";
|
private const string LOGLEVEL_NONE = "(none)";
|
||||||
|
|
||||||
private int y = -1;
|
private int m_cursorYPosition = -1;
|
||||||
private int cp = 0;
|
private int m_cursorXPosition = 0;
|
||||||
private int h = 1;
|
private StringBuilder m_commandLine = new StringBuilder();
|
||||||
private StringBuilder cmdline = new StringBuilder();
|
private bool m_echo = true;
|
||||||
private bool echo = true;
|
private List<string> m_history = new List<string>();
|
||||||
private List<string> history = new List<string>();
|
|
||||||
|
|
||||||
private static readonly ConsoleColor[] Colors = {
|
private static readonly ConsoleColor[] Colors = {
|
||||||
// the dark colors don't seem to be visible on some black background terminals like putty :(
|
// the dark colors don't seem to be visible on some black background terminals like putty :(
|
||||||
|
@ -81,10 +80,10 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
private void AddToHistory(string text)
|
private void AddToHistory(string text)
|
||||||
{
|
{
|
||||||
while (history.Count >= 100)
|
while (m_history.Count >= 100)
|
||||||
history.RemoveAt(0);
|
m_history.RemoveAt(0);
|
||||||
|
|
||||||
history.Add(text);
|
m_history.Add(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -111,11 +110,11 @@ namespace OpenSim.Framework.Console
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int bw = System.Console.BufferWidth;
|
int bufferWidth = System.Console.BufferWidth;
|
||||||
|
|
||||||
// On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
|
// On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
|
||||||
if (bw > 0 && left >= bw)
|
if (bufferWidth > 0 && left >= bufferWidth)
|
||||||
System.Console.CursorLeft = bw - 1;
|
System.Console.CursorLeft = bufferWidth - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (top < 0)
|
if (top < 0)
|
||||||
|
@ -124,11 +123,11 @@ namespace OpenSim.Framework.Console
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int bh = System.Console.BufferHeight;
|
int bufferHeight = System.Console.BufferHeight;
|
||||||
|
|
||||||
// On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
|
// On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
|
||||||
if (bh > 0 && top >= bh)
|
if (bufferHeight > 0 && top >= bufferHeight)
|
||||||
top = bh - 1;
|
top = bufferHeight - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Console.CursorTop = top;
|
System.Console.CursorTop = top;
|
||||||
|
@ -160,10 +159,10 @@ namespace OpenSim.Framework.Console
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int bh = System.Console.BufferHeight;
|
int bufferHeight = System.Console.BufferHeight;
|
||||||
// On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
|
// On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
|
||||||
if (bh > 0 && top >= bh)
|
if (bufferHeight > 0 && top >= bufferHeight)
|
||||||
System.Console.CursorTop = bh - 1;
|
System.Console.CursorTop = bufferHeight - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left < 0)
|
if (left < 0)
|
||||||
|
@ -172,11 +171,11 @@ namespace OpenSim.Framework.Console
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int bw = System.Console.BufferWidth;
|
int bufferWidth = System.Console.BufferWidth;
|
||||||
|
|
||||||
// On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
|
// On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
|
||||||
if (bw > 0 && left >= bw)
|
if (bufferWidth > 0 && left >= bufferWidth)
|
||||||
left = bw - 1;
|
left = bufferWidth - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Console.CursorLeft = left;
|
System.Console.CursorLeft = left;
|
||||||
|
@ -186,31 +185,30 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
private void Show()
|
private void Show()
|
||||||
{
|
{
|
||||||
lock (cmdline)
|
lock (m_commandLine)
|
||||||
{
|
{
|
||||||
if (y == -1 || System.Console.BufferWidth == 0)
|
if (m_cursorYPosition == -1 || System.Console.BufferWidth == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int xc = prompt.Length + cp;
|
int xc = prompt.Length + m_cursorXPosition;
|
||||||
int new_x = xc % System.Console.BufferWidth;
|
int new_x = xc % System.Console.BufferWidth;
|
||||||
int new_y = y + xc / System.Console.BufferWidth;
|
int new_y = m_cursorYPosition + xc / System.Console.BufferWidth;
|
||||||
int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
|
int end_y = m_cursorYPosition + (m_commandLine.Length + prompt.Length) / System.Console.BufferWidth;
|
||||||
if (end_y / System.Console.BufferWidth >= h)
|
|
||||||
h++;
|
|
||||||
if (end_y >= System.Console.BufferHeight) // wrap
|
if (end_y >= System.Console.BufferHeight) // wrap
|
||||||
{
|
{
|
||||||
y--;
|
m_cursorYPosition--;
|
||||||
new_y--;
|
new_y--;
|
||||||
SetCursorLeft(0);
|
SetCursorLeft(0);
|
||||||
SetCursorTop(System.Console.BufferHeight - 1);
|
SetCursorTop(System.Console.BufferHeight - 1);
|
||||||
System.Console.WriteLine(" ");
|
System.Console.WriteLine(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
y = SetCursorTop(y);
|
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
|
||||||
SetCursorLeft(0);
|
SetCursorLeft(0);
|
||||||
|
|
||||||
if (echo)
|
if (m_echo)
|
||||||
System.Console.Write("{0}{1}", prompt, cmdline);
|
System.Console.Write("{0}{1}", prompt, m_commandLine);
|
||||||
else
|
else
|
||||||
System.Console.Write("{0}", prompt);
|
System.Console.Write("{0}", prompt);
|
||||||
|
|
||||||
|
@ -221,20 +219,20 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
public override void LockOutput()
|
public override void LockOutput()
|
||||||
{
|
{
|
||||||
Monitor.Enter(cmdline);
|
Monitor.Enter(m_commandLine);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (y != -1)
|
if (m_cursorYPosition != -1)
|
||||||
{
|
{
|
||||||
y = SetCursorTop(y);
|
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
|
||||||
System.Console.CursorLeft = 0;
|
System.Console.CursorLeft = 0;
|
||||||
|
|
||||||
int count = cmdline.Length + prompt.Length;
|
int count = m_commandLine.Length + prompt.Length;
|
||||||
|
|
||||||
while (count-- > 0)
|
while (count-- > 0)
|
||||||
System.Console.Write(" ");
|
System.Console.Write(" ");
|
||||||
|
|
||||||
y = SetCursorTop(y);
|
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
|
||||||
SetCursorLeft(0);
|
SetCursorLeft(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,12 +243,12 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
public override void UnlockOutput()
|
public override void UnlockOutput()
|
||||||
{
|
{
|
||||||
if (y != -1)
|
if (m_cursorYPosition != -1)
|
||||||
{
|
{
|
||||||
y = System.Console.CursorTop;
|
m_cursorYPosition = System.Console.CursorTop;
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
Monitor.Exit(cmdline);
|
Monitor.Exit(m_commandLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteColorText(ConsoleColor color, string sender)
|
private void WriteColorText(ConsoleColor color, string sender)
|
||||||
|
@ -317,29 +315,29 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
public override void Output(string text, string level)
|
public override void Output(string text, string level)
|
||||||
{
|
{
|
||||||
lock (cmdline)
|
lock (m_commandLine)
|
||||||
{
|
{
|
||||||
if (y == -1)
|
if (m_cursorYPosition == -1)
|
||||||
{
|
{
|
||||||
WriteLocalText(text, level);
|
WriteLocalText(text, level);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = SetCursorTop(y);
|
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
|
||||||
SetCursorLeft(0);
|
SetCursorLeft(0);
|
||||||
|
|
||||||
int count = cmdline.Length + prompt.Length;
|
int count = m_commandLine.Length + prompt.Length;
|
||||||
|
|
||||||
while (count-- > 0)
|
while (count-- > 0)
|
||||||
System.Console.Write(" ");
|
System.Console.Write(" ");
|
||||||
|
|
||||||
y = SetCursorTop(y);
|
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
|
||||||
SetCursorLeft(0);
|
SetCursorLeft(0);
|
||||||
|
|
||||||
WriteLocalText(text, level);
|
WriteLocalText(text, level);
|
||||||
|
|
||||||
y = System.Console.CursorTop;
|
m_cursorYPosition = System.Console.CursorTop;
|
||||||
|
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
@ -347,9 +345,9 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
private bool ContextHelp()
|
private bool ContextHelp()
|
||||||
{
|
{
|
||||||
string[] words = Parser.Parse(cmdline.ToString());
|
string[] words = Parser.Parse(m_commandLine.ToString());
|
||||||
|
|
||||||
bool trailingSpace = cmdline.ToString().EndsWith(" ");
|
bool trailingSpace = m_commandLine.ToString().EndsWith(" ");
|
||||||
|
|
||||||
// Allow ? through while typing a URI
|
// Allow ? through while typing a URI
|
||||||
//
|
//
|
||||||
|
@ -368,19 +366,18 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
public override string ReadLine(string p, bool isCommand, bool e)
|
public override string ReadLine(string p, bool isCommand, bool e)
|
||||||
{
|
{
|
||||||
h = 1;
|
m_cursorXPosition = 0;
|
||||||
cp = 0;
|
|
||||||
prompt = p;
|
prompt = p;
|
||||||
echo = e;
|
m_echo = e;
|
||||||
int historyLine = history.Count;
|
int historyLine = m_history.Count;
|
||||||
|
|
||||||
SetCursorLeft(0); // Needed for mono
|
SetCursorLeft(0); // Needed for mono
|
||||||
System.Console.Write(" "); // Needed for mono
|
System.Console.Write(" "); // Needed for mono
|
||||||
|
|
||||||
lock (cmdline)
|
lock (m_commandLine)
|
||||||
{
|
{
|
||||||
y = System.Console.CursorTop;
|
m_cursorYPosition = System.Console.CursorTop;
|
||||||
cmdline.Remove(0, cmdline.Length);
|
m_commandLine.Remove(0, m_commandLine.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -388,92 +385,95 @@ namespace OpenSim.Framework.Console
|
||||||
Show();
|
Show();
|
||||||
|
|
||||||
ConsoleKeyInfo key = System.Console.ReadKey(true);
|
ConsoleKeyInfo key = System.Console.ReadKey(true);
|
||||||
char c = key.KeyChar;
|
char enteredChar = key.KeyChar;
|
||||||
|
|
||||||
if (!Char.IsControl(c))
|
if (!Char.IsControl(enteredChar))
|
||||||
{
|
{
|
||||||
if (cp >= 318)
|
if (m_cursorXPosition >= 318)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (c == '?' && isCommand)
|
if (enteredChar == '?' && isCommand)
|
||||||
{
|
{
|
||||||
if (ContextHelp())
|
if (ContextHelp())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdline.Insert(cp, c);
|
m_commandLine.Insert(m_cursorXPosition, enteredChar);
|
||||||
cp++;
|
m_cursorXPosition++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (key.Key)
|
switch (key.Key)
|
||||||
{
|
{
|
||||||
case ConsoleKey.Backspace:
|
case ConsoleKey.Backspace:
|
||||||
if (cp == 0)
|
if (m_cursorXPosition == 0)
|
||||||
break;
|
break;
|
||||||
cmdline.Remove(cp-1, 1);
|
m_commandLine.Remove(m_cursorXPosition-1, 1);
|
||||||
cp--;
|
m_cursorXPosition--;
|
||||||
|
|
||||||
SetCursorLeft(0);
|
SetCursorLeft(0);
|
||||||
y = SetCursorTop(y);
|
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
|
||||||
|
|
||||||
System.Console.Write("{0}{1} ", prompt, cmdline);
|
if (m_echo)
|
||||||
|
System.Console.Write("{0}{1} ", prompt, m_commandLine);
|
||||||
|
else
|
||||||
|
System.Console.Write("{0}", prompt);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.End:
|
case ConsoleKey.End:
|
||||||
cp = cmdline.Length;
|
m_cursorXPosition = m_commandLine.Length;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.Home:
|
case ConsoleKey.Home:
|
||||||
cp = 0;
|
m_cursorXPosition = 0;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.UpArrow:
|
case ConsoleKey.UpArrow:
|
||||||
if (historyLine < 1)
|
if (historyLine < 1)
|
||||||
break;
|
break;
|
||||||
historyLine--;
|
historyLine--;
|
||||||
LockOutput();
|
LockOutput();
|
||||||
cmdline.Remove(0, cmdline.Length);
|
m_commandLine.Remove(0, m_commandLine.Length);
|
||||||
cmdline.Append(history[historyLine]);
|
m_commandLine.Append(m_history[historyLine]);
|
||||||
cp = cmdline.Length;
|
m_cursorXPosition = m_commandLine.Length;
|
||||||
UnlockOutput();
|
UnlockOutput();
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.DownArrow:
|
case ConsoleKey.DownArrow:
|
||||||
if (historyLine >= history.Count)
|
if (historyLine >= m_history.Count)
|
||||||
break;
|
break;
|
||||||
historyLine++;
|
historyLine++;
|
||||||
LockOutput();
|
LockOutput();
|
||||||
if (historyLine == history.Count)
|
if (historyLine == m_history.Count)
|
||||||
{
|
{
|
||||||
cmdline.Remove(0, cmdline.Length);
|
m_commandLine.Remove(0, m_commandLine.Length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmdline.Remove(0, cmdline.Length);
|
m_commandLine.Remove(0, m_commandLine.Length);
|
||||||
cmdline.Append(history[historyLine]);
|
m_commandLine.Append(m_history[historyLine]);
|
||||||
}
|
}
|
||||||
cp = cmdline.Length;
|
m_cursorXPosition = m_commandLine.Length;
|
||||||
UnlockOutput();
|
UnlockOutput();
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.LeftArrow:
|
case ConsoleKey.LeftArrow:
|
||||||
if (cp > 0)
|
if (m_cursorXPosition > 0)
|
||||||
cp--;
|
m_cursorXPosition--;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.RightArrow:
|
case ConsoleKey.RightArrow:
|
||||||
if (cp < cmdline.Length)
|
if (m_cursorXPosition < m_commandLine.Length)
|
||||||
cp++;
|
m_cursorXPosition++;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.Enter:
|
case ConsoleKey.Enter:
|
||||||
SetCursorLeft(0);
|
SetCursorLeft(0);
|
||||||
y = SetCursorTop(y);
|
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
|
||||||
|
|
||||||
System.Console.WriteLine();
|
System.Console.WriteLine();
|
||||||
//Show();
|
//Show();
|
||||||
|
|
||||||
lock (cmdline)
|
lock (m_commandLine)
|
||||||
{
|
{
|
||||||
y = -1;
|
m_cursorYPosition = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
string commandLine = cmdline.ToString();
|
string commandLine = m_commandLine.ToString();
|
||||||
|
|
||||||
if (isCommand)
|
if (isCommand)
|
||||||
{
|
{
|
||||||
|
@ -481,12 +481,12 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
if (cmd.Length != 0)
|
if (cmd.Length != 0)
|
||||||
{
|
{
|
||||||
int i;
|
int index;
|
||||||
|
|
||||||
for (i=0 ; i < cmd.Length ; i++)
|
for (index=0 ; index < cmd.Length ; index++)
|
||||||
{
|
{
|
||||||
if (cmd[i].Contains(" "))
|
if (cmd[index].Contains(" "))
|
||||||
cmd[i] = "\"" + cmd[i] + "\"";
|
cmd[index] = "\"" + cmd[index] + "\"";
|
||||||
}
|
}
|
||||||
AddToHistory(String.Join(" ", cmd));
|
AddToHistory(String.Join(" ", cmd));
|
||||||
return String.Empty;
|
return String.Empty;
|
||||||
|
@ -494,7 +494,7 @@ namespace OpenSim.Framework.Console
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're not echoing to screen (e.g. a password) then we probably don't want it in history
|
// If we're not echoing to screen (e.g. a password) then we probably don't want it in history
|
||||||
if (echo && commandLine != "")
|
if (m_echo && commandLine != "")
|
||||||
AddToHistory(commandLine);
|
AddToHistory(commandLine);
|
||||||
|
|
||||||
return commandLine;
|
return commandLine;
|
||||||
|
|
|
@ -935,7 +935,7 @@ namespace OpenSim.Framework
|
||||||
event ScriptReset OnScriptReset;
|
event ScriptReset OnScriptReset;
|
||||||
event GetScriptRunning OnGetScriptRunning;
|
event GetScriptRunning OnGetScriptRunning;
|
||||||
event SetScriptRunning OnSetScriptRunning;
|
event SetScriptRunning OnSetScriptRunning;
|
||||||
event Action<Vector3, bool> OnAutoPilotGo;
|
event Action<Vector3, bool, bool> OnAutoPilotGo;
|
||||||
|
|
||||||
event TerrainUnacked OnUnackedTerrain;
|
event TerrainUnacked OnUnackedTerrain;
|
||||||
event ActivateGesture OnActivateGesture;
|
event ActivateGesture OnActivateGesture;
|
||||||
|
|
|
@ -1372,11 +1372,30 @@ namespace OpenSim.Framework
|
||||||
return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
|
return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">
|
||||||
|
/// If null or empty, then an bytes[0] is returned.
|
||||||
|
/// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
|
||||||
|
/// </param>
|
||||||
|
/// <param name="args">
|
||||||
|
/// Arguments to substitute into the string via the {} mechanism.
|
||||||
|
/// </param>
|
||||||
|
/// <returns></returns>
|
||||||
public static byte[] StringToBytes256(string str, params object[] args)
|
public static byte[] StringToBytes256(string str, params object[] args)
|
||||||
{
|
{
|
||||||
return StringToBytes256(string.Format(str, args));
|
return StringToBytes256(string.Format(str, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">
|
||||||
|
/// If null or empty, then an bytes[0] is returned.
|
||||||
|
/// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
|
||||||
|
/// </param>
|
||||||
|
/// <returns></returns>
|
||||||
public static byte[] StringToBytes256(string str)
|
public static byte[] StringToBytes256(string str)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
|
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
|
||||||
|
@ -1395,11 +1414,30 @@ namespace OpenSim.Framework
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 1024 bytes if necessary.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">
|
||||||
|
/// If null or empty, then an bytes[0] is returned.
|
||||||
|
/// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
|
||||||
|
/// </param>
|
||||||
|
/// <param name="args">
|
||||||
|
/// Arguments to substitute into the string via the {} mechanism.
|
||||||
|
/// </param>
|
||||||
|
/// <returns></returns>
|
||||||
public static byte[] StringToBytes1024(string str, params object[] args)
|
public static byte[] StringToBytes1024(string str, params object[] args)
|
||||||
{
|
{
|
||||||
return StringToBytes1024(string.Format(str, args));
|
return StringToBytes1024(string.Format(str, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 1024 bytes if necessary.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">
|
||||||
|
/// If null or empty, then an bytes[0] is returned.
|
||||||
|
/// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
|
||||||
|
/// </param>
|
||||||
|
/// <returns></returns>
|
||||||
public static byte[] StringToBytes1024(string str)
|
public static byte[] StringToBytes1024(string str)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
|
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
|
||||||
|
|
|
@ -269,13 +269,15 @@ namespace OpenSim
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "save oar",
|
m_console.Commands.AddCommand("region", false, "save oar",
|
||||||
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
||||||
"save oar [-p|--profile=<url>] [--noassets] [<OAR path>]",
|
"save oar [-p|--profile=<url>] [--noassets] [--perm=<permissions>] [<OAR path>]",
|
||||||
"Save a region's data to an OAR archive.",
|
"Save a region's data to an OAR archive.",
|
||||||
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
|
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
|
||||||
"-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
"-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
||||||
+ " The OAR path must be a filesystem path."
|
+ "--noassets stops assets being saved to the OAR." + Environment.NewLine
|
||||||
+ " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine
|
+ "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine
|
||||||
+ "--noassets stops assets being saved to the OAR.",
|
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine
|
||||||
|
+ "The OAR path must be a filesystem path."
|
||||||
|
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
||||||
SaveOar);
|
SaveOar);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "edit scale",
|
m_console.Commands.AddCommand("region", false, "edit scale",
|
||||||
|
|
|
@ -41,11 +41,15 @@ using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Framework.Statistics;
|
using OpenSim.Framework.Statistics;
|
||||||
using OpenSim.Region.ClientStack;
|
using OpenSim.Region.ClientStack;
|
||||||
|
using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
|
||||||
using OpenSim.Region.Framework;
|
using OpenSim.Region.Framework;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Services.UserAccountService;
|
||||||
|
|
||||||
namespace OpenSim
|
namespace OpenSim
|
||||||
{
|
{
|
||||||
|
@ -362,6 +366,9 @@ namespace OpenSim
|
||||||
|
|
||||||
scene.SetModuleInterfaces();
|
scene.SetModuleInterfaces();
|
||||||
|
|
||||||
|
while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
|
||||||
|
SetUpEstateOwner(scene);
|
||||||
|
|
||||||
// Prims have to be loaded after module configuration since some modules may be invoked during the load
|
// Prims have to be loaded after module configuration since some modules may be invoked during the load
|
||||||
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
|
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
|
||||||
|
|
||||||
|
@ -411,9 +418,69 @@ namespace OpenSim
|
||||||
|
|
||||||
scene.StartTimer();
|
scene.StartTimer();
|
||||||
|
|
||||||
|
scene.StartScripts();
|
||||||
|
|
||||||
return clientServer;
|
return clientServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to set up the estate owner for the given scene.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The involves asking the user for information about the user on the console. If the user does not already
|
||||||
|
/// exist then it is created.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="scene"></param>
|
||||||
|
private void SetUpEstateOwner(Scene scene)
|
||||||
|
{
|
||||||
|
RegionInfo regionInfo = scene.RegionInfo;
|
||||||
|
|
||||||
|
MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
|
||||||
|
List<char> excluded = new List<char>(new char[1]{' '});
|
||||||
|
string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
|
||||||
|
string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
|
||||||
|
|
||||||
|
UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last);
|
||||||
|
|
||||||
|
if (account == null)
|
||||||
|
{
|
||||||
|
|
||||||
|
// XXX: The LocalUserAccountServicesConnector is currently registering its inner service rather than
|
||||||
|
// itself!
|
||||||
|
// if (scene.UserAccountService is LocalUserAccountServicesConnector)
|
||||||
|
// {
|
||||||
|
// IUserAccountService innerUas
|
||||||
|
// = ((LocalUserAccountServicesConnector)scene.UserAccountService).UserAccountService;
|
||||||
|
//
|
||||||
|
// m_log.DebugFormat("B {0}", innerUas.GetType());
|
||||||
|
//
|
||||||
|
// if (innerUas is UserAccountService)
|
||||||
|
// {
|
||||||
|
|
||||||
|
if (scene.UserAccountService is UserAccountService)
|
||||||
|
{
|
||||||
|
string password = MainConsole.Instance.PasswdPrompt("Password");
|
||||||
|
string email = MainConsole.Instance.CmdPrompt("Email", "");
|
||||||
|
|
||||||
|
account
|
||||||
|
= ((UserAccountService)scene.UserAccountService).CreateUser(
|
||||||
|
regionInfo.ScopeID, first, last, password, email);
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account == null)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat(
|
||||||
|
"[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regionInfo.EstateSettings.EstateOwner = account.PrincipalID;
|
||||||
|
regionInfo.EstateSettings.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ShutdownRegion(Scene scene)
|
private void ShutdownRegion(Scene scene)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);
|
m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);
|
||||||
|
|
|
@ -231,7 +231,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public event ScriptReset OnScriptReset;
|
public event ScriptReset OnScriptReset;
|
||||||
public event GetScriptRunning OnGetScriptRunning;
|
public event GetScriptRunning OnGetScriptRunning;
|
||||||
public event SetScriptRunning OnSetScriptRunning;
|
public event SetScriptRunning OnSetScriptRunning;
|
||||||
public event Action<Vector3, bool> OnAutoPilotGo;
|
public event Action<Vector3, bool, bool> OnAutoPilotGo;
|
||||||
public event TerrainUnacked OnUnackedTerrain;
|
public event TerrainUnacked OnUnackedTerrain;
|
||||||
public event ActivateGesture OnActivateGesture;
|
public event ActivateGesture OnActivateGesture;
|
||||||
public event DeactivateGesture OnDeactivateGesture;
|
public event DeactivateGesture OnDeactivateGesture;
|
||||||
|
@ -4119,8 +4119,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
while (updatesThisCall < m_maxUpdates)
|
while (updatesThisCall < m_maxUpdates)
|
||||||
{
|
{
|
||||||
lock (m_entityProps.SyncRoot)
|
lock (m_entityProps.SyncRoot)
|
||||||
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
|
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
|
ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
|
||||||
if (update.SendFamilyProps)
|
if (update.SendFamilyProps)
|
||||||
|
@ -11640,9 +11640,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
locy = Convert.ToSingle(args[1]) - (float)regionY;
|
locy = Convert.ToSingle(args[1]) - (float)regionY;
|
||||||
locz = Convert.ToSingle(args[2]);
|
locz = Convert.ToSingle(args[2]);
|
||||||
|
|
||||||
Action<Vector3, bool> handlerAutoPilotGo = OnAutoPilotGo;
|
Action<Vector3, bool, bool> handlerAutoPilotGo = OnAutoPilotGo;
|
||||||
if (handlerAutoPilotGo != null)
|
if (handlerAutoPilotGo != null)
|
||||||
handlerAutoPilotGo(new Vector3(locx, locy, locz), false);
|
handlerAutoPilotGo(new Vector3(locx, locy, locz), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -41,14 +41,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AgentAssetTransactions
|
public class AgentAssetTransactions
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
private bool m_dumpAssetsToFile;
|
private bool m_dumpAssetsToFile;
|
||||||
private Scene m_Scene;
|
private Scene m_Scene;
|
||||||
public UUID UserID;
|
private UUID UserID;
|
||||||
public Dictionary<UUID, AssetXferUploader> XferUploaders =
|
private Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>();
|
||||||
new Dictionary<UUID, AssetXferUploader>();
|
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
public AgentAssetTransactions(UUID agentID, Scene scene,
|
public AgentAssetTransactions(UUID agentID, Scene scene,
|
||||||
|
@ -59,36 +58,94 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
m_dumpAssetsToFile = dumpAssetsToFile;
|
m_dumpAssetsToFile = dumpAssetsToFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssetXferUploader RequestXferUploader(UUID transactionID)
|
/// <summary>
|
||||||
|
/// Return a xfer uploader if one does not already exist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transactionID"></param>
|
||||||
|
/// <param name="assetID">
|
||||||
|
/// We must transfer the new asset ID into the uploader on creation, otherwise
|
||||||
|
/// we can see race conditions with other threads which can retrieve an item before it is updated with the new
|
||||||
|
/// asset id.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// The xfer uploader requested. Null if one is already in existence.
|
||||||
|
/// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple
|
||||||
|
/// transfers are made. Needs to be corrected.
|
||||||
|
/// </returns>
|
||||||
|
public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID)
|
||||||
{
|
{
|
||||||
if (!XferUploaders.ContainsKey(transactionID))
|
lock (XferUploaders)
|
||||||
{
|
{
|
||||||
AssetXferUploader uploader = new AssetXferUploader(m_Scene,
|
if (!XferUploaders.ContainsKey(transactionID))
|
||||||
m_dumpAssetsToFile);
|
|
||||||
|
|
||||||
lock (XferUploaders)
|
|
||||||
{
|
{
|
||||||
XferUploaders.Add(transactionID, uploader);
|
AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile);
|
||||||
}
|
|
||||||
|
|
||||||
return uploader;
|
// m_log.DebugFormat(
|
||||||
|
// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID);
|
||||||
|
|
||||||
|
XferUploaders.Add(transactionID, uploader);
|
||||||
|
|
||||||
|
return uploader;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleXfer(ulong xferID, uint packetID, byte[] data)
|
public void HandleXfer(ulong xferID, uint packetID, byte[] data)
|
||||||
{
|
{
|
||||||
|
AssetXferUploader foundUploader = null;
|
||||||
|
|
||||||
lock (XferUploaders)
|
lock (XferUploaders)
|
||||||
{
|
{
|
||||||
foreach (AssetXferUploader uploader in XferUploaders.Values)
|
foreach (AssetXferUploader uploader in XferUploaders.Values)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[AGENT ASSETS TRANSACTIONS]: In HandleXfer, inspect xfer upload with xfer id {0}",
|
||||||
|
// uploader.XferID);
|
||||||
|
|
||||||
if (uploader.XferID == xferID)
|
if (uploader.XferID == xferID)
|
||||||
{
|
{
|
||||||
uploader.HandleXferPacket(xferID, packetID, data);
|
foundUploader = uploader;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (foundUploader != null)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[AGENT ASSETS TRANSACTIONS]: Found xfer uploader for xfer id {0}, packet id {1}, data length {2}",
|
||||||
|
// xferID, packetID, data.Length);
|
||||||
|
|
||||||
|
foundUploader.HandleXferPacket(xferID, packetID, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat(
|
||||||
|
"[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}",
|
||||||
|
xferID, packetID, data.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemoveXferUploader(UUID transactionID)
|
||||||
|
{
|
||||||
|
lock (XferUploaders)
|
||||||
|
{
|
||||||
|
bool removed = XferUploaders.Remove(transactionID);
|
||||||
|
|
||||||
|
if (!removed)
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[AGENT ASSET TRANSACTIONS]: Received request to remove xfer uploader with transaction ID {0} but none found",
|
||||||
|
transactionID);
|
||||||
|
// else
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[AGENT ASSET TRANSACTIONS]: Removed xfer uploader with transaction ID {0}", transactionID);
|
||||||
|
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestCreateInventoryItem(IClientAPI remoteClient,
|
public void RequestCreateInventoryItem(IClientAPI remoteClient,
|
||||||
|
@ -96,36 +153,43 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
string description, string name, sbyte invType,
|
string description, string name, sbyte invType,
|
||||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||||
{
|
{
|
||||||
if (XferUploaders.ContainsKey(transactionID))
|
AssetXferUploader uploader = null;
|
||||||
|
|
||||||
|
lock (XferUploaders)
|
||||||
{
|
{
|
||||||
XferUploaders[transactionID].RequestCreateInventoryItem(
|
if (XferUploaders.ContainsKey(transactionID))
|
||||||
remoteClient, transactionID, folderID,
|
uploader = XferUploaders[transactionID];
|
||||||
callbackID, description, name, invType, type,
|
|
||||||
wearableType, nextOwnerMask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uploader != null)
|
||||||
|
uploader.RequestCreateInventoryItem(
|
||||||
|
remoteClient, transactionID, folderID,
|
||||||
|
callbackID, description, name, invType, type,
|
||||||
|
wearableType, nextOwnerMask);
|
||||||
|
else
|
||||||
|
m_log.ErrorFormat(
|
||||||
|
"[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}",
|
||||||
|
transactionID, name, remoteClient.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get an uploaded asset. If the data is successfully retrieved,
|
/// Get an uploaded asset. If the data is successfully retrieved,
|
||||||
/// the transaction will be removed.
|
/// the transaction will be removed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="transactionID"></param>
|
/// <param name="transactionID"></param>
|
||||||
/// <returns>The asset if the upload has completed, null if it has not.</returns>
|
/// <returns>The asset if the upload has completed, null if it has not.</returns>
|
||||||
public AssetBase GetTransactionAsset(UUID transactionID)
|
private AssetBase GetTransactionAsset(UUID transactionID)
|
||||||
{
|
{
|
||||||
if (XferUploaders.ContainsKey(transactionID))
|
lock (XferUploaders)
|
||||||
{
|
{
|
||||||
AssetXferUploader uploader = XferUploaders[transactionID];
|
if (XferUploaders.ContainsKey(transactionID))
|
||||||
AssetBase asset = uploader.GetAssetData();
|
|
||||||
|
|
||||||
lock (XferUploaders)
|
|
||||||
{
|
{
|
||||||
XferUploaders.Remove(transactionID);
|
AssetXferUploader uploader = XferUploaders[transactionID];
|
||||||
}
|
AssetBase asset = uploader.GetAssetData();
|
||||||
|
RemoveXferUploader(transactionID);
|
||||||
|
|
||||||
return asset;
|
return asset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -135,7 +199,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
SceneObjectPart part, UUID transactionID,
|
SceneObjectPart part, UUID transactionID,
|
||||||
TaskInventoryItem item)
|
TaskInventoryItem item)
|
||||||
{
|
{
|
||||||
if (XferUploaders.ContainsKey(transactionID))
|
AssetXferUploader uploader = null;
|
||||||
|
|
||||||
|
lock (XferUploaders)
|
||||||
|
{
|
||||||
|
if (XferUploaders.ContainsKey(transactionID))
|
||||||
|
uploader = XferUploaders[transactionID];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uploader != null)
|
||||||
{
|
{
|
||||||
AssetBase asset = GetTransactionAsset(transactionID);
|
AssetBase asset = GetTransactionAsset(transactionID);
|
||||||
|
|
||||||
|
@ -161,28 +233,34 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
m_Scene.AssetService.Store(asset);
|
m_Scene.AssetService.Store(asset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat(
|
||||||
|
"[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}",
|
||||||
|
transactionID, item.Name, part.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestUpdateInventoryItem(IClientAPI remoteClient,
|
public void RequestUpdateInventoryItem(IClientAPI remoteClient,
|
||||||
UUID transactionID, InventoryItemBase item)
|
UUID transactionID, InventoryItemBase item)
|
||||||
{
|
{
|
||||||
if (XferUploaders.ContainsKey(transactionID))
|
AssetXferUploader uploader = null;
|
||||||
|
|
||||||
|
lock (XferUploaders)
|
||||||
{
|
{
|
||||||
AssetBase asset = GetTransactionAsset(transactionID);
|
if (XferUploaders.ContainsKey(transactionID))
|
||||||
|
uploader = XferUploaders[transactionID];
|
||||||
|
}
|
||||||
|
|
||||||
if (asset != null)
|
if (uploader != null)
|
||||||
{
|
{
|
||||||
asset.FullID = UUID.Random();
|
uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item);
|
||||||
asset.Name = item.Name;
|
}
|
||||||
asset.Description = item.Description;
|
else
|
||||||
asset.Type = (sbyte)item.AssetType;
|
{
|
||||||
item.AssetID = asset.FullID;
|
m_log.ErrorFormat(
|
||||||
|
"[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}",
|
||||||
m_Scene.AssetService.Store(asset);
|
transactionID, item.Name, remoteClient.Name);
|
||||||
|
|
||||||
IInventoryService invService = m_Scene.InventoryService;
|
|
||||||
invService.UpdateItem(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,11 +172,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update an inventory item with data that has been received through a
|
/// Update an inventory item with data that has been received through a
|
||||||
/// transaction.
|
/// transaction.
|
||||||
///
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
/// This is called when clothing or body parts are updated (for
|
/// This is called when clothing or body parts are updated (for
|
||||||
/// instance, with new textures or colours). It may also be called in
|
/// instance, with new textures or colours). It may also be called in
|
||||||
/// other situations.
|
/// other situations.
|
||||||
/// </summary>
|
/// </remarks>
|
||||||
/// <param name="remoteClient"></param>
|
/// <param name="remoteClient"></param>
|
||||||
/// <param name="transactionID"></param>
|
/// <param name="transactionID"></param>
|
||||||
/// <param name="item"></param>
|
/// <param name="item"></param>
|
||||||
|
@ -184,14 +185,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
UUID transactionID, InventoryItemBase item)
|
UUID transactionID, InventoryItemBase item)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
|
// "[ASSET TRANSACTION MODULE]: Called HandleItemUpdateFromTransaction with item {0}",
|
||||||
// item.Name);
|
// item.Name);
|
||||||
|
|
||||||
AgentAssetTransactions transactions =
|
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||||
GetUserTransactions(remoteClient.AgentId);
|
|
||||||
|
|
||||||
transactions.RequestUpdateInventoryItem(remoteClient,
|
transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
|
||||||
transactionID, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -255,11 +254,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AgentAssetTransactions transactions =
|
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||||
GetUserTransactions(remoteClient.AgentId);
|
AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID);
|
||||||
|
|
||||||
AssetXferUploader uploader =
|
|
||||||
transactions.RequestXferUploader(transaction);
|
|
||||||
|
|
||||||
if (uploader != null)
|
if (uploader != null)
|
||||||
{
|
{
|
||||||
|
@ -279,9 +275,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
public void HandleXfer(IClientAPI remoteClient, ulong xferID,
|
public void HandleXfer(IClientAPI remoteClient, ulong xferID,
|
||||||
uint packetID, byte[] data)
|
uint packetID, byte[] data)
|
||||||
{
|
{
|
||||||
//m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!");
|
// m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data length " + data.Length);
|
||||||
AgentAssetTransactions transactions =
|
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||||
GetUserTransactions(remoteClient.AgentId);
|
|
||||||
|
|
||||||
transactions.HandleXfer(xferID, packetID, data);
|
transactions.HandleXfer(xferID, packetID, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
|
||||||
|
/// are performing a delayed update.
|
||||||
|
/// </summary>
|
||||||
|
AgentAssetTransactions m_transactions;
|
||||||
|
|
||||||
private AssetBase m_asset;
|
private AssetBase m_asset;
|
||||||
private UUID InventFolder = UUID.Zero;
|
private UUID InventFolder = UUID.Zero;
|
||||||
private sbyte invType = 0;
|
private sbyte invType = 0;
|
||||||
|
|
||||||
private bool m_createItem = false;
|
private bool m_createItem = false;
|
||||||
private uint m_createItemCallback = 0;
|
private uint m_createItemCallback = 0;
|
||||||
|
private bool m_updateItem = false;
|
||||||
|
private InventoryItemBase m_updateItemData;
|
||||||
|
|
||||||
private string m_description = String.Empty;
|
private string m_description = String.Empty;
|
||||||
private bool m_dumpAssetToFile;
|
private bool m_dumpAssetToFile;
|
||||||
private bool m_finished = false;
|
private bool m_finished = false;
|
||||||
|
@ -58,9 +68,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
public ulong XferID;
|
public ulong XferID;
|
||||||
private Scene m_Scene;
|
private Scene m_Scene;
|
||||||
|
|
||||||
public AssetXferUploader(Scene scene, bool dumpAssetToFile)
|
public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile)
|
||||||
{
|
{
|
||||||
|
m_transactions = transactions;
|
||||||
m_Scene = scene;
|
m_Scene = scene;
|
||||||
|
m_asset = new AssetBase() { FullID = assetID };
|
||||||
m_dumpAssetToFile = dumpAssetToFile;
|
m_dumpAssetToFile = dumpAssetToFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +85,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
/// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
|
/// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
|
||||||
public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
|
public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})",
|
||||||
|
// packetID, xferID, data.Length);
|
||||||
|
|
||||||
if (XferID == xferID)
|
if (XferID == xferID)
|
||||||
{
|
{
|
||||||
if (m_asset.Data.Length > 1)
|
if (m_asset.Data.Length > 1)
|
||||||
|
@ -107,16 +123,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
/// <param name="xferID"></param>
|
/// <param name="xferID"></param>
|
||||||
/// <param name="packetID"></param>
|
/// <param name="packetID"></param>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <returns>True if the transfer is complete, false otherwise</returns>
|
public void Initialise(IClientAPI remoteClient, UUID assetID,
|
||||||
public bool Initialise(IClientAPI remoteClient, UUID assetID,
|
|
||||||
UUID transaction, sbyte type, byte[] data, bool storeLocal,
|
UUID transaction, sbyte type, byte[] data, bool storeLocal,
|
||||||
bool tempFile)
|
bool tempFile)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}",
|
||||||
|
// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length);
|
||||||
|
|
||||||
ourClient = remoteClient;
|
ourClient = remoteClient;
|
||||||
m_asset = new AssetBase(assetID, "blank", type,
|
m_asset.Name = "blank";
|
||||||
remoteClient.AgentId.ToString());
|
|
||||||
m_asset.Data = data;
|
|
||||||
m_asset.Description = "empty";
|
m_asset.Description = "empty";
|
||||||
|
m_asset.Type = type;
|
||||||
|
m_asset.CreatorID = remoteClient.AgentId.ToString();
|
||||||
|
m_asset.Data = data;
|
||||||
m_asset.Local = storeLocal;
|
m_asset.Local = storeLocal;
|
||||||
m_asset.Temporary = tempFile;
|
m_asset.Temporary = tempFile;
|
||||||
|
|
||||||
|
@ -126,21 +146,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
if (m_asset.Data.Length > 2)
|
if (m_asset.Data.Length > 2)
|
||||||
{
|
{
|
||||||
SendCompleteMessage();
|
SendCompleteMessage();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RequestStartXfer();
|
RequestStartXfer();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RequestStartXfer()
|
protected void RequestStartXfer()
|
||||||
{
|
{
|
||||||
XferID = Util.GetNextXferID();
|
XferID = Util.GetNextXferID();
|
||||||
ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID,
|
|
||||||
0, new byte[0]);
|
// m_log.DebugFormat(
|
||||||
|
// "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}",
|
||||||
|
// m_asset.FullID, m_asset.Type, XferID, ourClient.Name);
|
||||||
|
|
||||||
|
ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SendCompleteMessage()
|
protected void SendCompleteMessage()
|
||||||
|
@ -148,18 +169,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
|
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
|
||||||
m_asset.FullID);
|
m_asset.FullID);
|
||||||
|
|
||||||
m_finished = true;
|
// We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
|
||||||
if (m_createItem)
|
// message from other client UDP.
|
||||||
|
lock (this)
|
||||||
{
|
{
|
||||||
DoCreateItem(m_createItemCallback);
|
m_finished = true;
|
||||||
}
|
if (m_createItem)
|
||||||
else if (m_storeLocal)
|
{
|
||||||
{
|
DoCreateItem(m_createItemCallback);
|
||||||
m_Scene.AssetService.Store(m_asset);
|
}
|
||||||
|
else if (m_updateItem)
|
||||||
|
{
|
||||||
|
StoreAssetForItemUpdate(m_updateItemData);
|
||||||
|
|
||||||
|
// Remove ourselves from the list of transactions if completion was delayed until the transaction
|
||||||
|
// was complete.
|
||||||
|
// TODO: Should probably do the same for create item.
|
||||||
|
m_transactions.RemoveXferUploader(TransactionID);
|
||||||
|
}
|
||||||
|
else if (m_storeLocal)
|
||||||
|
{
|
||||||
|
m_Scene.AssetService.Store(m_asset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}",
|
"[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
|
||||||
m_asset.FullID, TransactionID);
|
m_asset.FullID, TransactionID);
|
||||||
|
|
||||||
if (m_dumpAssetToFile)
|
if (m_dumpAssetToFile)
|
||||||
|
@ -205,18 +240,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
m_asset.Description = description;
|
m_asset.Description = description;
|
||||||
m_asset.Type = type;
|
m_asset.Type = type;
|
||||||
|
|
||||||
|
// We must lock to avoid a race with a separate thread uploading the asset.
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
if (m_finished)
|
||||||
|
{
|
||||||
|
DoCreateItem(callbackID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_createItem = true; //set flag so the inventory item is created when upload is complete
|
||||||
|
m_createItemCallback = callbackID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item)
|
||||||
|
{
|
||||||
|
// We must lock to avoid a race with a separate thread uploading the asset.
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
m_asset.Name = item.Name;
|
||||||
|
m_asset.Description = item.Description;
|
||||||
|
m_asset.Type = (sbyte)item.AssetType;
|
||||||
|
|
||||||
|
// We must always store the item at this point even if the asset hasn't finished uploading, in order
|
||||||
|
// to avoid a race condition when the appearance module retrieves the item to set the asset id in
|
||||||
|
// the AvatarAppearance structure.
|
||||||
|
item.AssetID = m_asset.FullID;
|
||||||
|
m_Scene.InventoryService.UpdateItem(item);
|
||||||
|
|
||||||
if (m_finished)
|
if (m_finished)
|
||||||
{
|
{
|
||||||
DoCreateItem(callbackID);
|
StoreAssetForItemUpdate(item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_createItem = true; //set flag so the inventory item is created when upload is complete
|
// m_log.DebugFormat(
|
||||||
m_createItemCallback = callbackID;
|
// "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}",
|
||||||
|
// item.Name, remoteClient.Name, transactionID);
|
||||||
|
|
||||||
|
m_updateItem = true;
|
||||||
|
m_updateItemData = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Store the asset for the given item.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
private void StoreAssetForItemUpdate(InventoryItemBase item)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
|
||||||
|
// m_asset.FullID, item.Name, ourClient.Name);
|
||||||
|
|
||||||
|
m_Scene.AssetService.Store(m_asset);
|
||||||
|
}
|
||||||
|
|
||||||
private void DoCreateItem(uint callbackID)
|
private void DoCreateItem(uint callbackID)
|
||||||
{
|
{
|
||||||
m_Scene.AssetService.Store(m_asset);
|
m_Scene.AssetService.Store(m_asset);
|
||||||
|
|
|
@ -143,20 +143,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
|
|
||||||
public void SaveChangedAttachments(IScenePresence sp)
|
public void SaveChangedAttachments(IScenePresence sp)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
|
||||||
|
|
||||||
foreach (SceneObjectGroup grp in sp.GetAttachments())
|
foreach (SceneObjectGroup grp in sp.GetAttachments())
|
||||||
{
|
{
|
||||||
if (grp.HasGroupChanged) // Resizer scripts?
|
// if (grp.HasGroupChanged) // Resizer scripts?
|
||||||
{
|
// {
|
||||||
grp.IsAttachment = false;
|
grp.IsAttachment = false;
|
||||||
grp.AbsolutePosition = grp.RootPart.AttachedPos;
|
grp.AbsolutePosition = grp.RootPart.AttachedPos;
|
||||||
UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID);
|
UpdateKnownItem(sp.ControllingClient, grp);
|
||||||
grp.IsAttachment = true;
|
grp.IsAttachment = true;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
|
public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
|
||||||
|
// m_scene.RegionInfo.RegionName, sp.Name, silent);
|
||||||
|
|
||||||
foreach (SceneObjectGroup sop in sp.GetAttachments())
|
foreach (SceneObjectGroup sop in sp.GetAttachments())
|
||||||
{
|
{
|
||||||
sop.Scene.DeleteSceneObject(sop, silent);
|
sop.Scene.DeleteSceneObject(sop, silent);
|
||||||
|
@ -212,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
||||||
|
|
||||||
// Save avatar attachment information
|
// Save avatar attachment information
|
||||||
m_log.Info(
|
m_log.Debug(
|
||||||
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
||||||
+ ", AttachmentPoint: " + AttachmentPt);
|
+ ", AttachmentPoint: " + AttachmentPt);
|
||||||
|
|
||||||
|
@ -240,80 +246,83 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
|
|
||||||
private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
|
private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
lock (sp.AttachmentsSyncLock)
|
||||||
// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
|
|
||||||
// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
|
|
||||||
|
|
||||||
if (sp.GetAttachments(attachmentPt).Contains(group))
|
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat(
|
// m_log.DebugFormat(
|
||||||
// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
|
// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
|
||||||
// group.Name, group.LocalId, sp.Name, AttachmentPt);
|
// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
|
||||||
|
|
||||||
return false;
|
if (sp.GetAttachments(attachmentPt).Contains(group))
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 attachPos = group.AbsolutePosition;
|
|
||||||
|
|
||||||
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
|
||||||
// be removed when that functionality is implemented in opensim
|
|
||||||
attachmentPt &= 0x7f;
|
|
||||||
|
|
||||||
// If the attachment point isn't the same as the one previously used
|
|
||||||
// set it's offset position = 0 so that it appears on the attachment point
|
|
||||||
// and not in a weird location somewhere unknown.
|
|
||||||
if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
|
|
||||||
{
|
|
||||||
attachPos = Vector3.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
// AttachmentPt 0 means the client chose to 'wear' the attachment.
|
|
||||||
if (attachmentPt == 0)
|
|
||||||
{
|
|
||||||
// Check object for stored attachment point
|
|
||||||
attachmentPt = group.AttachmentPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we still didn't find a suitable attachment point.......
|
|
||||||
if (attachmentPt == 0)
|
|
||||||
{
|
|
||||||
// Stick it on left hand with Zero Offset from the attachment point.
|
|
||||||
attachmentPt = (uint)AttachmentPoint.LeftHand;
|
|
||||||
attachPos = Vector3.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
group.AttachmentPoint = attachmentPt;
|
|
||||||
group.AbsolutePosition = attachPos;
|
|
||||||
|
|
||||||
// We also don't want to do any of the inventory operations for an NPC.
|
|
||||||
if (sp.PresenceType != PresenceType.Npc)
|
|
||||||
{
|
|
||||||
// Remove any previous attachments
|
|
||||||
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
|
||||||
|
|
||||||
// At the moment we can only deal with a single attachment
|
|
||||||
if (attachments.Count != 0)
|
|
||||||
{
|
{
|
||||||
UUID oldAttachmentItemID = attachments[0].GetFromItemID();
|
// m_log.WarnFormat(
|
||||||
|
// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
|
||||||
|
// group.Name, group.LocalId, sp.Name, AttachmentPt);
|
||||||
|
|
||||||
if (oldAttachmentItemID != UUID.Zero)
|
return false;
|
||||||
DetachSingleAttachmentToInv(oldAttachmentItemID, sp);
|
|
||||||
else
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
|
||||||
attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the new attachment to inventory if we don't already have it.
|
|
||||||
UUID newAttachmentItemID = group.GetFromItemID();
|
|
||||||
if (newAttachmentItemID == UUID.Zero)
|
|
||||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID;
|
|
||||||
|
|
||||||
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
Vector3 attachPos = group.AbsolutePosition;
|
||||||
|
|
||||||
|
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
||||||
|
// be removed when that functionality is implemented in opensim
|
||||||
|
attachmentPt &= 0x7f;
|
||||||
|
|
||||||
|
// If the attachment point isn't the same as the one previously used
|
||||||
|
// set it's offset position = 0 so that it appears on the attachment point
|
||||||
|
// and not in a weird location somewhere unknown.
|
||||||
|
if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
|
||||||
|
{
|
||||||
|
attachPos = Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttachmentPt 0 means the client chose to 'wear' the attachment.
|
||||||
|
if (attachmentPt == 0)
|
||||||
|
{
|
||||||
|
// Check object for stored attachment point
|
||||||
|
attachmentPt = group.AttachmentPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we still didn't find a suitable attachment point.......
|
||||||
|
if (attachmentPt == 0)
|
||||||
|
{
|
||||||
|
// Stick it on left hand with Zero Offset from the attachment point.
|
||||||
|
attachmentPt = (uint)AttachmentPoint.LeftHand;
|
||||||
|
attachPos = Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
group.AttachmentPoint = attachmentPt;
|
||||||
|
group.AbsolutePosition = attachPos;
|
||||||
|
|
||||||
|
// We also don't want to do any of the inventory operations for an NPC.
|
||||||
|
if (sp.PresenceType != PresenceType.Npc)
|
||||||
|
{
|
||||||
|
// Remove any previous attachments
|
||||||
|
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
||||||
|
|
||||||
|
// At the moment we can only deal with a single attachment
|
||||||
|
if (attachments.Count != 0)
|
||||||
|
{
|
||||||
|
UUID oldAttachmentItemID = attachments[0].GetFromItemID();
|
||||||
|
|
||||||
|
if (oldAttachmentItemID != UUID.Zero)
|
||||||
|
DetachSingleAttachmentToInv(oldAttachmentItemID, sp);
|
||||||
|
else
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
||||||
|
attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new attachment to inventory if we don't already have it.
|
||||||
|
UUID newAttachmentItemID = group.GetFromItemID();
|
||||||
|
if (newAttachmentItemID == UUID.Zero)
|
||||||
|
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID;
|
||||||
|
|
||||||
|
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,17 +331,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
|
RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
|
||||||
RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects)
|
RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects)
|
||||||
{
|
{
|
||||||
foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
|
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||||
|
|
||||||
|
if (sp == null)
|
||||||
{
|
{
|
||||||
RezSingleAttachmentFromInventory(remoteClient, obj.ItemID, obj.AttachmentPt);
|
m_log.ErrorFormat(
|
||||||
|
"[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
|
||||||
|
remoteClient.Name, remoteClient.AgentId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (sp.AttachmentsSyncLock)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
|
||||||
|
|
||||||
|
foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
|
||||||
|
{
|
||||||
|
RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISceneEntity RezSingleAttachmentFromInventory(
|
public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
|
||||||
IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
|
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}",
|
// "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}",
|
||||||
// (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name);
|
// (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name);
|
||||||
|
|
||||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||||
|
@ -344,11 +367,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
remoteClient.Name, remoteClient.AgentId);
|
remoteClient.Name, remoteClient.AgentId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
|
||||||
|
// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
|
||||||
|
|
||||||
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
||||||
// be removed when that functionality is implemented in opensim
|
// be removed when that functionality is implemented in opensim
|
||||||
AttachmentPt &= 0x7f;
|
AttachmentPt &= 0x7f;
|
||||||
|
|
||||||
|
// Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
|
||||||
|
// This often happens during login - not sure the exact reason.
|
||||||
|
// For now, we will ignore the request. Unfortunately, this means that we need to dig through all the
|
||||||
|
// ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login
|
||||||
|
// before anything has actually been attached.
|
||||||
|
bool alreadyOn = false;
|
||||||
|
List<SceneObjectGroup> existingAttachments = sp.GetAttachments();
|
||||||
|
foreach (SceneObjectGroup so in existingAttachments)
|
||||||
|
{
|
||||||
|
if (so.GetFromItemID() == itemID)
|
||||||
|
{
|
||||||
|
alreadyOn = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (sp.Appearance.GetAttachmentForItem(itemID) != null)
|
||||||
|
if (alreadyOn)
|
||||||
|
{
|
||||||
|
// m_log.WarnFormat(
|
||||||
|
// "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn",
|
||||||
|
// sp.Name, itemID, AttachmentPt);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt);
|
SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt);
|
||||||
|
|
||||||
if (att == null)
|
if (att == null)
|
||||||
|
@ -363,65 +421,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
|
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||||
if (invAccess != null)
|
if (invAccess != null)
|
||||||
{
|
{
|
||||||
SceneObjectGroup objatt;
|
lock (sp.AttachmentsSyncLock)
|
||||||
|
|
||||||
if (itemID != UUID.Zero)
|
|
||||||
objatt = invAccess.RezObject(sp.ControllingClient,
|
|
||||||
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
|
||||||
false, false, sp.UUID, true);
|
|
||||||
else
|
|
||||||
objatt = invAccess.RezObject(sp.ControllingClient,
|
|
||||||
null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
|
||||||
false, false, sp.UUID, true);
|
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
|
|
||||||
// objatt.Name, remoteClient.Name, AttachmentPt);
|
|
||||||
|
|
||||||
if (objatt != null)
|
|
||||||
{
|
{
|
||||||
// HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
|
SceneObjectGroup objatt;
|
||||||
objatt.HasGroupChanged = false;
|
|
||||||
bool tainted = false;
|
if (itemID != UUID.Zero)
|
||||||
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
|
objatt = invAccess.RezObject(sp.ControllingClient,
|
||||||
tainted = true;
|
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||||
|
false, false, sp.UUID, true);
|
||||||
// This will throw if the attachment fails
|
else
|
||||||
try
|
objatt = invAccess.RezObject(sp.ControllingClient,
|
||||||
{
|
null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||||
AttachObject(sp, objatt, attachmentPt, false);
|
false, false, sp.UUID, true);
|
||||||
}
|
|
||||||
catch (Exception e)
|
// m_log.DebugFormat(
|
||||||
{
|
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
|
||||||
m_log.ErrorFormat(
|
// objatt.Name, remoteClient.Name, AttachmentPt);
|
||||||
"[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
|
|
||||||
objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
|
|
||||||
|
|
||||||
// Make sure the object doesn't stick around and bail
|
|
||||||
sp.RemoveAttachment(objatt);
|
|
||||||
m_scene.DeleteSceneObject(objatt, false);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tainted)
|
if (objatt != null)
|
||||||
objatt.HasGroupChanged = true;
|
{
|
||||||
|
// HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
|
||||||
|
objatt.HasGroupChanged = false;
|
||||||
|
bool tainted = false;
|
||||||
|
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
|
||||||
|
tainted = true;
|
||||||
|
|
||||||
|
// This will throw if the attachment fails
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AttachObject(sp, objatt, attachmentPt, false);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat(
|
||||||
|
"[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
|
||||||
|
objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
|
||||||
|
|
||||||
|
// Make sure the object doesn't stick around and bail
|
||||||
|
sp.RemoveAttachment(objatt);
|
||||||
|
m_scene.DeleteSceneObject(objatt, false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tainted)
|
||||||
|
objatt.HasGroupChanged = true;
|
||||||
|
|
||||||
|
// Fire after attach, so we don't get messy perms dialogs
|
||||||
|
// 4 == AttachedRez
|
||||||
|
objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
|
||||||
|
objatt.ResumeScripts();
|
||||||
|
|
||||||
|
// Do this last so that event listeners have access to all the effects of the attachment
|
||||||
|
m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
|
||||||
|
|
||||||
// Fire after attach, so we don't get messy perms dialogs
|
return objatt;
|
||||||
// 4 == AttachedRez
|
}
|
||||||
objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
|
else
|
||||||
objatt.ResumeScripts();
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
// Do this last so that event listeners have access to all the effects of the attachment
|
"[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
|
||||||
m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
|
itemID, sp.Name, attachmentPt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
|
|
||||||
itemID, sp.Name, attachmentPt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return objatt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -438,8 +499,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
|
IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
|
// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
|
||||||
// att.Name, remoteClient.Name, AttachmentPt, itemID);
|
// att.Name, sp.Name, AttachmentPt, itemID);
|
||||||
|
|
||||||
if (UUID.Zero == itemID)
|
if (UUID.Zero == itemID)
|
||||||
{
|
{
|
||||||
|
@ -462,6 +523,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
|
|
||||||
public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
|
public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name);
|
||||||
|
|
||||||
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
|
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
|
||||||
if (group != null)
|
if (group != null)
|
||||||
{
|
{
|
||||||
|
@ -474,14 +538,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
ScenePresence presence;
|
ScenePresence presence;
|
||||||
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||||
{
|
{
|
||||||
// Save avatar attachment information
|
lock (presence.AttachmentsSyncLock)
|
||||||
m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
|
{
|
||||||
|
// Save avatar attachment information
|
||||||
|
m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
|
||||||
|
|
||||||
bool changed = presence.Appearance.DetachAttachment(itemID);
|
bool changed = presence.Appearance.DetachAttachment(itemID);
|
||||||
if (changed && m_scene.AvatarFactory != null)
|
if (changed && m_scene.AvatarFactory != null)
|
||||||
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||||
|
|
||||||
DetachSingleAttachmentToInv(itemID, presence);
|
DetachSingleAttachmentToInv(itemID, presence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +556,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
|
// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
|
||||||
// remoteClient.Name, sceneObjectID);
|
// remoteClient.Name, soLocalId);
|
||||||
|
|
||||||
SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
|
SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
|
||||||
|
|
||||||
|
@ -508,24 +575,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
ScenePresence presence;
|
ScenePresence presence;
|
||||||
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||||
{
|
{
|
||||||
if (!m_scene.Permissions.CanRezObject(
|
lock (presence.AttachmentsSyncLock)
|
||||||
so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
|
{
|
||||||
return;
|
if (!m_scene.Permissions.CanRezObject(
|
||||||
|
so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
|
||||||
|
return;
|
||||||
|
|
||||||
bool changed = presence.Appearance.DetachAttachment(inventoryID);
|
bool changed = presence.Appearance.DetachAttachment(inventoryID);
|
||||||
if (changed && m_scene.AvatarFactory != null)
|
if (changed && m_scene.AvatarFactory != null)
|
||||||
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||||
|
|
||||||
presence.RemoveAttachment(so);
|
presence.RemoveAttachment(so);
|
||||||
DetachSceneObjectToGround(so, presence);
|
DetachSceneObjectToGround(so, presence);
|
||||||
|
|
||||||
List<UUID> uuids = new List<UUID>();
|
List<UUID> uuids = new List<UUID>();
|
||||||
uuids.Add(inventoryID);
|
uuids.Add(inventoryID);
|
||||||
m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids);
|
m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids);
|
||||||
remoteClient.SendRemoveInventoryItem(inventoryID);
|
remoteClient.SendRemoveInventoryItem(inventoryID);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -559,6 +629,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
|
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
|
||||||
private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
|
private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
|
||||||
|
|
||||||
if (itemID == UUID.Zero) // If this happened, someone made a mistake....
|
if (itemID == UUID.Zero) // If this happened, someone made a mistake....
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -567,37 +639,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
EntityBase[] detachEntities = m_scene.GetEntities();
|
EntityBase[] detachEntities = m_scene.GetEntities();
|
||||||
SceneObjectGroup group;
|
SceneObjectGroup group;
|
||||||
|
|
||||||
foreach (EntityBase entity in detachEntities)
|
lock (sp.AttachmentsSyncLock)
|
||||||
{
|
{
|
||||||
if (entity is SceneObjectGroup)
|
foreach (EntityBase entity in detachEntities)
|
||||||
{
|
{
|
||||||
group = (SceneObjectGroup)entity;
|
if (entity is SceneObjectGroup)
|
||||||
if (group.GetFromItemID() == itemID)
|
|
||||||
{
|
{
|
||||||
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
|
group = (SceneObjectGroup)entity;
|
||||||
sp.RemoveAttachment(group);
|
if (group.GetFromItemID() == itemID)
|
||||||
|
{
|
||||||
|
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
|
||||||
|
sp.RemoveAttachment(group);
|
||||||
|
|
||||||
// Prepare sog for storage
|
// Prepare sog for storage
|
||||||
group.AttachedAvatar = UUID.Zero;
|
group.AttachedAvatar = UUID.Zero;
|
||||||
|
group.RootPart.SetParentLocalId(0);
|
||||||
|
group.IsAttachment = false;
|
||||||
|
group.AbsolutePosition = group.RootPart.AttachedPos;
|
||||||
|
|
||||||
group.ForEachPart(
|
UpdateKnownItem(sp.ControllingClient, group);
|
||||||
delegate(SceneObjectPart part)
|
m_scene.DeleteSceneObject(group, false);
|
||||||
{
|
|
||||||
// If there are any scripts,
|
|
||||||
// then always trigger a new object and state persistence in UpdateKnownItem()
|
|
||||||
if (part.Inventory.ContainsScripts())
|
|
||||||
group.HasGroupChanged = true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
group.RootPart.SetParentLocalId(0);
|
return;
|
||||||
group.IsAttachment = false;
|
}
|
||||||
group.AbsolutePosition = group.RootPart.AttachedPos;
|
|
||||||
|
|
||||||
UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID);
|
|
||||||
m_scene.DeleteSceneObject(group, false);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -628,28 +692,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="remoteClient"></param>
|
/// <param name="remoteClient"></param>
|
||||||
/// <param name="grp"></param>
|
/// <param name="grp"></param>
|
||||||
/// <param name="itemID"></param>
|
private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp)
|
||||||
/// <param name="agentID"></param>
|
|
||||||
public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
|
|
||||||
{
|
{
|
||||||
if (grp != null)
|
if (grp.HasGroupChanged || grp.ContainsScripts())
|
||||||
{
|
{
|
||||||
if (!grp.HasGroupChanged)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat(
|
|
||||||
"[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
|
|
||||||
grp.UUID, grp.AttachmentPoint);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
|
"[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
|
||||||
grp.UUID, grp.AttachmentPoint);
|
grp.UUID, grp.AttachmentPoint);
|
||||||
|
|
||||||
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
|
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
|
||||||
|
|
||||||
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
|
InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId);
|
||||||
item = m_scene.InventoryService.GetItem(item);
|
item = m_scene.InventoryService.GetItem(item);
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
|
@ -675,6 +728,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
remoteClient.SendInventoryItemCreateUpdate(item, 0);
|
remoteClient.SendInventoryItemCreateUpdate(item, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
|
||||||
|
grp.UUID, grp.AttachmentPoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -692,7 +751,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
private void AttachToAgent(
|
private void AttachToAgent(
|
||||||
IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
|
IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
|
// m_log.DebugFormat(
|
||||||
|
// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
|
||||||
// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
|
// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
|
||||||
|
|
||||||
so.DetachFromBackup();
|
so.DetachFromBackup();
|
||||||
|
@ -745,7 +805,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
/// <returns>The user inventory item created that holds the attachment.</returns>
|
/// <returns>The user inventory item created that holds the attachment.</returns>
|
||||||
private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp)
|
private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId);
|
// m_log.DebugFormat(
|
||||||
|
// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
|
||||||
|
// grp.Name, grp.LocalId, remoteClient.Name);
|
||||||
|
|
||||||
Vector3 inventoryStoredPosition = new Vector3
|
Vector3 inventoryStoredPosition = new Vector3
|
||||||
(((grp.AbsolutePosition.X > (int)Constants.RegionSize)
|
(((grp.AbsolutePosition.X > (int)Constants.RegionSize)
|
||||||
|
@ -829,4 +891,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -220,6 +220,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||||
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
|
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test that attachments don't hang about in the scene when the agent is closed
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestRemoveAttachmentsOnAvatarExit()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
UUID userId = TestHelpers.ParseTail(0x1);
|
||||||
|
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||||
|
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||||
|
string attName = "att";
|
||||||
|
|
||||||
|
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||||
|
InventoryItemBase attItem
|
||||||
|
= UserInventoryHelpers.CreateInventoryItem(
|
||||||
|
scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
|
||||||
|
|
||||||
|
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
|
||||||
|
acd.Appearance = new AvatarAppearance();
|
||||||
|
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
|
||||||
|
ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
|
||||||
|
|
||||||
|
SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
|
||||||
|
|
||||||
|
scene.IncomingCloseAgent(presence.UUID);
|
||||||
|
|
||||||
|
// Check that we can't retrieve this attachment from the scene.
|
||||||
|
Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestRezAttachmentsOnAvatarEntrance()
|
public void TestRezAttachmentsOnAvatarEntrance()
|
||||||
{
|
{
|
||||||
|
|
|
@ -211,8 +211,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
// Process the visual params, this may change height as well
|
// Process the visual params, this may change height as well
|
||||||
if (visualParams != null)
|
if (visualParams != null)
|
||||||
{
|
{
|
||||||
|
// string[] visualParamsStrings = new string[visualParams.Length];
|
||||||
|
// for (int i = 0; i < visualParams.Length; i++)
|
||||||
|
// visualParamsStrings[i] = visualParams[i].ToString();
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[AVFACTORY]: Setting visual params for {0} to {1}",
|
||||||
|
// client.Name, string.Join(", ", visualParamsStrings));
|
||||||
|
|
||||||
|
float oldHeight = sp.Appearance.AvatarHeight;
|
||||||
changed = sp.Appearance.SetVisualParams(visualParams);
|
changed = sp.Appearance.SetVisualParams(visualParams);
|
||||||
if (sp.Appearance.AvatarHeight > 0)
|
|
||||||
|
if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
|
||||||
sp.SetHeight(sp.Appearance.AvatarHeight);
|
sp.SetHeight(sp.Appearance.AvatarHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,6 +425,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
|
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
|
||||||
|
|
||||||
|
// This could take awhile since it needs to pull inventory
|
||||||
|
// We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
|
||||||
|
// assets and item asset id changes to complete.
|
||||||
|
// I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
|
||||||
|
// multiple save requests.
|
||||||
|
SetAppearanceAssets(sp.UUID, sp.Appearance);
|
||||||
|
|
||||||
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
|
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +483,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId);
|
// m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name);
|
||||||
|
|
||||||
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
|
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
|
||||||
}
|
}
|
||||||
|
@ -502,9 +518,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
avatAppearance.GetAssetsFrom(sp.Appearance);
|
avatAppearance.GetAssetsFrom(sp.Appearance);
|
||||||
|
|
||||||
// This could take awhile since it needs to pull inventory
|
|
||||||
SetAppearanceAssets(sp.UUID, ref avatAppearance);
|
|
||||||
|
|
||||||
lock (m_setAppearanceLock)
|
lock (m_setAppearanceLock)
|
||||||
{
|
{
|
||||||
// Update only those fields that we have changed. This is important because the viewer
|
// Update only those fields that we have changed. This is important because the viewer
|
||||||
|
@ -538,7 +551,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
|
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
|
||||||
{
|
{
|
||||||
IInventoryService invService = m_scene.InventoryService;
|
IInventoryService invService = m_scene.InventoryService;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
* (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;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -145,14 +146,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||||
scene.Entities[toAgentID] is ScenePresence)
|
scene.Entities[toAgentID] is ScenePresence)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
// "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
||||||
// toAgentID.ToString(), scene.RegionInfo.RegionName);
|
// toAgentID.ToString(), scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||||
if (!user.IsChildAgent)
|
if (!user.IsChildAgent)
|
||||||
{
|
{
|
||||||
// Local message
|
// Local message
|
||||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
|
// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
|
||||||
user.ControllingClient.SendInstantMessage(im);
|
user.ControllingClient.SendInstantMessage(im);
|
||||||
|
|
||||||
// Message sent
|
// Message sent
|
||||||
|
@ -166,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||||
foreach (Scene scene in m_Scenes)
|
foreach (Scene scene in m_Scenes)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
|
// "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||||
scene.Entities[toAgentID] is ScenePresence)
|
scene.Entities[toAgentID] is ScenePresence)
|
||||||
|
@ -174,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||||
// Local message
|
// Local message
|
||||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||||
|
|
||||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
|
// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
|
||||||
user.ControllingClient.SendInstantMessage(im);
|
user.ControllingClient.SendInstantMessage(im);
|
||||||
|
|
||||||
// Message sent
|
// Message sent
|
||||||
|
@ -183,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
|
// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
|
||||||
// Is the user a local user?
|
// Is the user a local user?
|
||||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
|
||||||
string url = string.Empty;
|
string url = string.Empty;
|
||||||
|
|
|
@ -154,14 +154,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||||
if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
|
if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
|
||||||
{
|
{
|
||||||
UUID sessionID = new UUID(im.imSessionID);
|
UUID sessionID = new UUID(im.imSessionID);
|
||||||
m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
|
|
||||||
m_PendingLures.Add(sessionID, im, 7200); // 2 hours
|
if (!m_PendingLures.Contains(sessionID))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
|
||||||
|
m_PendingLures.Add(sessionID, im, 7200); // 2 hours
|
||||||
|
}
|
||||||
|
|
||||||
// Forward. We do this, because the IM module explicitly rejects
|
// Forward. We do this, because the IM module explicitly rejects
|
||||||
// IMs of this type
|
// IMs of this type
|
||||||
if (m_TransferModule != null)
|
if (m_TransferModule != null)
|
||||||
m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
|
m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,12 +180,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||||
|
|
||||||
m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
|
m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
|
||||||
|
|
||||||
|
UUID sessionID = UUID.Random();
|
||||||
|
|
||||||
GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
|
GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
|
||||||
client.FirstName+" "+client.LastName, targetid,
|
client.FirstName+" "+client.LastName, targetid,
|
||||||
(byte)InstantMessageDialog.RequestTeleport, false,
|
(byte)InstantMessageDialog.RequestTeleport, false,
|
||||||
message, UUID.Random(), false, presence.AbsolutePosition,
|
message, sessionID, false, presence.AbsolutePosition,
|
||||||
new Byte[0]);
|
new Byte[0]);
|
||||||
m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
|
m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
|
||||||
|
|
||||||
|
m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message);
|
||||||
|
m_PendingLures.Add(sessionID, m, 7200); // 2 hours
|
||||||
|
|
||||||
if (m_TransferModule != null)
|
if (m_TransferModule != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,7 +59,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
get { return m_MaxTransferDistance; }
|
get { return m_MaxTransferDistance; }
|
||||||
set { m_MaxTransferDistance = value; }
|
set { m_MaxTransferDistance = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected bool m_Enabled = false;
|
protected bool m_Enabled = false;
|
||||||
protected Scene m_aScene;
|
protected Scene m_aScene;
|
||||||
|
@ -68,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
|
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
|
||||||
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
|
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
|
||||||
|
|
||||||
|
|
||||||
#region ISharedRegionModule
|
#region ISharedRegionModule
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
|
@ -329,6 +327,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
if (sp.ParentID != (uint)0)
|
if (sp.ParentID != (uint)0)
|
||||||
sp.StandUp();
|
sp.StandUp();
|
||||||
|
|
||||||
|
if (!sp.ValidateAttachments())
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
|
||||||
|
sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
|
||||||
|
|
||||||
// if (!sp.ValidateAttachments())
|
// if (!sp.ValidateAttachments())
|
||||||
// {
|
// {
|
||||||
// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
|
// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
|
||||||
|
@ -939,7 +942,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
/// This Closes child agents on neighbouring regions
|
/// This Closes child agents on neighbouring regions
|
||||||
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version)
|
protected ScenePresence CrossAgentToNewRegionAsync(
|
||||||
|
ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
|
||||||
|
bool isFlying, string version)
|
||||||
{
|
{
|
||||||
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
|
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
|
||||||
|
|
||||||
|
@ -949,7 +954,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
if (neighbourRegion != null)
|
if (neighbourRegion != null)
|
||||||
{
|
{
|
||||||
agent.ValidateAttachments();
|
if (!agent.ValidateAttachments())
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
|
||||||
|
agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
|
||||||
|
|
||||||
pos = pos + (agent.Velocity);
|
pos = pos + (agent.Velocity);
|
||||||
|
|
||||||
|
|
|
@ -363,9 +363,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
lock (m_UserCache)
|
lock (m_UserCache)
|
||||||
m_UserCache[user.Id] = user;
|
m_UserCache[user.Id] = user;
|
||||||
|
|
||||||
m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
"[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
|
// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
|
||||||
user.Id, user.FirstName, user.LastName, user.HomeURL);
|
// user.Id, user.FirstName, user.LastName, user.HomeURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//public void AddUser(UUID uuid, string userData)
|
//public void AddUser(UUID uuid, string userData)
|
||||||
|
|
|
@ -185,15 +185,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
|
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
|
||||||
{
|
{
|
||||||
InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID);
|
InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID);
|
||||||
Util.FireAndForget(delegate
|
|
||||||
|
if (UserManager != null)
|
||||||
{
|
{
|
||||||
if (UserManager != null)
|
// Protect ourselves against the caller subsequently modifying the items list
|
||||||
|
List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
|
||||||
|
|
||||||
|
Util.FireAndForget(delegate
|
||||||
{
|
{
|
||||||
// Protect ourselves against the caller subsequently modifying the items list
|
foreach (InventoryItemBase item in items)
|
||||||
foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
|
|
||||||
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
return invCol;
|
return invCol;
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,15 +193,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
|
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
|
||||||
{
|
{
|
||||||
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
|
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
|
||||||
Util.FireAndForget(delegate
|
|
||||||
|
if (UserManager != null)
|
||||||
{
|
{
|
||||||
if (UserManager != null)
|
// Protect ourselves against the caller subsequently modifying the items list
|
||||||
|
List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
|
||||||
|
|
||||||
|
Util.FireAndForget(delegate
|
||||||
{
|
{
|
||||||
// Protect ourselves against the caller subsequently modifying the items list
|
foreach (InventoryItemBase item in items)
|
||||||
foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
|
|
||||||
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
return invCol;
|
return invCol;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
|
||||||
LogManager.GetLogger(
|
LogManager.GetLogger(
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private IUserAccountService m_UserService;
|
/// <summary>
|
||||||
|
/// This is not on the IUserAccountService. It's only being used so that standalone scenes can punch through
|
||||||
|
/// to a local UserAccountService when setting up an estate manager.
|
||||||
|
/// </summary>
|
||||||
|
public IUserAccountService UserAccountService { get; private set; }
|
||||||
|
|
||||||
private UserAccountCache m_Cache;
|
private UserAccountCache m_Cache;
|
||||||
|
|
||||||
private bool m_Enabled = false;
|
private bool m_Enabled = false;
|
||||||
|
@ -86,9 +91,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
|
||||||
}
|
}
|
||||||
|
|
||||||
Object[] args = new Object[] { source };
|
Object[] args = new Object[] { source };
|
||||||
m_UserService = ServerUtils.LoadPlugin<IUserAccountService>(serviceDll, args);
|
UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(serviceDll, args);
|
||||||
|
|
||||||
if (m_UserService == null)
|
if (UserAccountService == null)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll);
|
"[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll);
|
||||||
|
@ -119,7 +124,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
|
||||||
if (!m_Enabled)
|
if (!m_Enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scene.RegisterModuleInterface<IUserAccountService>(m_UserService);
|
// FIXME: Why do we bother setting this module and caching up if we just end up registering the inner
|
||||||
|
// user account service?!
|
||||||
|
scene.RegisterModuleInterface<IUserAccountService>(UserAccountService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -147,7 +154,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
|
||||||
if (inCache)
|
if (inCache)
|
||||||
return account;
|
return account;
|
||||||
|
|
||||||
account = m_UserService.GetUserAccount(scopeID, userID);
|
account = UserAccountService.GetUserAccount(scopeID, userID);
|
||||||
m_Cache.Cache(userID, account);
|
m_Cache.Cache(userID, account);
|
||||||
|
|
||||||
return account;
|
return account;
|
||||||
|
@ -160,7 +167,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
|
||||||
if (inCache)
|
if (inCache)
|
||||||
return account;
|
return account;
|
||||||
|
|
||||||
account = m_UserService.GetUserAccount(scopeID, firstName, lastName);
|
account = UserAccountService.GetUserAccount(scopeID, firstName, lastName);
|
||||||
if (account != null)
|
if (account != null)
|
||||||
m_Cache.Cache(account.PrincipalID, account);
|
m_Cache.Cache(account.PrincipalID, account);
|
||||||
|
|
||||||
|
@ -169,22 +176,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
|
||||||
|
|
||||||
public UserAccount GetUserAccount(UUID scopeID, string Email)
|
public UserAccount GetUserAccount(UUID scopeID, string Email)
|
||||||
{
|
{
|
||||||
return m_UserService.GetUserAccount(scopeID, Email);
|
return UserAccountService.GetUserAccount(scopeID, Email);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
|
public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
|
||||||
{
|
{
|
||||||
return m_UserService.GetUserAccounts(scopeID, query);
|
return UserAccountService.GetUserAccounts(scopeID, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update all updatable fields
|
// Update all updatable fields
|
||||||
//
|
//
|
||||||
public bool StoreUserAccount(UserAccount data)
|
public bool StoreUserAccount(UserAccount data)
|
||||||
{
|
{
|
||||||
return m_UserService.StoreUserAccount(data);
|
return UserAccountService.StoreUserAccount(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -284,8 +284,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
|
|
||||||
// And zap any troublesome sit target information
|
// And zap any troublesome sit target information
|
||||||
part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
|
// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
|
||||||
part.SitTargetPosition = new Vector3(0, 0, 0);
|
// part.SitTargetPosition = new Vector3(0, 0, 0);
|
||||||
|
|
||||||
// Fix ownership/creator of inventory items
|
// Fix ownership/creator of inventory items
|
||||||
// Not doing so results in inventory items
|
// Not doing so results in inventory items
|
||||||
|
|
|
@ -127,6 +127,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
|
|
||||||
EntityBase[] entities = m_scene.GetEntities();
|
EntityBase[] entities = m_scene.GetEntities();
|
||||||
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
|
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
|
||||||
|
|
||||||
|
string checkPermissions = null;
|
||||||
|
int numObjectsSkippedPermissions = 0;
|
||||||
|
Object temp;
|
||||||
|
if (options.TryGetValue("checkPermissions", out temp))
|
||||||
|
checkPermissions = (string)temp;
|
||||||
|
|
||||||
// Filter entities so that we only have scene objects.
|
// Filter entities so that we only have scene objects.
|
||||||
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
|
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
|
||||||
|
@ -136,9 +142,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
if (entity is SceneObjectGroup)
|
if (entity is SceneObjectGroup)
|
||||||
{
|
{
|
||||||
SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
|
SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
|
||||||
|
|
||||||
if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
|
if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
|
||||||
sceneObjects.Add((SceneObjectGroup)entity);
|
{
|
||||||
|
if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions))
|
||||||
|
{
|
||||||
|
// The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
|
||||||
|
++numObjectsSkippedPermissions;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sceneObjects.Add(sceneObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +175,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
|
m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (numObjectsSkippedPermissions > 0)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
|
||||||
|
numObjectsSkippedPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure that we also request terrain texture assets
|
// Make sure that we also request terrain texture assets
|
||||||
RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
|
RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
|
||||||
|
|
||||||
|
@ -210,6 +233,83 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether the user has permission to export an object group to an OAR.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">The user</param>
|
||||||
|
/// <param name="objGroup">The object group</param>
|
||||||
|
/// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param>
|
||||||
|
/// <returns>Whether the user is allowed to export the object to an OAR</returns>
|
||||||
|
private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions)
|
||||||
|
{
|
||||||
|
if (checkPermissions == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
IPermissionsModule module = m_scene.RequestModuleInterface<IPermissionsModule>();
|
||||||
|
if (module == null)
|
||||||
|
return true; // this shouldn't happen
|
||||||
|
|
||||||
|
// Check whether the user is permitted to export all of the parts in the SOG. If any
|
||||||
|
// part can't be exported then the entire SOG can't be exported.
|
||||||
|
|
||||||
|
bool permitted = true;
|
||||||
|
//int primNumber = 1;
|
||||||
|
|
||||||
|
foreach (SceneObjectPart obj in objGroup.Parts)
|
||||||
|
{
|
||||||
|
uint perm;
|
||||||
|
PermissionClass permissionClass = module.GetPermissionClass(user, obj);
|
||||||
|
switch (permissionClass)
|
||||||
|
{
|
||||||
|
case PermissionClass.Owner:
|
||||||
|
perm = obj.BaseMask;
|
||||||
|
break;
|
||||||
|
case PermissionClass.Group:
|
||||||
|
perm = obj.GroupMask | obj.EveryoneMask;
|
||||||
|
break;
|
||||||
|
case PermissionClass.Everyone:
|
||||||
|
default:
|
||||||
|
perm = obj.EveryoneMask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canCopy = (perm & (uint)PermissionMask.Copy) != 0;
|
||||||
|
bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0;
|
||||||
|
|
||||||
|
// Special case: if Everyone can copy the object then this implies it can also be
|
||||||
|
// Transferred.
|
||||||
|
// However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask
|
||||||
|
// always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer
|
||||||
|
// does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied.
|
||||||
|
if (permissionClass != PermissionClass.Owner)
|
||||||
|
{
|
||||||
|
canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool partPermitted = true;
|
||||||
|
if (checkPermissions.Contains("C") && !canCopy)
|
||||||
|
partPermitted = false;
|
||||||
|
if (checkPermissions.Contains("T") && !canTransfer)
|
||||||
|
partPermitted = false;
|
||||||
|
|
||||||
|
//string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount);
|
||||||
|
//m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}",
|
||||||
|
// name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask,
|
||||||
|
// permissionClass, checkPermissions, canCopy, canTransfer, permitted);
|
||||||
|
|
||||||
|
if (!partPermitted)
|
||||||
|
{
|
||||||
|
permitted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//++primNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
return permitted;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create the control file for the most up to date archive
|
/// Create the control file for the most up to date archive
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
|
// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
|
||||||
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
|
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
|
||||||
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
|
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
|
||||||
|
ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
|
||||||
|
|
||||||
List<string> mainParams = ops.Parse(cmdparams);
|
List<string> mainParams = ops.Parse(cmdparams);
|
||||||
|
|
||||||
|
|
|
@ -318,6 +318,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
|
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
|
||||||
|
|
||||||
SceneObjectPart part1 = CreateSceneObjectPart1();
|
SceneObjectPart part1 = CreateSceneObjectPart1();
|
||||||
|
|
||||||
|
part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
|
||||||
|
part1.SitTargetPosition = new Vector3(1, 2, 3);
|
||||||
|
|
||||||
SceneObjectGroup object1 = new SceneObjectGroup(part1);
|
SceneObjectGroup object1 = new SceneObjectGroup(part1);
|
||||||
|
|
||||||
// Let's put some inventory items into our object
|
// Let's put some inventory items into our object
|
||||||
|
@ -390,6 +394,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
|
object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
|
||||||
Assert.That(
|
Assert.That(
|
||||||
object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
|
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];
|
TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
|
||||||
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
|
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
|
||||||
|
|
|
@ -968,10 +968,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||||
args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3;
|
args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3;
|
||||||
args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4;
|
args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4;
|
||||||
|
|
||||||
m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 1 {0} for region {1}", args.terrainDetail0, Scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 1 {0} for region {1}", args.terrainDetail0, Scene.RegionInfo.RegionName);
|
||||||
m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 2 {0} for region {1}", args.terrainDetail1, Scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 2 {0} for region {1}", args.terrainDetail1, Scene.RegionInfo.RegionName);
|
||||||
m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 3 {0} for region {1}", args.terrainDetail2, Scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 3 {0} for region {1}", args.terrainDetail2, Scene.RegionInfo.RegionName);
|
||||||
m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 4 {0} for region {1}", args.terrainDetail3, Scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 4 {0} for region {1}", args.terrainDetail3, Scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
remoteClient.SendRegionHandshake(Scene.RegionInfo,args);
|
remoteClient.SendRegionHandshake(Scene.RegionInfo,args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
|
||||||
|
|
||||||
part.ParentGroup.HasGroupChanged = true;
|
part.ParentGroup.HasGroupChanged = true;
|
||||||
|
|
||||||
part.GetProperties(client);
|
part.SendPropertiesToClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice)
|
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice)
|
||||||
|
@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
|
||||||
part.SalePrice = 10;
|
part.SalePrice = 10;
|
||||||
|
|
||||||
group.HasGroupChanged = true;
|
group.HasGroupChanged = true;
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
part.TriggerScriptChangedEvent(Changed.OWNER);
|
part.TriggerScriptChangedEvent(Changed.OWNER);
|
||||||
group.ResumeScripts();
|
group.ResumeScripts();
|
||||||
part.ScheduleFullUpdate();
|
part.ScheduleFullUpdate();
|
||||||
|
|
|
@ -39,7 +39,7 @@ using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
namespace OpenSim.Region.CoreModules.World.Permissions
|
namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
{
|
{
|
||||||
public class PermissionsModule : IRegionModule
|
public class PermissionsModule : IRegionModule, IPermissionsModule
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
@ -150,6 +150,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
else
|
else
|
||||||
m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
|
m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
|
||||||
|
|
||||||
|
scene.RegisterModuleInterface<IPermissionsModule>(this);
|
||||||
|
|
||||||
//Register functions with Scene External Checks!
|
//Register functions with Scene External Checks!
|
||||||
m_scene.Permissions.OnBypassPermissions += BypassPermissions;
|
m_scene.Permissions.OnBypassPermissions += BypassPermissions;
|
||||||
m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions;
|
m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions;
|
||||||
|
@ -574,46 +576,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
if (objectOwner != UUID.Zero)
|
if (objectOwner != UUID.Zero)
|
||||||
objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner;
|
objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner;
|
||||||
|
|
||||||
if (m_bypassPermissions)
|
PermissionClass permissionClass = GetPermissionClass(user, task);
|
||||||
return objectOwnerMask;
|
|
||||||
|
|
||||||
// Object owners should be able to edit their own content
|
switch (permissionClass)
|
||||||
if (user == objectOwner)
|
|
||||||
return objectOwnerMask;
|
|
||||||
|
|
||||||
if (IsFriendWithPerms(user, objectOwner))
|
|
||||||
{
|
{
|
||||||
return objectOwnerMask;
|
case PermissionClass.Owner:
|
||||||
}
|
|
||||||
// Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
|
|
||||||
if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
|
|
||||||
{
|
|
||||||
return objectOwnerMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Admin should be able to edit anything in the sim (including admin objects)
|
|
||||||
if (IsAdministrator(user))
|
|
||||||
{
|
|
||||||
return objectOwnerMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Users should be able to edit what is over their land.
|
|
||||||
Vector3 taskPos = task.AbsolutePosition;
|
|
||||||
ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
|
|
||||||
if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod)
|
|
||||||
{
|
|
||||||
// Admin objects should not be editable by the above
|
|
||||||
if (!IsAdministrator(objectOwner))
|
|
||||||
{
|
|
||||||
return objectOwnerMask;
|
return objectOwnerMask;
|
||||||
}
|
case PermissionClass.Group:
|
||||||
|
return objectGroupMask | objectEveryoneMask;
|
||||||
|
case PermissionClass.Everyone:
|
||||||
|
default:
|
||||||
|
return objectEveryoneMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group permissions
|
|
||||||
if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
|
|
||||||
return objectGroupMask | objectEveryoneMask;
|
|
||||||
|
|
||||||
return objectEveryoneMask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask)
|
private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask)
|
||||||
|
@ -644,6 +618,47 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
return objectFlagsMask;
|
return objectFlagsMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
return PermissionClass.Everyone;
|
||||||
|
|
||||||
|
if (m_bypassPermissions)
|
||||||
|
return PermissionClass.Owner;
|
||||||
|
|
||||||
|
// Object owners should be able to edit their own content
|
||||||
|
UUID objectOwner = obj.OwnerID;
|
||||||
|
if (user == objectOwner)
|
||||||
|
return PermissionClass.Owner;
|
||||||
|
|
||||||
|
if (IsFriendWithPerms(user, objectOwner))
|
||||||
|
return PermissionClass.Owner;
|
||||||
|
|
||||||
|
// Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
|
||||||
|
if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
|
||||||
|
return PermissionClass.Owner;
|
||||||
|
|
||||||
|
// Admin should be able to edit anything in the sim (including admin objects)
|
||||||
|
if (IsAdministrator(user))
|
||||||
|
return PermissionClass.Owner;
|
||||||
|
|
||||||
|
// Users should be able to edit what is over their land.
|
||||||
|
Vector3 taskPos = obj.AbsolutePosition;
|
||||||
|
ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
|
||||||
|
if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod)
|
||||||
|
{
|
||||||
|
// Admin objects should not be editable by the above
|
||||||
|
if (!IsAdministrator(objectOwner))
|
||||||
|
return PermissionClass.Owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group permissions
|
||||||
|
if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0))
|
||||||
|
return PermissionClass.Group;
|
||||||
|
|
||||||
|
return PermissionClass.Everyone;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// General permissions checks for any operation involving an object. These supplement more specific checks
|
/// General permissions checks for any operation involving an object. These supplement more specific checks
|
||||||
/// implemented by callers.
|
/// implemented by callers.
|
||||||
|
|
|
@ -222,7 +222,7 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||||
public event ScriptReset OnScriptReset;
|
public event ScriptReset OnScriptReset;
|
||||||
public event GetScriptRunning OnGetScriptRunning;
|
public event GetScriptRunning OnGetScriptRunning;
|
||||||
public event SetScriptRunning OnSetScriptRunning;
|
public event SetScriptRunning OnSetScriptRunning;
|
||||||
public event Action<Vector3, bool> OnAutoPilotGo;
|
public event Action<Vector3, bool, bool> OnAutoPilotGo;
|
||||||
|
|
||||||
public event TerrainUnacked OnUnackedTerrain;
|
public event TerrainUnacked OnUnackedTerrain;
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,15 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
|
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
|
||||||
ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
|
ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rez an attachment from user inventory and change inventory status to match.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sp"></param>
|
||||||
|
/// <param name="itemID"></param>
|
||||||
|
/// <param name="AttachmentPt"></param>
|
||||||
|
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
|
||||||
|
ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rez multiple attachments from a user's inventory
|
/// Rez multiple attachments from a user's inventory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -129,14 +138,5 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <param name="sog"></param>
|
/// <param name="sog"></param>
|
||||||
/// <param name="pos"></param>
|
/// <param name="pos"></param>
|
||||||
void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos);
|
void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update the user inventory with a changed attachment
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="remoteClient"></param>
|
|
||||||
/// <param name="grp"></param>
|
|
||||||
/// <param name="itemID"></param>
|
|
||||||
/// <param name="agentID"></param>
|
|
||||||
void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -48,6 +48,14 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <param name="estateID"></param>
|
/// <param name="estateID"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
EstateSettings LoadEstateSettings(int estateID);
|
EstateSettings LoadEstateSettings(int estateID);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new estate.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="EstateSettings"/>
|
||||||
|
/// </returns>
|
||||||
|
EstateSettings CreateNewEstate();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load/Get all estate settings.
|
/// Load/Get all estate settings.
|
||||||
|
|
|
@ -54,6 +54,14 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
EstateSettings LoadEstateSettings(int estateID);
|
EstateSettings LoadEstateSettings(int estateID);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new estate.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="EstateSettings"/>
|
||||||
|
/// </returns>
|
||||||
|
EstateSettings CreateNewEstate();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load/Get all estate settings.
|
/// Load/Get all estate settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -25,36 +25,30 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
|
||||||
public enum StatusIndicators : int
|
namespace OpenSim.Region.Framework.Interfaces
|
||||||
{
|
{
|
||||||
Generic = 0,
|
/// <value>
|
||||||
Start = 1,
|
/// Which set of permissions a user has.
|
||||||
End = 2
|
/// </value>
|
||||||
|
public enum PermissionClass
|
||||||
|
{
|
||||||
|
Owner,
|
||||||
|
Group,
|
||||||
|
Everyone
|
||||||
|
};
|
||||||
|
|
||||||
|
public interface IPermissionsModule
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the type of permissions that the user has over an object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">The user</param>
|
||||||
|
/// <param name="obj">The object</param>
|
||||||
|
/// <returns>The type of permissions the user has over the object</returns>
|
||||||
|
PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct sCollisionData
|
|
||||||
{
|
|
||||||
public uint ColliderLocalId;
|
|
||||||
public uint CollidedWithLocalId;
|
|
||||||
public int NumberOfCollisions;
|
|
||||||
public int CollisionType;
|
|
||||||
public int StatusIndicator;
|
|
||||||
public int lastframe;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum CollisionCategories : int
|
|
||||||
{
|
|
||||||
Disabled = 0,
|
|
||||||
Geom = 0x00000001,
|
|
||||||
Body = 0x00000002,
|
|
||||||
Space = 0x00000004,
|
|
||||||
Character = 0x00000008,
|
|
||||||
Land = 0x00000010,
|
|
||||||
Water = 0x00000020,
|
|
||||||
Wind = 0x00000040,
|
|
||||||
Sensor = 0x00000080,
|
|
||||||
Selected = 0x00000100
|
|
||||||
}
|
|
|
@ -60,6 +60,14 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
AvatarAppearance Appearance { get; set; }
|
AvatarAppearance Appearance { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// All add and remove attachment operations must synchronize on this for the lifetime of their operations.
|
||||||
|
/// </remarks>
|
||||||
|
Object AttachmentsSyncLock { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The scene objects attached to this avatar.
|
/// The scene objects attached to this avatar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -52,5 +52,10 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
ArrayList GetScriptErrors(UUID itemID);
|
ArrayList GetScriptErrors(UUID itemID);
|
||||||
|
|
||||||
void SaveAllState();
|
void SaveAllState();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the processing threads.
|
||||||
|
/// </summary>
|
||||||
|
void StartProcessing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Security.Permissions;
|
using System.Security.Permissions;
|
||||||
|
using log4net;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
@ -35,6 +37,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
public abstract class EntityBase : ISceneEntity
|
public abstract class EntityBase : ISceneEntity
|
||||||
{
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The scene to which this entity belongs
|
/// The scene to which this entity belongs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -71,12 +75,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
protected Vector3 m_pos;
|
protected Vector3 m_pos;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Absolute position of this entity in a scene.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual Vector3 AbsolutePosition
|
public virtual Vector3 AbsolutePosition
|
||||||
{
|
{
|
||||||
get { return m_pos; }
|
get { return m_pos; }
|
||||||
set { m_pos = value; }
|
set
|
||||||
|
{
|
||||||
|
m_pos = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Vector3 m_velocity;
|
protected Vector3 m_velocity;
|
||||||
|
|
|
@ -57,11 +57,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
protected AsyncInventorySender m_asyncInventorySender;
|
protected AsyncInventorySender m_asyncInventorySender;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start all the scripts in the scene which should be started.
|
/// Creates all the scripts in the scene which should be started.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void CreateScriptInstances()
|
public void CreateScriptInstances()
|
||||||
{
|
{
|
||||||
m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
|
m_log.Info("[PRIM INVENTORY]: Creating scripts in scene");
|
||||||
|
|
||||||
EntityBase[] entities = Entities.GetEntities();
|
EntityBase[] entities = Entities.GetEntities();
|
||||||
foreach (EntityBase group in entities)
|
foreach (EntityBase group in entities)
|
||||||
|
@ -74,6 +74,26 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lets the script engines start processing scripts.
|
||||||
|
/// </summary>
|
||||||
|
public void StartScripts()
|
||||||
|
{
|
||||||
|
m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
|
||||||
|
|
||||||
|
IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
|
||||||
|
if (engines != null)
|
||||||
|
{
|
||||||
|
foreach (IScriptModule engine in engines)
|
||||||
|
{
|
||||||
|
if (engine != null)
|
||||||
|
{
|
||||||
|
engine.StartProcessing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
|
public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
|
||||||
{
|
{
|
||||||
IMoneyModule money = RequestModuleInterface<IMoneyModule>();
|
IMoneyModule money = RequestModuleInterface<IMoneyModule>();
|
||||||
|
@ -254,7 +274,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (group.UpdateInventoryItem(item))
|
if (group.UpdateInventoryItem(item))
|
||||||
remoteClient.SendAgentAlertMessage("Script saved", false);
|
remoteClient.SendAgentAlertMessage("Script saved", false);
|
||||||
|
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
|
|
||||||
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
|
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
|
||||||
ArrayList errors = new ArrayList();
|
ArrayList errors = new ArrayList();
|
||||||
|
@ -314,6 +334,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
|
public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
|
||||||
UUID itemID, InventoryItemBase itemUpd)
|
UUID itemID, InventoryItemBase itemUpd)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[USER INVENTORY]: Updating asset for item {0} {1}, transaction ID {2} for {3}",
|
||||||
|
// itemID, itemUpd.Name, transactionID, remoteClient.Name);
|
||||||
|
|
||||||
// This one will let people set next perms on items in agent
|
// This one will let people set next perms on items in agent
|
||||||
// inventory. Rut-Roh. Whatever. Make this secure. Yeah.
|
// inventory. Rut-Roh. Whatever. Make this secure. Yeah.
|
||||||
//
|
//
|
||||||
|
@ -365,8 +389,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
||||||
if (agentTransactions != null)
|
if (agentTransactions != null)
|
||||||
{
|
{
|
||||||
agentTransactions.HandleItemUpdateFromTransaction(
|
agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
|
||||||
remoteClient, transactionID, item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -979,7 +1002,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
group.RemoveInventoryItem(localID, itemID);
|
group.RemoveInventoryItem(localID, itemID);
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
|
private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
|
||||||
|
@ -1252,7 +1275,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
|
if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
|
||||||
{
|
{
|
||||||
destPart.GetProperties(avatar.ControllingClient);
|
destPart.SendPropertiesToClient(avatar.ControllingClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1407,7 +1430,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
|
"[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
|
||||||
item.Name, primLocalID, remoteClient.Name);
|
item.Name, primLocalID, remoteClient.Name);
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
if (!Permissions.BypassPermissions())
|
if (!Permissions.BypassPermissions())
|
||||||
{
|
{
|
||||||
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
|
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
|
||||||
|
@ -1502,7 +1525,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (part.Inventory.UpdateInventoryItem(itemInfo))
|
if (part.Inventory.UpdateInventoryItem(itemInfo))
|
||||||
{
|
{
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1554,7 +1577,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// m_log.InfoFormat("[PRIMINVENTORY]: " +
|
// m_log.InfoFormat("[PRIMINVENTORY]: " +
|
||||||
// "Rezzed script {0} into prim local ID {1} for user {2}",
|
// "Rezzed script {0} into prim local ID {1} for user {2}",
|
||||||
// item.inventoryName, localID, remoteClient.Name);
|
// item.inventoryName, localID, remoteClient.Name);
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
part.ParentGroup.ResumeScripts();
|
part.ParentGroup.ResumeScripts();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1612,7 +1635,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
taskItem.AssetID = asset.FullID;
|
taskItem.AssetID = asset.FullID;
|
||||||
|
|
||||||
part.Inventory.AddInventoryItem(taskItem, false);
|
part.Inventory.AddInventoryItem(taskItem, false);
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
|
|
||||||
part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
|
part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
|
||||||
part.ParentGroup.ResumeScripts();
|
part.ParentGroup.ResumeScripts();
|
||||||
|
@ -1726,7 +1749,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
|
if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
|
||||||
{
|
{
|
||||||
destPart.GetProperties(avatar.ControllingClient);
|
destPart.SendPropertiesToClient(avatar.ControllingClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2064,7 +2087,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectPart part = GetSceneObjectPart(localID);
|
SceneObjectPart part = GetSceneObjectPart(localID);
|
||||||
if (part == null)
|
if (part == null)
|
||||||
continue;
|
continue;
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (((SceneObjectGroup) ent).LocalId == primLocalID)
|
if (((SceneObjectGroup) ent).LocalId == primLocalID)
|
||||||
{
|
{
|
||||||
((SceneObjectGroup) ent).GetProperties(remoteClient);
|
((SceneObjectGroup) ent).SendPropertiesToClient(remoteClient);
|
||||||
((SceneObjectGroup) ent).IsSelected = true;
|
((SceneObjectGroup) ent).IsSelected = true;
|
||||||
// A prim is only tainted if it's allowed to be edited by the person clicking it.
|
// A prim is only tainted if it's allowed to be edited by the person clicking it.
|
||||||
if (Permissions.CanEditObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId)
|
if (Permissions.CanEditObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId)
|
||||||
|
@ -167,7 +167,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (part.LocalId == primLocalID)
|
if (part.LocalId == primLocalID)
|
||||||
{
|
{
|
||||||
part.GetProperties(remoteClient);
|
part.SendPropertiesToClient(remoteClient);
|
||||||
foundPrim = true;
|
foundPrim = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -656,7 +656,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
EventManager.OnLandObjectRemoved +=
|
EventManager.OnLandObjectRemoved +=
|
||||||
new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
|
new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
|
||||||
|
|
||||||
m_sceneGraph = new SceneGraph(this, m_regInfo);
|
m_sceneGraph = new SceneGraph(this);
|
||||||
|
|
||||||
// If the scene graph has an Unrecoverable error, restart this sim.
|
// If the scene graph has an Unrecoverable error, restart this sim.
|
||||||
// Currently the only thing that causes it to happen is two kinds of specific
|
// Currently the only thing that causes it to happen is two kinds of specific
|
||||||
|
@ -870,6 +870,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (dm != null)
|
if (dm != null)
|
||||||
m_eventManager.OnPermissionError += dm.SendAlertToUser;
|
m_eventManager.OnPermissionError += dm.SendAlertToUser;
|
||||||
|
|
||||||
|
m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetSimulatorVersion()
|
public override string GetSimulatorVersion()
|
||||||
|
@ -1170,87 +1172,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_dialogModule = RequestModuleInterface<IDialogModule>();
|
m_dialogModule = RequestModuleInterface<IDialogModule>();
|
||||||
m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
|
m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
|
||||||
m_teleportModule = RequestModuleInterface<IEntityTransferModule>();
|
m_teleportModule = RequestModuleInterface<IEntityTransferModule>();
|
||||||
|
|
||||||
// Shoving this in here for now, because we have the needed
|
|
||||||
// interfaces at this point
|
|
||||||
//
|
|
||||||
// TODO: Find a better place for this
|
|
||||||
//
|
|
||||||
while (m_regInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", m_regInfo.EstateSettings.EstateName);
|
|
||||||
List<char> excluded = new List<char>(new char[1]{' '});
|
|
||||||
string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
|
|
||||||
string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
|
|
||||||
|
|
||||||
UserAccount account = UserAccountService.GetUserAccount(m_regInfo.ScopeID, first, last);
|
|
||||||
|
|
||||||
if (account == null)
|
|
||||||
{
|
|
||||||
// Create a new account
|
|
||||||
account = new UserAccount(m_regInfo.ScopeID, first, last, String.Empty);
|
|
||||||
if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0))
|
|
||||||
{
|
|
||||||
account.ServiceURLs = new Dictionary<string, object>();
|
|
||||||
account.ServiceURLs["HomeURI"] = string.Empty;
|
|
||||||
account.ServiceURLs["GatekeeperURI"] = string.Empty;
|
|
||||||
account.ServiceURLs["InventoryServerURI"] = string.Empty;
|
|
||||||
account.ServiceURLs["AssetServerURI"] = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UserAccountService.StoreUserAccount(account))
|
|
||||||
{
|
|
||||||
string password = MainConsole.Instance.PasswdPrompt("Password");
|
|
||||||
string email = MainConsole.Instance.CmdPrompt("Email", "");
|
|
||||||
|
|
||||||
account.Email = email;
|
|
||||||
UserAccountService.StoreUserAccount(account);
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
success = AuthenticationService.SetPassword(account.PrincipalID, password);
|
|
||||||
if (!success)
|
|
||||||
m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set password for account {0} {1}.",
|
|
||||||
first, last);
|
|
||||||
|
|
||||||
GridRegion home = null;
|
|
||||||
if (GridService != null)
|
|
||||||
{
|
|
||||||
List<GridRegion> defaultRegions = GridService.GetDefaultRegions(UUID.Zero);
|
|
||||||
if (defaultRegions != null && defaultRegions.Count >= 1)
|
|
||||||
home = defaultRegions[0];
|
|
||||||
|
|
||||||
if (GridUserService != null && home != null)
|
|
||||||
GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
|
|
||||||
else
|
|
||||||
m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set home for account {0} {1}.",
|
|
||||||
first, last);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to retrieve home region for account {0} {1}.",
|
|
||||||
first, last);
|
|
||||||
|
|
||||||
if (InventoryService != null)
|
|
||||||
success = InventoryService.CreateUserInventory(account.PrincipalID);
|
|
||||||
if (!success)
|
|
||||||
m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
|
|
||||||
first, last);
|
|
||||||
|
|
||||||
|
|
||||||
m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", first, last);
|
|
||||||
|
|
||||||
m_regInfo.EstateSettings.EstateOwner = account.PrincipalID;
|
|
||||||
m_regInfo.EstateSettings.Save();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_log.ErrorFormat("[SCENE]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_regInfo.EstateSettings.EstateOwner = account.PrincipalID;
|
|
||||||
m_regInfo.EstateSettings.Save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -1579,7 +1500,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
|
msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
|
||||||
msg.Position = Vector3.Zero;
|
msg.Position = Vector3.Zero;
|
||||||
msg.RegionID = RegionInfo.RegionID.Guid;
|
msg.RegionID = RegionInfo.RegionID.Guid;
|
||||||
msg.binaryBucket = new byte[0];
|
|
||||||
|
// We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
|
||||||
|
msg.binaryBucket = Util.StringToBytes256("\0");
|
||||||
if (ret.Value.count > 1)
|
if (ret.Value.count > 1)
|
||||||
msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||||
else
|
else
|
||||||
|
@ -2459,14 +2382,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns>False</returns>
|
/// <returns>False</returns>
|
||||||
public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
|
public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
|
m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
|
||||||
|
|
||||||
ScenePresence sp = GetScenePresence(userID);
|
// Commented out since this is as yet unused and is arguably not the appropriate place to do this, as
|
||||||
if (sp != null && AttachmentsModule != null)
|
// attachments are being rezzed elsewhere in AddNewClient()
|
||||||
{
|
// ScenePresence sp = GetScenePresence(userID);
|
||||||
uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
|
// if (sp != null && AttachmentsModule != null)
|
||||||
AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
|
// {
|
||||||
}
|
// uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
|
||||||
|
// AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
|
||||||
|
// }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5215,5 +5140,70 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
reason = String.Empty;
|
reason = String.Empty;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method deals with movement when an avatar is automatically moving (but this is distinct from the
|
||||||
|
/// autopilot that moves an avatar to a sit target!.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is not intended as a permament location for this method.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="presence"></param>
|
||||||
|
private void HandleOnSignificantClientMovement(ScenePresence presence)
|
||||||
|
{
|
||||||
|
if (presence.MovingToTarget)
|
||||||
|
{
|
||||||
|
double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}",
|
||||||
|
// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
|
||||||
|
|
||||||
|
// Check the error term of the current position in relation to the target position
|
||||||
|
if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
|
||||||
|
{
|
||||||
|
// We are close enough to the target
|
||||||
|
// m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name);
|
||||||
|
|
||||||
|
presence.Velocity = Vector3.Zero;
|
||||||
|
presence.AbsolutePosition = presence.MoveToPositionTarget;
|
||||||
|
presence.ResetMoveToTarget();
|
||||||
|
|
||||||
|
if (presence.PhysicsActor.Flying)
|
||||||
|
{
|
||||||
|
// A horrible hack to stop the avatar dead in its tracks rather than having them overshoot
|
||||||
|
// the target if flying.
|
||||||
|
// We really need to be more subtle (slow the avatar as it approaches the target) or at
|
||||||
|
// least be able to set collision status once, rather than 5 times to give it enough
|
||||||
|
// weighting so that that PhysicsActor thinks it really is colliding.
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
presence.PhysicsActor.IsColliding = true;
|
||||||
|
|
||||||
|
if (presence.LandAtTarget)
|
||||||
|
presence.PhysicsActor.Flying = false;
|
||||||
|
|
||||||
|
// Vector3 targetPos = presence.MoveToPositionTarget;
|
||||||
|
// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
|
||||||
|
// if (targetPos.Z - terrainHeight < 0.2)
|
||||||
|
// {
|
||||||
|
// presence.PhysicsActor.Flying = false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}",
|
||||||
|
// presence.AgentControlFlags, presence.MovementFlag, presence.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE]: Updating npc {0} at {1} for next movement to {2}",
|
||||||
|
// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
|
||||||
|
|
||||||
|
Vector3 agent_control_v3 = new Vector3();
|
||||||
|
presence.HandleMoveToTargetUpdate(ref agent_control_v3);
|
||||||
|
presence.AddNewMovement(agent_control_v3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
protected internal EntityManager Entities = new EntityManager();
|
protected internal EntityManager Entities = new EntityManager();
|
||||||
|
|
||||||
protected RegionInfo m_regInfo;
|
|
||||||
protected Scene m_parentScene;
|
protected Scene m_parentScene;
|
||||||
protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
|
protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
|
||||||
protected int m_numRootAgents = 0;
|
protected int m_numRootAgents = 0;
|
||||||
|
@ -108,10 +107,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
protected internal SceneGraph(Scene parent, RegionInfo regInfo)
|
protected internal SceneGraph(Scene parent)
|
||||||
{
|
{
|
||||||
m_parentScene = parent;
|
m_parentScene = parent;
|
||||||
m_regInfo = regInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsScene PhysicsScene
|
public PhysicsScene PhysicsScene
|
||||||
|
@ -122,7 +120,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// If we're not doing the initial set
|
// If we're not doing the initial set
|
||||||
// Then we've got to remove the previous
|
// Then we've got to remove the previous
|
||||||
// event handler
|
// event handler
|
||||||
|
|
||||||
if (_PhyScene != null)
|
if (_PhyScene != null)
|
||||||
_PhyScene.OnPhysicsCrash -= physicsBasedCrash;
|
_PhyScene.OnPhysicsCrash -= physicsBasedCrash;
|
||||||
|
|
||||||
|
@ -372,12 +369,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
|
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
|
||||||
// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
|
// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
|
||||||
|
|
||||||
SceneObjectPart[] children = sceneObject.Parts;
|
SceneObjectPart[] parts = sceneObject.Parts;
|
||||||
|
|
||||||
// Clamp child prim sizes and add child prims to the m_numPrim count
|
// Clamp child prim sizes and add child prims to the m_numPrim count
|
||||||
if (m_parentScene.m_clampPrimSize)
|
if (m_parentScene.m_clampPrimSize)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in children)
|
foreach (SceneObjectPart part in parts)
|
||||||
{
|
{
|
||||||
Vector3 scale = part.Shape.Scale;
|
Vector3 scale = part.Shape.Scale;
|
||||||
|
|
||||||
|
@ -391,7 +388,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
part.Shape.Scale = scale;
|
part.Shape.Scale = scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_numPrim += children.Length;
|
m_numPrim += parts.Length;
|
||||||
|
|
||||||
sceneObject.AttachToScene(m_parentScene);
|
sceneObject.AttachToScene(m_parentScene);
|
||||||
|
|
||||||
|
@ -411,15 +408,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
lock (SceneObjectGroupsByFullPartID)
|
lock (SceneObjectGroupsByFullPartID)
|
||||||
{
|
{
|
||||||
SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject;
|
foreach (SceneObjectPart part in parts)
|
||||||
foreach (SceneObjectPart part in children)
|
|
||||||
SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
|
SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (SceneObjectGroupsByLocalPartID)
|
lock (SceneObjectGroupsByLocalPartID)
|
||||||
{
|
{
|
||||||
SceneObjectGroupsByLocalPartID[sceneObject.LocalId] = sceneObject;
|
// m_log.DebugFormat(
|
||||||
foreach (SceneObjectPart part in children)
|
// "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}",
|
||||||
|
// sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
foreach (SceneObjectPart part in parts)
|
||||||
SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
|
SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,6 +431,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns>true if the object was deleted, false if there was no object to delete</returns>
|
/// <returns>true if the object was deleted, false if there was no object to delete</returns>
|
||||||
public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
|
public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE GRAPH]: Deleting scene object with uuid {0}, resultOfObjectLinked = {1}",
|
||||||
|
// uuid, resultOfObjectLinked);
|
||||||
|
|
||||||
EntityBase entity;
|
EntityBase entity;
|
||||||
if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup)))
|
if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup)))
|
||||||
return false;
|
return false;
|
||||||
|
@ -460,7 +463,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectPart[] parts = grp.Parts;
|
SceneObjectPart[] parts = grp.Parts;
|
||||||
for (int i = 0; i < parts.Length; i++)
|
for (int i = 0; i < parts.Length; i++)
|
||||||
SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
|
SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
|
||||||
SceneObjectGroupsByFullPartID.Remove(grp.RootPart.UUID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (SceneObjectGroupsByLocalPartID)
|
lock (SceneObjectGroupsByLocalPartID)
|
||||||
|
@ -468,7 +470,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectPart[] parts = grp.Parts;
|
SceneObjectPart[] parts = grp.Parts;
|
||||||
for (int i = 0; i < parts.Length; i++)
|
for (int i = 0; i < parts.Length; i++)
|
||||||
SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
|
SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
|
||||||
SceneObjectGroupsByLocalPartID.Remove(grp.RootPart.LocalId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Entities.Remove(uuid);
|
return Entities.Remove(uuid);
|
||||||
|
@ -589,7 +590,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScenePresence newAvatar = null;
|
ScenePresence newAvatar = null;
|
||||||
|
|
||||||
// ScenePresence always defaults to child agent
|
// ScenePresence always defaults to child agent
|
||||||
newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance, type);
|
newAvatar = new ScenePresence(client, m_parentScene, appearance, type);
|
||||||
|
|
||||||
AddScenePresence(newAvatar);
|
AddScenePresence(newAvatar);
|
||||||
|
|
||||||
|
@ -651,7 +652,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (!Entities.Remove(agentID))
|
if (!Entities.Remove(agentID))
|
||||||
{
|
{
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list",
|
"[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list",
|
||||||
agentID);
|
agentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
|
m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -881,7 +882,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (Entities.TryGetValue(localID, out entity))
|
if (Entities.TryGetValue(localID, out entity))
|
||||||
return entity as SceneObjectGroup;
|
return entity as SceneObjectGroup;
|
||||||
|
|
||||||
//m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID);
|
// m_log.DebugFormat("[SCENE GRAPH]: Entered GetGroupByPrim with localID {0}", localID);
|
||||||
|
|
||||||
SceneObjectGroup sog;
|
SceneObjectGroup sog;
|
||||||
lock (SceneObjectGroupsByLocalPartID)
|
lock (SceneObjectGroupsByLocalPartID)
|
||||||
SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
|
SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
|
||||||
|
@ -889,8 +891,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (sog != null)
|
if (sog != null)
|
||||||
{
|
{
|
||||||
if (sog.HasChildPrim(localID))
|
if (sog.HasChildPrim(localID))
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.",
|
||||||
|
// sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
|
||||||
|
|
||||||
return sog;
|
return sog;
|
||||||
SceneObjectGroupsByLocalPartID.Remove(localID);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (SceneObjectGroupsByLocalPartID)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.",
|
||||||
|
sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
SceneObjectGroupsByLocalPartID.Remove(localID);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityBase[] entityList = GetEntities();
|
EntityBase[] entityList = GetEntities();
|
||||||
|
|
|
@ -389,5 +389,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
for (int i = 0; i < parts.Length; i++)
|
for (int i = 0; i < parts.Length; i++)
|
||||||
parts[i].Inventory.ResumeScripts();
|
parts[i].Inventory.ResumeScripts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if any part in the scene object contains scripts, false otherwise.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool ContainsScripts()
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart part in Parts)
|
||||||
|
if (part.Inventory.ContainsScripts())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1599,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
|
ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
|
||||||
if (avatar != null)
|
if (avatar != null)
|
||||||
{
|
{
|
||||||
avatar.MoveToTarget(target, false);
|
avatar.MoveToTarget(target, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1728,8 +1728,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Scheduling
|
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
// Check that the group was not deleted before the scheduled update
|
// Check that the group was not deleted before the scheduled update
|
||||||
|
@ -1880,7 +1878,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
parts[i].SendTerseUpdateToAllClients();
|
parts[i].SendTerseUpdateToAllClients();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
/// <summary>
|
||||||
|
/// Send metadata about the root prim (name, description, sale price, etc.) to a client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
public void SendPropertiesToClient(IClientAPI client)
|
||||||
|
{
|
||||||
|
m_rootPart.SendPropertiesToClient(client);
|
||||||
|
}
|
||||||
|
|
||||||
#region SceneGroupPart Methods
|
#region SceneGroupPart Methods
|
||||||
|
|
||||||
|
@ -2369,15 +2374,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return metadata about a prim (name, description, sale price, etc.)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="client"></param>
|
|
||||||
public void GetProperties(IClientAPI client)
|
|
||||||
{
|
|
||||||
m_rootPart.GetProperties(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the name of a prim
|
/// Set the name of a prim
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1305,8 +1305,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#endregion Public Properties with only Get
|
#endregion Public Properties with only Get
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
private uint ApplyMask(uint val, bool set, uint mask)
|
private uint ApplyMask(uint val, bool set, uint mask)
|
||||||
{
|
{
|
||||||
if (set)
|
if (set)
|
||||||
|
@ -1327,14 +1325,27 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_updateFlag = 0;
|
m_updateFlag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendObjectPropertiesToClient(UUID AgentID)
|
/// <summary>
|
||||||
|
/// Send this part's properties (name, description, inventory serial, base mask, etc.) to a client
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
public void SendPropertiesToClient(IClientAPI client)
|
||||||
|
{
|
||||||
|
client.SendObjectPropertiesReply(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For the scene object group to which this part belongs, send that scene object's root part properties to a client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="AgentID"></param>
|
||||||
|
private void SendRootPartPropertiesToClient(UUID AgentID)
|
||||||
{
|
{
|
||||||
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
||||||
{
|
{
|
||||||
// Ugly reference :(
|
// Ugly reference :(
|
||||||
if (avatar.UUID == AgentID)
|
if (avatar.UUID == AgentID)
|
||||||
{
|
{
|
||||||
m_parentGroup.GetProperties(avatar.ControllingClient);
|
m_parentGroup.SendPropertiesToClient(avatar.ControllingClient);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1363,8 +1374,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
|
|
||||||
public void ResetExpire()
|
public void ResetExpire()
|
||||||
|
@ -1705,20 +1714,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Name, LocalId, id);
|
Name, LocalId, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SceneObjectPart Create()
|
|
||||||
{
|
|
||||||
SceneObjectPart part = new SceneObjectPart();
|
|
||||||
part.UUID = UUID.Random();
|
|
||||||
|
|
||||||
PrimitiveBaseShape shape = PrimitiveBaseShape.Create();
|
|
||||||
part.Shape = shape;
|
|
||||||
|
|
||||||
part.Name = "Primitive";
|
|
||||||
part._ownerID = UUID.Random();
|
|
||||||
|
|
||||||
return part;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Do a physics property update for a NINJA joint.
|
/// Do a physics property update for a NINJA joint.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2030,11 +2025,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return Vector3.Zero;
|
return Vector3.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetProperties(IClientAPI client)
|
|
||||||
{
|
|
||||||
client.SendObjectPropertiesReply(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Method for a prim to get it's world position from the group.
|
/// Method for a prim to get it's world position from the group.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3453,7 +3443,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
_groupID = groupID;
|
_groupID = groupID;
|
||||||
if (client != null)
|
if (client != null)
|
||||||
GetProperties(client);
|
SendPropertiesToClient(client);
|
||||||
m_updateFlag = 2;
|
m_updateFlag = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4273,10 +4263,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendFullUpdateToAllClients();
|
SendFullUpdateToAllClients();
|
||||||
|
|
||||||
SendObjectPropertiesToClient(AgentID);
|
SendRootPartPropertiesToClient(AgentID);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -784,6 +784,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
private bool CreateInventoryFile()
|
private bool CreateInventoryFile()
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}",
|
||||||
|
// m_part.Name, m_part.UUID, m_part.LocalId, m_inventorySerial);
|
||||||
|
|
||||||
if (m_inventoryFileName == String.Empty ||
|
if (m_inventoryFileName == String.Empty ||
|
||||||
m_inventoryFileNameSerial < m_inventorySerial)
|
m_inventoryFileNameSerial < m_inventorySerial)
|
||||||
{
|
{
|
||||||
|
@ -797,6 +801,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
foreach (TaskInventoryItem item in m_items.Values)
|
foreach (TaskInventoryItem item in m_items.Values)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}",
|
||||||
|
// item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId);
|
||||||
|
|
||||||
UUID ownerID = item.OwnerID;
|
UUID ownerID = item.OwnerID;
|
||||||
uint everyoneMask = 0;
|
uint everyoneMask = 0;
|
||||||
uint baseMask = item.BasePermissions;
|
uint baseMask = item.BasePermissions;
|
||||||
|
@ -856,28 +864,43 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="xferManager"></param>
|
/// <param name="xferManager"></param>
|
||||||
public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
|
public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
|
||||||
{
|
{
|
||||||
CreateInventoryFile();
|
lock (m_items)
|
||||||
|
|
||||||
if (m_inventorySerial == 0) // No inventory
|
|
||||||
{
|
{
|
||||||
client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
|
// Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing
|
||||||
return;
|
// a new script if any previous deletion has left the prim inventory empty.
|
||||||
|
if (m_items.Count == 0) // No inventory
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items",
|
||||||
|
// m_part.Name, m_part.LocalId, m_part.UUID, client.Name);
|
||||||
|
|
||||||
|
client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateInventoryFile();
|
||||||
|
|
||||||
|
// In principle, we should only do the rest if the inventory changed;
|
||||||
|
// by sending m_inventorySerial to the client, it ought to know
|
||||||
|
// that nothing changed and that it doesn't need to request the file.
|
||||||
|
// Unfortunately, it doesn't look like the client optimizes this;
|
||||||
|
// the client seems to always come back and request the Xfer,
|
||||||
|
// no matter what value m_inventorySerial has.
|
||||||
|
// FIXME: Could probably be > 0 here rather than > 2
|
||||||
|
if (m_inventoryFileData.Length > 2)
|
||||||
|
{
|
||||||
|
// Add the file for Xfer
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}",
|
||||||
|
// m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId);
|
||||||
|
|
||||||
|
xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the client we're ready to Xfer the file
|
||||||
|
client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
|
||||||
|
Util.StringToBytes256(m_inventoryFileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// In principle, we should only do the rest if the inventory changed;
|
|
||||||
// by sending m_inventorySerial to the client, it ought to know
|
|
||||||
// that nothing changed and that it doesn't need to request the file.
|
|
||||||
// Unfortunately, it doesn't look like the client optimizes this;
|
|
||||||
// the client seems to always come back and request the Xfer,
|
|
||||||
// no matter what value m_inventorySerial has.
|
|
||||||
|
|
||||||
if (m_inventoryFileData.Length > 2)
|
|
||||||
// Add the file for Xfer
|
|
||||||
xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
|
|
||||||
|
|
||||||
// Tell the client we're ready to Xfer the file
|
|
||||||
client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
|
|
||||||
Util.StringToBytes256(m_inventoryFileName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1035,10 +1058,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
item.BasePermissions = perms;
|
item.BasePermissions = perms;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inventorySerial++;
|
m_inventorySerial++;
|
||||||
HasInventoryChanged = true;
|
HasInventoryChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this part inventory contains any scripts. False otherwise.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
public bool ContainsScripts()
|
public bool ContainsScripts()
|
||||||
{
|
{
|
||||||
lock (m_items)
|
lock (m_items)
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
// ~ScenePresence()
|
// ~ScenePresence()
|
||||||
// {
|
// {
|
||||||
// m_log.Debug("[ScenePresence] Destructor called");
|
// m_log.Debug("[SCENE PRESENCE] Destructor called");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -120,6 +120,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
|
protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
|
||||||
|
|
||||||
|
public Object AttachmentsSyncLock { get; private set; }
|
||||||
|
|
||||||
private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
|
private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
|
||||||
private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
|
private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
|
||||||
private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
|
private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
|
||||||
|
@ -176,8 +178,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
private Quaternion m_bodyRot = Quaternion.Identity;
|
private Quaternion m_bodyRot = Quaternion.Identity;
|
||||||
|
|
||||||
private Quaternion m_bodyRotPrevious = Quaternion.Identity;
|
|
||||||
|
|
||||||
private const int LAND_VELOCITYMAG_MAX = 12;
|
private const int LAND_VELOCITYMAG_MAX = 12;
|
||||||
|
|
||||||
public bool IsRestrictedToRegion;
|
public bool IsRestrictedToRegion;
|
||||||
|
@ -186,7 +186,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
private float m_health = 100f;
|
private float m_health = 100f;
|
||||||
|
|
||||||
protected RegionInfo m_regionInfo;
|
|
||||||
protected ulong crossingFromRegion;
|
protected ulong crossingFromRegion;
|
||||||
|
|
||||||
private readonly Vector3[] Dir_Vectors = new Vector3[9];
|
private readonly Vector3[] Dir_Vectors = new Vector3[9];
|
||||||
|
@ -221,6 +220,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public bool MovingToTarget { get; private set; }
|
public bool MovingToTarget { get; private set; }
|
||||||
public Vector3 MoveToPositionTarget { get; private set; }
|
public Vector3 MoveToPositionTarget { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controls whether an avatar automatically moving to a target will land when it gets there (if flying).
|
||||||
|
/// </summary>
|
||||||
|
public bool LandAtTarget { get; private set; }
|
||||||
|
|
||||||
private bool m_followCamAuto;
|
private bool m_followCamAuto;
|
||||||
|
|
||||||
private int m_movementUpdateCount;
|
private int m_movementUpdateCount;
|
||||||
|
@ -466,7 +470,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
PhysicsActor actor = m_physicsActor;
|
PhysicsActor actor = m_physicsActor;
|
||||||
if (actor != null)
|
if (actor != null)
|
||||||
|
{
|
||||||
m_pos = actor.Position;
|
m_pos = actor.Position;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!",
|
||||||
|
// m_pos, Name, Scene.RegionInfo.RegionName);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Obtain the correct position of a seated avatar.
|
// Obtain the correct position of a seated avatar.
|
||||||
|
@ -510,19 +520,26 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message);
|
m_log.Error("[SCENE PRESENCE]: ABSOLUTE POSITION " + e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pos = value;
|
m_pos = value;
|
||||||
m_parentPosition = Vector3.Zero;
|
m_parentPosition = Vector3.Zero;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
|
||||||
|
// Scene.RegionInfo.RegionName, Name, m_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If sitting, returns the offset position from the prim the avatar is sitting on.
|
||||||
|
/// Otherwise, returns absolute position in the scene.
|
||||||
|
/// </summary>
|
||||||
public Vector3 OffsetPosition
|
public Vector3 OffsetPosition
|
||||||
{
|
{
|
||||||
get { return m_pos; }
|
get { return m_pos; }
|
||||||
set { m_pos = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -534,8 +551,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
PhysicsActor actor = m_physicsActor;
|
PhysicsActor actor = m_physicsActor;
|
||||||
if (actor != null)
|
if (actor != null)
|
||||||
|
{
|
||||||
m_velocity = actor.Velocity;
|
m_velocity = actor.Velocity;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
|
||||||
|
// m_velocity, Name, Scene.RegionInfo.RegionName);
|
||||||
|
}
|
||||||
|
|
||||||
return m_velocity;
|
return m_velocity;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
|
@ -550,24 +573,26 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message);
|
m_log.Error("[SCENE PRESENCE]: VELOCITY " + e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_velocity = value;
|
m_velocity = value;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE PRESENCE]: In {0} set velocity of {1} to {2}",
|
||||||
|
// Scene.RegionInfo.RegionName, Name, m_velocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Quaternion Rotation
|
public Quaternion Rotation
|
||||||
{
|
{
|
||||||
get { return m_bodyRot; }
|
get { return m_bodyRot; }
|
||||||
set { m_bodyRot = value; }
|
set
|
||||||
}
|
{
|
||||||
|
m_bodyRot = value;
|
||||||
public Quaternion PreviousRotation
|
// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
|
||||||
{
|
}
|
||||||
get { return m_bodyRotPrevious; }
|
|
||||||
set { m_bodyRotPrevious = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -705,23 +730,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructor(s)
|
#region Constructor(s)
|
||||||
|
|
||||||
public ScenePresence(
|
public ScenePresence(
|
||||||
IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type)
|
IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
|
||||||
{
|
{
|
||||||
|
AttachmentsSyncLock = new Object();
|
||||||
|
|
||||||
m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
|
m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
|
||||||
m_sceneViewer = new SceneViewer(this);
|
m_sceneViewer = new SceneViewer(this);
|
||||||
m_animator = new ScenePresenceAnimator(this);
|
m_animator = new ScenePresenceAnimator(this);
|
||||||
PresenceType = type;
|
PresenceType = type;
|
||||||
m_DrawDistance = world.DefaultDrawDistance;
|
m_DrawDistance = world.DefaultDrawDistance;
|
||||||
m_rootRegionHandle = reginfo.RegionHandle;
|
m_rootRegionHandle = world.RegionInfo.RegionHandle;
|
||||||
m_controllingClient = client;
|
m_controllingClient = client;
|
||||||
m_firstname = m_controllingClient.FirstName;
|
m_firstname = m_controllingClient.FirstName;
|
||||||
m_lastname = m_controllingClient.LastName;
|
m_lastname = m_controllingClient.LastName;
|
||||||
m_name = String.Format("{0} {1}", m_firstname, m_lastname);
|
m_name = String.Format("{0} {1}", m_firstname, m_lastname);
|
||||||
m_scene = world;
|
m_scene = world;
|
||||||
m_uuid = client.AgentId;
|
m_uuid = client.AgentId;
|
||||||
m_regionInfo = reginfo;
|
|
||||||
m_localId = m_scene.AllocateLocalId();
|
m_localId = m_scene.AllocateLocalId();
|
||||||
|
|
||||||
UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
|
UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
|
||||||
|
@ -983,7 +1009,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Animator.ResetAnimations();
|
Animator.ResetAnimations();
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
|
// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
|
||||||
// Name, UUID, m_scene.RegionInfo.RegionName);
|
// Name, UUID, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
// Don't zero out the velocity since this can cause problems when an avatar is making a region crossing,
|
// Don't zero out the velocity since this can cause problems when an avatar is making a region crossing,
|
||||||
|
@ -1150,9 +1176,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_callbackURI = null;
|
m_callbackURI = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_log.DebugFormat("Completed movement");
|
//m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
|
||||||
|
|
||||||
m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look);
|
m_controllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
|
||||||
SendInitialData();
|
SendInitialData();
|
||||||
|
|
||||||
// Create child agents in neighbouring regions
|
// Create child agents in neighbouring regions
|
||||||
|
@ -1217,7 +1243,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
|
public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE PRESENCE]: In {0} received agent update from {1}",
|
||||||
|
// Scene.RegionInfo.RegionName, remoteClient.Name);
|
||||||
|
|
||||||
//if (m_isChildAgent)
|
//if (m_isChildAgent)
|
||||||
//{
|
//{
|
||||||
|
@ -1658,7 +1686,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// This is to allow movement to targets that are known to be on an elevated platform with a continuous path
|
/// This is to allow movement to targets that are known to be on an elevated platform with a continuous path
|
||||||
/// from start to finish.
|
/// from start to finish.
|
||||||
/// </param>
|
/// </param>
|
||||||
public void MoveToTarget(Vector3 pos, bool noFly)
|
/// <param name="landAtTarget">
|
||||||
|
/// If true and the avatar starts flying during the move then land at the target.
|
||||||
|
/// </param>
|
||||||
|
public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[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}",
|
||||||
|
@ -1684,7 +1715,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// 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
|
||||||
// always slightly higher than the actual terrain height.
|
// always slightly higher than the actual terrain height.
|
||||||
// FIXME: This constrains NOC movements as well, so should be somewhere else.
|
// FIXME: This constrains NPC movements as well, so should be somewhere else.
|
||||||
if (pos.Z - terrainHeight < 0.2)
|
if (pos.Z - terrainHeight < 0.2)
|
||||||
pos.Z = terrainHeight;
|
pos.Z = terrainHeight;
|
||||||
|
|
||||||
|
@ -1697,9 +1728,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
else if (pos.Z > terrainHeight)
|
else if (pos.Z > terrainHeight)
|
||||||
PhysicsActor.Flying = true;
|
PhysicsActor.Flying = true;
|
||||||
|
|
||||||
|
LandAtTarget = landAtTarget;
|
||||||
MovingToTarget = true;
|
MovingToTarget = true;
|
||||||
MoveToPositionTarget = pos;
|
MoveToPositionTarget = pos;
|
||||||
|
|
||||||
|
// Rotate presence around the z-axis to point in same direction as movement.
|
||||||
|
// Ignore z component of vector
|
||||||
|
Vector3 localVectorToTarget3D = pos - AbsolutePosition;
|
||||||
|
Vector3 localVectorToTarget2D = new Vector3((float)(localVectorToTarget3D.X), (float)(localVectorToTarget3D.Y), 0f);
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0}", localVectorToTarget2D);
|
||||||
|
|
||||||
|
// Calculate the yaw.
|
||||||
|
Vector3 angle = new Vector3(0, 0, (float)(Math.Atan2(localVectorToTarget2D.Y, localVectorToTarget2D.X)));
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[SCENE PRESENCE]: Angle is {0}", angle);
|
||||||
|
|
||||||
|
Rotation = Quaternion.CreateFromEulers(angle);
|
||||||
|
// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation);
|
||||||
|
|
||||||
Vector3 agent_control_v3 = new Vector3();
|
Vector3 agent_control_v3 = new Vector3();
|
||||||
HandleMoveToTargetUpdate(ref agent_control_v3);
|
HandleMoveToTargetUpdate(ref agent_control_v3);
|
||||||
AddNewMovement(agent_control_v3);
|
AddNewMovement(agent_control_v3);
|
||||||
|
@ -2389,7 +2436,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Vector3 pos = m_pos;
|
Vector3 pos = m_pos;
|
||||||
pos.Z += m_appearance.HipOffset;
|
pos.Z += m_appearance.HipOffset;
|
||||||
|
|
||||||
//m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
|
//m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
|
||||||
|
|
||||||
remoteClient.SendPrimUpdate(
|
remoteClient.SendPrimUpdate(
|
||||||
this,
|
this,
|
||||||
|
@ -2476,6 +2523,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void SendInitialData()
|
private void SendInitialData()
|
||||||
{
|
{
|
||||||
|
//m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID);
|
||||||
// Moved this into CompleteMovement to ensure that m_appearance is initialized before
|
// Moved this into CompleteMovement to ensure that m_appearance is initialized before
|
||||||
// the inventory arrives
|
// the inventory arrives
|
||||||
// m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
|
// m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
|
||||||
|
@ -2520,10 +2568,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendAvatarDataToAllAgents()
|
public void SendAvatarDataToAllAgents()
|
||||||
{
|
{
|
||||||
|
//m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID);
|
||||||
// only send update from root agents to other clients; children are only "listening posts"
|
// only send update from root agents to other clients; children are only "listening posts"
|
||||||
if (IsChildAgent)
|
if (IsChildAgent)
|
||||||
{
|
{
|
||||||
m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent");
|
m_log.Warn("[SCENE PRESENCE] attempt to send avatar data from a child agent");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2573,7 +2622,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="avatar"></param>
|
/// <param name="avatar"></param>
|
||||||
public void SendAvatarDataToAgent(ScenePresence avatar)
|
public void SendAvatarDataToAgent(ScenePresence avatar)
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
|
//m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID);
|
||||||
|
|
||||||
avatar.ControllingClient.SendAvatarDataImmediate(this);
|
avatar.ControllingClient.SendAvatarDataImmediate(this);
|
||||||
if (Animator != null)
|
if (Animator != null)
|
||||||
|
@ -2586,10 +2635,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendAppearanceToAllOtherAgents()
|
public void SendAppearanceToAllOtherAgents()
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} ({1})", Name, UUID);
|
||||||
// only send update from root agents to other clients; children are only "listening posts"
|
// only send update from root agents to other clients; children are only "listening posts"
|
||||||
if (IsChildAgent)
|
if (IsChildAgent)
|
||||||
{
|
{
|
||||||
m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent");
|
m_log.Warn("[SCENE PRESENCE] attempt to send avatar data from a child agent");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2615,6 +2665,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendOtherAgentsAppearanceToMe()
|
public void SendOtherAgentsAppearanceToMe()
|
||||||
{
|
{
|
||||||
|
//m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} ({1})", Name, UUID);
|
||||||
m_perfMonMS = Util.EnvironmentTickCount();
|
m_perfMonMS = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -2873,8 +2924,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </returns>
|
/// </returns>
|
||||||
protected int HaveNeighbor(Cardinals car, ref int[] fix)
|
protected int HaveNeighbor(Cardinals car, ref int[] fix)
|
||||||
{
|
{
|
||||||
uint neighbourx = m_regionInfo.RegionLocX;
|
uint neighbourx = m_scene.RegionInfo.RegionLocX;
|
||||||
uint neighboury = m_regionInfo.RegionLocY;
|
uint neighboury = m_scene.RegionInfo.RegionLocY;
|
||||||
|
|
||||||
int dir = (int)car;
|
int dir = (int)car;
|
||||||
|
|
||||||
|
@ -2894,8 +2945,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (neighbourRegion == null)
|
if (neighbourRegion == null)
|
||||||
{
|
{
|
||||||
fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx);
|
fix[0] = (int)(m_scene.RegionInfo.RegionLocX - neighbourx);
|
||||||
fix[1] = (int)(m_regionInfo.RegionLocY - neighboury);
|
fix[1] = (int)(m_scene.RegionInfo.RegionLocY - neighboury);
|
||||||
return dir * (-1);
|
return dir * (-1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3141,26 +3192,30 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
// Attachment objects
|
// Attachment objects
|
||||||
if (m_attachments != null && m_attachments.Count > 0)
|
lock (m_attachments)
|
||||||
{
|
{
|
||||||
cAgent.AttachmentObjects = new List<ISceneObject>();
|
if (m_attachments.Count > 0)
|
||||||
cAgent.AttachmentObjectStates = new List<string>();
|
|
||||||
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
|
||||||
m_InTransitScriptStates.Clear();
|
|
||||||
foreach (SceneObjectGroup sog in m_attachments)
|
|
||||||
{
|
{
|
||||||
// We need to make a copy and pass that copy
|
cAgent.AttachmentObjects = new List<ISceneObject>();
|
||||||
// because of transfers withn the same sim
|
cAgent.AttachmentObjectStates = new List<string>();
|
||||||
ISceneObject clone = sog.CloneForNewScene();
|
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
||||||
// Attachment module assumes that GroupPosition holds the offsets...!
|
m_InTransitScriptStates.Clear();
|
||||||
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
|
|
||||||
((SceneObjectGroup)clone).IsAttachment = false;
|
foreach (SceneObjectGroup sog in m_attachments)
|
||||||
cAgent.AttachmentObjects.Add(clone);
|
{
|
||||||
string state = sog.GetStateSnapshot();
|
// We need to make a copy and pass that copy
|
||||||
cAgent.AttachmentObjectStates.Add(state);
|
// because of transfers withn the same sim
|
||||||
m_InTransitScriptStates.Add(state);
|
ISceneObject clone = sog.CloneForNewScene();
|
||||||
// Let's remove the scripts of the original object here
|
// Attachment module assumes that GroupPosition holds the offsets...!
|
||||||
sog.RemoveScriptInstances(true);
|
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
|
||||||
|
((SceneObjectGroup)clone).IsAttachment = false;
|
||||||
|
cAgent.AttachmentObjects.Add(clone);
|
||||||
|
string state = sog.GetStateSnapshot();
|
||||||
|
cAgent.AttachmentObjectStates.Add(state);
|
||||||
|
m_InTransitScriptStates.Add(state);
|
||||||
|
// Let's remove the scripts of the original object here
|
||||||
|
sog.RemoveScriptInstances(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3277,6 +3332,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void AddToPhysicalScene(bool isFlying)
|
public void AddToPhysicalScene(bool isFlying)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE PRESENCE]: Adding physics actor for {0}, ifFlying = {1} in {2}",
|
||||||
|
// Name, isFlying, Scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
if (m_appearance.AvatarHeight == 0)
|
if (m_appearance.AvatarHeight == 0)
|
||||||
m_appearance.SetHeight();
|
m_appearance.SetHeight();
|
||||||
|
|
||||||
|
@ -3317,7 +3376,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
//if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
|
//if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
|
||||||
// The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
|
// The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
|
||||||
// as of this comment the interval is set in AddToPhysicalScene
|
// as of this comment the interval is set in AddToPhysicalScene
|
||||||
if (Animator!=null)
|
if (Animator != null)
|
||||||
Animator.UpdateMovementAnimations();
|
Animator.UpdateMovementAnimations();
|
||||||
|
|
||||||
CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
|
CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
|
||||||
|
@ -3398,7 +3457,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
|
if (!IsChildAgent)
|
||||||
|
m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
|
||||||
|
|
||||||
lock (m_knownChildRegions)
|
lock (m_knownChildRegions)
|
||||||
{
|
{
|
||||||
|
@ -3501,8 +3561,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is currently just being done for information.
|
/// This is currently just being done for information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ValidateAttachments()
|
public bool ValidateAttachments()
|
||||||
{
|
{
|
||||||
|
bool validated = true;
|
||||||
|
|
||||||
lock (m_attachments)
|
lock (m_attachments)
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
|
@ -3512,15 +3574,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name);
|
"[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name);
|
||||||
|
|
||||||
|
validated = false;
|
||||||
}
|
}
|
||||||
else if (gobj.IsDeleted)
|
else if (gobj.IsDeleted)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing",
|
"[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing",
|
||||||
gobj.Name, gobj.UUID, Name);
|
gobj.Name, gobj.UUID, Name);
|
||||||
|
|
||||||
|
validated = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return validated;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3552,29 +3620,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene)
|
|
||||||
{
|
|
||||||
m_controllingClient = client;
|
|
||||||
m_regionInfo = region;
|
|
||||||
m_scene = scene;
|
|
||||||
|
|
||||||
RegisterToEvents();
|
|
||||||
|
|
||||||
/*
|
|
||||||
AbsolutePosition = client.StartPos;
|
|
||||||
|
|
||||||
Animations = new AvatarAnimations();
|
|
||||||
Animations.LoadAnims();
|
|
||||||
|
|
||||||
m_animations = new List<UUID>();
|
|
||||||
m_animations.Add(Animations.AnimsUUID["STAND"]);
|
|
||||||
m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber);
|
|
||||||
|
|
||||||
SetDirectionVectors();
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void PushForce(Vector3 impulse)
|
internal void PushForce(Vector3 impulse)
|
||||||
{
|
{
|
||||||
if (PhysicsActor != null)
|
if (PhysicsActor != null)
|
||||||
|
@ -3602,6 +3647,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
obj.ignoreControls = (ScriptControlled)controls;
|
obj.ignoreControls = (ScriptControlled)controls;
|
||||||
obj.eventControls = (ScriptControlled)controls;
|
obj.eventControls = (ScriptControlled)controls;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pass_on == 1 && accept == 1)
|
if (pass_on == 1 && accept == 1)
|
||||||
{
|
{
|
||||||
IgnoredControls = ScriptControlled.CONTROL_ZERO;
|
IgnoredControls = ScriptControlled.CONTROL_ZERO;
|
||||||
|
@ -3622,6 +3668,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
scriptedcontrols[Script_item_UUID] = obj;
|
scriptedcontrols[Script_item_UUID] = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
|
ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3803,4 +3850,4 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,22 +52,25 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
|
|
||||||
Scene scene = SceneHelpers.SetupScene();
|
Scene scene = SceneHelpers.SetupScene();
|
||||||
|
int partsToTestCount = 3;
|
||||||
|
|
||||||
string objName = "obj1";
|
SceneObjectGroup so
|
||||||
UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
|
= SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
|
||||||
|
SceneObjectPart[] parts = so.Parts;
|
||||||
|
|
||||||
SceneObjectPart part
|
Assert.That(scene.AddNewSceneObject(so, false), Is.True);
|
||||||
= new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
|
SceneObjectGroup retrievedSo = scene.GetSceneObjectGroup(so.UUID);
|
||||||
{ Name = objName, UUID = objUuid };
|
SceneObjectPart[] retrievedParts = retrievedSo.Parts;
|
||||||
|
|
||||||
Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True);
|
|
||||||
|
|
||||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid);
|
|
||||||
|
|
||||||
//m_log.Debug("retrievedPart : {0}", retrievedPart);
|
//m_log.Debug("retrievedPart : {0}", retrievedPart);
|
||||||
// If the parts have the same UUID then we will consider them as one and the same
|
// If the parts have the same UUID then we will consider them as one and the same
|
||||||
Assert.That(retrievedPart.Name, Is.EqualTo(objName));
|
Assert.That(retrievedSo.PrimCount, Is.EqualTo(partsToTestCount));
|
||||||
Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
|
|
||||||
|
for (int i = 0; i < partsToTestCount; i++)
|
||||||
|
{
|
||||||
|
Assert.That(retrievedParts[i].Name, Is.EqualTo(parts[i].Name));
|
||||||
|
Assert.That(retrievedParts[i].UUID, Is.EqualTo(parts[i].UUID));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -103,6 +106,39 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||||
Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name));
|
Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name));
|
||||||
Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
|
Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test retrieving a scene object via the local id of one of its parts.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestGetSceneObjectByPartLocalId()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
|
||||||
|
Scene scene = SceneHelpers.SetupScene();
|
||||||
|
int partsToTestCount = 3;
|
||||||
|
|
||||||
|
SceneObjectGroup so
|
||||||
|
= SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
|
||||||
|
SceneObjectPart[] parts = so.Parts;
|
||||||
|
|
||||||
|
scene.AddNewSceneObject(so, false);
|
||||||
|
|
||||||
|
// Test getting via the root part's local id
|
||||||
|
Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Not.Null);
|
||||||
|
|
||||||
|
// Test getting via a non root part's local id
|
||||||
|
Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Not.Null);
|
||||||
|
|
||||||
|
// Test that we don't get back an object for a local id that doesn't exist
|
||||||
|
Assert.That(scene.GetGroupByPrim(999), Is.Null);
|
||||||
|
|
||||||
|
// Now delete the scene object and check again
|
||||||
|
scene.DeleteSceneObject(so, false);
|
||||||
|
|
||||||
|
Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Null);
|
||||||
|
Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Null);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test deleting an object from a scene.
|
/// Test deleting an object from a scene.
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Communications;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Framework.Scenes.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ScenePresenceAutopilotTests
|
||||||
|
{
|
||||||
|
private TestScene m_scene;
|
||||||
|
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public void FixtureInit()
|
||||||
|
{
|
||||||
|
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||||
|
Util.FireAndForgetMethod = FireAndForgetMethod.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestFixtureTearDown]
|
||||||
|
public void TearDown()
|
||||||
|
{
|
||||||
|
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||||
|
// threads. Possibly, later tests should be rewritten not to worry about such things.
|
||||||
|
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
m_scene = SceneHelpers.SetupScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMove()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
|
||||||
|
|
||||||
|
Vector3 startPos = sp.AbsolutePosition;
|
||||||
|
// Vector3 startPos = new Vector3(128, 128, 30);
|
||||||
|
|
||||||
|
// For now, we'll make the scene presence fly to simplify this test, but this needs to change.
|
||||||
|
sp.PhysicsActor.Flying = true;
|
||||||
|
|
||||||
|
m_scene.Update();
|
||||||
|
Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
|
||||||
|
|
||||||
|
Vector3 targetPos = startPos + new Vector3(0, 10, 0);
|
||||||
|
sp.MoveToTarget(targetPos, false, false);
|
||||||
|
|
||||||
|
Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
|
||||||
|
Assert.That(
|
||||||
|
sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
|
||||||
|
|
||||||
|
m_scene.Update();
|
||||||
|
|
||||||
|
// We should really check the exact figure.
|
||||||
|
Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X));
|
||||||
|
Assert.That(sp.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
|
||||||
|
Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
|
||||||
|
Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X));
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
m_scene.Update();
|
||||||
|
|
||||||
|
double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
|
||||||
|
Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move");
|
||||||
|
Assert.That(sp.AbsolutePosition, Is.EqualTo(targetPos));
|
||||||
|
Assert.That(sp.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE));
|
||||||
|
|
||||||
|
// Try a second movement
|
||||||
|
startPos = sp.AbsolutePosition;
|
||||||
|
targetPos = startPos + new Vector3(10, 0, 0);
|
||||||
|
sp.MoveToTarget(targetPos, false, false);
|
||||||
|
|
||||||
|
Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
|
||||||
|
Assert.That(
|
||||||
|
sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
|
||||||
|
|
||||||
|
m_scene.Update();
|
||||||
|
|
||||||
|
// We should really check the exact figure.
|
||||||
|
Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X));
|
||||||
|
Assert.That(sp.AbsolutePosition.X, Is.LessThan(targetPos.X));
|
||||||
|
Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
|
||||||
|
Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
m_scene.Update();
|
||||||
|
|
||||||
|
distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
|
||||||
|
Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move");
|
||||||
|
Assert.That(sp.AbsolutePosition, Is.EqualTo(targetPos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,11 +43,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gather uuids for a given entity.
|
/// Gather uuids for a given entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
/// <remarks>
|
||||||
/// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts
|
/// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts
|
||||||
/// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets
|
/// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets
|
||||||
/// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be
|
/// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be
|
||||||
/// retrieved to work out which assets it references).
|
/// retrieved to work out which assets it references).
|
||||||
|
/// </remarks>
|
||||||
public class UuidGatherer
|
public class UuidGatherer
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -76,11 +77,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gather all the asset uuids associated with the asset referenced by a given uuid
|
/// Gather all the asset uuids associated with the asset referenced by a given uuid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
/// <remarks>
|
||||||
/// This includes both those directly associated with
|
/// This includes both those directly associated with
|
||||||
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
|
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
|
||||||
/// within this object).
|
/// within this object).
|
||||||
///
|
/// </remarks>
|
||||||
/// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
|
/// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
|
||||||
/// <param name="assetType">The type of the asset for the uuid given</param>
|
/// <param name="assetType">The type of the asset for the uuid given</param>
|
||||||
/// <param name="assetUuids">The assets gathered</param>
|
/// <param name="assetUuids">The assets gathered</param>
|
||||||
|
@ -123,11 +124,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gather all the asset uuids associated with a given object.
|
/// Gather all the asset uuids associated with a given object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
/// <remarks>
|
||||||
/// This includes both those directly associated with
|
/// This includes both those directly associated with
|
||||||
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
|
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
|
||||||
/// within this object).
|
/// within this object).
|
||||||
///
|
/// </remarks>
|
||||||
/// <param name="sceneObject">The scene object for which to gather assets</param>
|
/// <param name="sceneObject">The scene object for which to gather assets</param>
|
||||||
/// <param name="assetUuids">The assets gathered</param>
|
/// <param name="assetUuids">The assets gathered</param>
|
||||||
public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids)
|
public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids)
|
||||||
|
|
|
@ -806,7 +806,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
public event ScriptReset OnScriptReset;
|
public event ScriptReset OnScriptReset;
|
||||||
public event GetScriptRunning OnGetScriptRunning;
|
public event GetScriptRunning OnGetScriptRunning;
|
||||||
public event SetScriptRunning OnSetScriptRunning;
|
public event SetScriptRunning OnSetScriptRunning;
|
||||||
public event Action<Vector3, bool> OnAutoPilotGo;
|
public event Action<Vector3, bool, bool> OnAutoPilotGo;
|
||||||
public event TerrainUnacked OnUnackedTerrain;
|
public event TerrainUnacked OnUnackedTerrain;
|
||||||
public event ActivateGesture OnActivateGesture;
|
public event ActivateGesture OnActivateGesture;
|
||||||
public event DeactivateGesture OnDeactivateGesture;
|
public event DeactivateGesture OnDeactivateGesture;
|
||||||
|
|
|
@ -37,11 +37,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
public class NPCAvatar : IClientAPI
|
public class NPCAvatar : IClientAPI
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Signal whether the avatar should land when it reaches a move target
|
|
||||||
/// </summary>
|
|
||||||
public bool LandAtTarget { get; set; }
|
|
||||||
|
|
||||||
private readonly string m_firstname;
|
private readonly string m_firstname;
|
||||||
private readonly string m_lastname;
|
private readonly string m_lastname;
|
||||||
private readonly Vector3 m_startPos;
|
private readonly Vector3 m_startPos;
|
||||||
|
@ -333,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
public event ScriptReset OnScriptReset;
|
public event ScriptReset OnScriptReset;
|
||||||
public event GetScriptRunning OnGetScriptRunning;
|
public event GetScriptRunning OnGetScriptRunning;
|
||||||
public event SetScriptRunning OnSetScriptRunning;
|
public event SetScriptRunning OnSetScriptRunning;
|
||||||
public event Action<Vector3, bool> OnAutoPilotGo;
|
public event Action<Vector3, bool, bool> OnAutoPilotGo;
|
||||||
|
|
||||||
public event TerrainUnacked OnUnackedTerrain;
|
public event TerrainUnacked OnUnackedTerrain;
|
||||||
|
|
||||||
|
|
|
@ -53,78 +53,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
if (config != null && config.GetBoolean("Enabled", false))
|
if (config != null && config.GetBoolean("Enabled", false))
|
||||||
{
|
{
|
||||||
scene.RegisterModuleInterface<INPCModule>(this);
|
scene.RegisterModuleInterface<INPCModule>(this);
|
||||||
scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HandleOnSignificantClientMovement(ScenePresence presence)
|
|
||||||
{
|
|
||||||
lock (m_avatars)
|
|
||||||
{
|
|
||||||
if (m_avatars.ContainsKey(presence.UUID) && presence.MovingToTarget)
|
|
||||||
{
|
|
||||||
double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[NPC MODULE]: Abs pos of {0} is {1}, target {2}, distance {3}",
|
|
||||||
// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
|
|
||||||
|
|
||||||
// Check the error term of the current position in relation to the target position
|
|
||||||
if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
|
|
||||||
{
|
|
||||||
// We are close enough to the target
|
|
||||||
m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name);
|
|
||||||
|
|
||||||
presence.Velocity = Vector3.Zero;
|
|
||||||
presence.AbsolutePosition = presence.MoveToPositionTarget;
|
|
||||||
presence.ResetMoveToTarget();
|
|
||||||
|
|
||||||
if (presence.PhysicsActor.Flying)
|
|
||||||
{
|
|
||||||
// A horrible hack to stop the NPC dead in its tracks rather than having them overshoot
|
|
||||||
// the target if flying.
|
|
||||||
// We really need to be more subtle (slow the avatar as it approaches the target) or at
|
|
||||||
// least be able to set collision status once, rather than 5 times to give it enough
|
|
||||||
// weighting so that that PhysicsActor thinks it really is colliding.
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
presence.PhysicsActor.IsColliding = true;
|
|
||||||
|
|
||||||
// Vector3 targetPos = presence.MoveToPositionTarget;
|
|
||||||
if (m_avatars[presence.UUID].LandAtTarget)
|
|
||||||
presence.PhysicsActor.Flying = false;
|
|
||||||
|
|
||||||
// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
|
|
||||||
// if (targetPos.Z - terrainHeight < 0.2)
|
|
||||||
// {
|
|
||||||
// presence.PhysicsActor.Flying = false;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[NPC MODULE]: AgentControlFlags {0}, MovementFlag {1} for {2}",
|
|
||||||
// presence.AgentControlFlags, presence.MovementFlag, presence.Name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[NPC MODULE]: Updating npc {0} at {1} for next movement to {2}",
|
|
||||||
// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
|
|
||||||
|
|
||||||
Vector3 agent_control_v3 = new Vector3();
|
|
||||||
presence.HandleMoveToTargetUpdate(ref agent_control_v3);
|
|
||||||
presence.AddNewMovement(agent_control_v3);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
//// presence.DoMoveToPositionUpdate((0, presence.MoveToPositionTarget, null);
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsNPC(UUID agentId, Scene scene)
|
public bool IsNPC(UUID agentId, Scene scene)
|
||||||
{
|
{
|
||||||
|
// FIXME: This implementation could not just use the ScenePresence.PresenceType (and callers could inspect
|
||||||
|
// that directly).
|
||||||
ScenePresence sp = scene.GetScenePresence(agentId);
|
ScenePresence sp = scene.GetScenePresence(agentId);
|
||||||
if (sp == null || sp.IsChildAgent)
|
if (sp == null || sp.IsChildAgent)
|
||||||
return false;
|
return false;
|
||||||
|
@ -218,8 +153,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
"[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
|
"[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
|
||||||
sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
|
sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
|
||||||
|
|
||||||
m_avatars[agentID].LandAtTarget = landAtTarget;
|
sp.MoveToTarget(pos, noFly, landAtTarget);
|
||||||
sp.MoveToTarget(pos, noFly);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,18 +182,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
|
||||||
scene.Update();
|
scene.Update();
|
||||||
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
|
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
|
||||||
|
|
||||||
Vector3 targetPos = startPos + new Vector3(0, 0, 10);
|
Vector3 targetPos = startPos + new Vector3(0, 10, 0);
|
||||||
npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false);
|
npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false);
|
||||||
|
|
||||||
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
|
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
|
||||||
|
//Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f)));
|
||||||
|
Assert.That(
|
||||||
|
npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
|
||||||
|
|
||||||
scene.Update();
|
scene.Update();
|
||||||
|
|
||||||
// We should really check the exact figure.
|
// We should really check the exact figure.
|
||||||
Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
|
Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
|
||||||
Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
|
Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
|
||||||
Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z));
|
Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
|
||||||
Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z));
|
Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
scene.Update();
|
scene.Update();
|
||||||
|
@ -208,6 +211,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
|
||||||
targetPos = startPos + new Vector3(10, 0, 0);
|
targetPos = startPos + new Vector3(10, 0, 0);
|
||||||
npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false);
|
npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false);
|
||||||
|
|
||||||
|
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
|
||||||
|
// Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0, 1)));
|
||||||
|
Assert.That(
|
||||||
|
npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
|
||||||
|
|
||||||
scene.Update();
|
scene.Update();
|
||||||
|
|
||||||
// We should really check the exact figure.
|
// We should really check the exact figure.
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// Information about this assembly is defined by the following
|
|
||||||
// attributes.
|
|
||||||
//
|
|
||||||
// change them to the information which is associated with the assembly
|
|
||||||
// you compile.
|
|
||||||
|
|
||||||
[assembly : AssemblyTitle("BulletDotNETPlugin")]
|
|
||||||
[assembly : AssemblyDescription("")]
|
|
||||||
[assembly : AssemblyConfiguration("")]
|
|
||||||
[assembly : AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly : AssemblyProduct("OdePlugin")]
|
|
||||||
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
|
|
||||||
[assembly : AssemblyTrademark("")]
|
|
||||||
[assembly : AssemblyCulture("")]
|
|
||||||
|
|
||||||
// This sets the default COM visibility of types in the assembly to invisible.
|
|
||||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
|
||||||
|
|
||||||
[assembly : ComVisible(false)]
|
|
||||||
|
|
||||||
// The assembly version has following format :
|
|
||||||
//
|
|
||||||
// Major.Minor.Build.Revision
|
|
||||||
//
|
|
||||||
// You can specify all values by your own or you can build default build and revision
|
|
||||||
// numbers with the '*' character (the default):
|
|
||||||
|
|
||||||
[assembly : AssemblyVersion("0.6.3.*")]
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BulletDotNETPlugin
|
|
||||||
{
|
|
||||||
public class BulletDotNetPlugin : IPhysicsPlugin
|
|
||||||
{
|
|
||||||
private BulletDotNETScene m_scene;
|
|
||||||
private const string m_pluginName = "BulletDotNETPlugin";
|
|
||||||
|
|
||||||
#region IPhysicsPlugin Members
|
|
||||||
|
|
||||||
public bool Init()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PhysicsScene GetScene(string sceneIdentifier)
|
|
||||||
{
|
|
||||||
if (m_scene == null)
|
|
||||||
{
|
|
||||||
m_scene = new BulletDotNETScene(sceneIdentifier);
|
|
||||||
}
|
|
||||||
return m_scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetName()
|
|
||||||
{
|
|
||||||
return m_pluginName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,776 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.IO;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Threading;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using BulletDotNET;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BulletDotNETPlugin
|
|
||||||
{
|
|
||||||
public class BulletDotNETScene : PhysicsScene
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
// private string m_sceneIdentifier = string.Empty;
|
|
||||||
|
|
||||||
private List<BulletDotNETCharacter> m_characters = new List<BulletDotNETCharacter>();
|
|
||||||
private Dictionary<uint, BulletDotNETCharacter> m_charactersLocalID = new Dictionary<uint, BulletDotNETCharacter>();
|
|
||||||
private List<BulletDotNETPrim> m_prims = new List<BulletDotNETPrim>();
|
|
||||||
private Dictionary<uint, BulletDotNETPrim> m_primsLocalID = new Dictionary<uint, BulletDotNETPrim>();
|
|
||||||
private List<BulletDotNETPrim> m_activePrims = new List<BulletDotNETPrim>();
|
|
||||||
private List<PhysicsActor> m_taintedActors = new List<PhysicsActor>();
|
|
||||||
private btDiscreteDynamicsWorld m_world;
|
|
||||||
private btAxisSweep3 m_broadphase;
|
|
||||||
private btCollisionConfiguration m_collisionConfiguration;
|
|
||||||
private btConstraintSolver m_solver;
|
|
||||||
private btCollisionDispatcher m_dispatcher;
|
|
||||||
private btHeightfieldTerrainShape m_terrainShape;
|
|
||||||
public btRigidBody TerrainBody;
|
|
||||||
private btVector3 m_terrainPosition;
|
|
||||||
private btVector3 m_gravity;
|
|
||||||
public btMotionState m_terrainMotionState;
|
|
||||||
public btTransform m_terrainTransform;
|
|
||||||
public btVector3 VectorZero;
|
|
||||||
public btQuaternion QuatIdentity;
|
|
||||||
public btTransform TransZero;
|
|
||||||
|
|
||||||
public float geomDefaultDensity = 10.000006836f;
|
|
||||||
|
|
||||||
private float avPIDD = 65f;
|
|
||||||
private float avPIDP = 21f;
|
|
||||||
private float avCapRadius = 0.37f;
|
|
||||||
private float avStandupTensor = 2000000f;
|
|
||||||
private float avDensity = 80f;
|
|
||||||
private float avHeightFudgeFactor = 0.52f;
|
|
||||||
private float avMovementDivisorWalk = 1.8f;
|
|
||||||
private float avMovementDivisorRun = 0.8f;
|
|
||||||
|
|
||||||
// private float minimumGroundFlightOffset = 3f;
|
|
||||||
|
|
||||||
public bool meshSculptedPrim = true;
|
|
||||||
|
|
||||||
public float meshSculptLOD = 32;
|
|
||||||
public float MeshSculptphysicalLOD = 16;
|
|
||||||
|
|
||||||
public float bodyPIDD = 35f;
|
|
||||||
public float bodyPIDG = 25;
|
|
||||||
internal int geomCrossingFailuresBeforeOutofbounds = 4;
|
|
||||||
|
|
||||||
public float bodyMotorJointMaxforceTensor = 2;
|
|
||||||
|
|
||||||
public int bodyFramesAutoDisable = 20;
|
|
||||||
|
|
||||||
public float WorldTimeStep = 10f/60f;
|
|
||||||
public const float WorldTimeComp = 1/60f;
|
|
||||||
public float gravityz = -9.8f;
|
|
||||||
|
|
||||||
private float[] _origheightmap; // Used for Fly height. Kitto Flora
|
|
||||||
private bool usingGImpactAlgorithm = false;
|
|
||||||
|
|
||||||
// private IConfigSource m_config;
|
|
||||||
private readonly btVector3 worldAabbMin = new btVector3(-10f, -10f, 0);
|
|
||||||
private readonly btVector3 worldAabbMax = new btVector3((int)Constants.RegionSize + 10f, (int)Constants.RegionSize + 10f, 9000);
|
|
||||||
|
|
||||||
public IMesher mesher;
|
|
||||||
private ContactAddedCallbackHandler m_CollisionInterface;
|
|
||||||
|
|
||||||
public BulletDotNETScene(string sceneIdentifier)
|
|
||||||
{
|
|
||||||
// m_sceneIdentifier = sceneIdentifier;
|
|
||||||
VectorZero = new btVector3(0, 0, 0);
|
|
||||||
QuatIdentity = new btQuaternion(0, 0, 0, 1);
|
|
||||||
TransZero = new btTransform(QuatIdentity, VectorZero);
|
|
||||||
m_gravity = new btVector3(0, 0, gravityz);
|
|
||||||
_origheightmap = new float[(int)Constants.RegionSize * (int)Constants.RegionSize];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
|
||||||
{
|
|
||||||
mesher = meshmerizer;
|
|
||||||
// m_config = config;
|
|
||||||
/*
|
|
||||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
|
||||||
{
|
|
||||||
m_log.Fatal("[BulletDotNET]: This configuration is not supported on *nix currently");
|
|
||||||
Thread.Sleep(5000);
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax, 16000);
|
|
||||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
|
||||||
m_solver = new btSequentialImpulseConstraintSolver();
|
|
||||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
|
||||||
m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
|
|
||||||
m_world.setGravity(m_gravity);
|
|
||||||
EnableCollisionInterface();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
|
|
||||||
{
|
|
||||||
BulletDotNETCharacter chr = new BulletDotNETCharacter(avName, this, position, size, avPIDD, avPIDP,
|
|
||||||
avCapRadius, avStandupTensor, avDensity,
|
|
||||||
avHeightFudgeFactor, avMovementDivisorWalk,
|
|
||||||
avMovementDivisorRun);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_characters.Add(chr);
|
|
||||||
m_charactersLocalID.Add(chr.m_localID, chr);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// noop if it's already there
|
|
||||||
m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate avatar localID");
|
|
||||||
}
|
|
||||||
AddPhysicsActorTaint(chr);
|
|
||||||
return chr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RemoveAvatar(PhysicsActor actor)
|
|
||||||
{
|
|
||||||
BulletDotNETCharacter chr = (BulletDotNETCharacter) actor;
|
|
||||||
|
|
||||||
m_charactersLocalID.Remove(chr.m_localID);
|
|
||||||
m_characters.Remove(chr);
|
|
||||||
m_world.removeRigidBody(chr.Body);
|
|
||||||
m_world.removeCollisionObject(chr.Body);
|
|
||||||
|
|
||||||
chr.Remove();
|
|
||||||
AddPhysicsActorTaint(chr);
|
|
||||||
//chr = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RemovePrim(PhysicsActor prim)
|
|
||||||
{
|
|
||||||
if (prim is BulletDotNETPrim)
|
|
||||||
{
|
|
||||||
|
|
||||||
BulletDotNETPrim p = (BulletDotNETPrim)prim;
|
|
||||||
|
|
||||||
p.setPrimForRemoval();
|
|
||||||
AddPhysicsActorTaint(prim);
|
|
||||||
//RemovePrimThreadLocked(p);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
|
|
||||||
IMesh mesh, PrimitiveBaseShape pbs, bool isphysical)
|
|
||||||
{
|
|
||||||
Vector3 pos = position;
|
|
||||||
//pos.X = position.X;
|
|
||||||
//pos.Y = position.Y;
|
|
||||||
//pos.Z = position.Z;
|
|
||||||
Vector3 siz = Vector3.Zero;
|
|
||||||
siz.X = size.X;
|
|
||||||
siz.Y = size.Y;
|
|
||||||
siz.Z = size.Z;
|
|
||||||
Quaternion rot = rotation;
|
|
||||||
|
|
||||||
BulletDotNETPrim newPrim;
|
|
||||||
|
|
||||||
newPrim = new BulletDotNETPrim(name, this, pos, siz, rot, mesh, pbs, isphysical);
|
|
||||||
|
|
||||||
//lock (m_prims)
|
|
||||||
// m_prims.Add(newPrim);
|
|
||||||
|
|
||||||
|
|
||||||
return newPrim;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
|
|
||||||
{
|
|
||||||
PhysicsActor result;
|
|
||||||
IMesh mesh = null;
|
|
||||||
|
|
||||||
//switch (pbs.ProfileShape)
|
|
||||||
//{
|
|
||||||
// case ProfileShape.Square:
|
|
||||||
// //support simple box & hollow box now; later, more shapes
|
|
||||||
// if (needsMeshing(pbs))
|
|
||||||
// {
|
|
||||||
// mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// break;
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (needsMeshing(pbs))
|
|
||||||
mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical);
|
|
||||||
|
|
||||||
result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AddPhysicsActorTaint(PhysicsActor prim)
|
|
||||||
{
|
|
||||||
lock (m_taintedActors)
|
|
||||||
{
|
|
||||||
if (!m_taintedActors.Contains(prim))
|
|
||||||
{
|
|
||||||
m_taintedActors.Add(prim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal void SetUsingGImpact()
|
|
||||||
{
|
|
||||||
if (!usingGImpactAlgorithm)
|
|
||||||
btGImpactCollisionAlgorithm.registerAlgorithm(m_dispatcher);
|
|
||||||
usingGImpactAlgorithm = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override float Simulate(float timeStep)
|
|
||||||
{
|
|
||||||
|
|
||||||
lock (m_taintedActors)
|
|
||||||
{
|
|
||||||
foreach (PhysicsActor act in m_taintedActors)
|
|
||||||
{
|
|
||||||
if (act is BulletDotNETCharacter)
|
|
||||||
((BulletDotNETCharacter) act).ProcessTaints(timeStep);
|
|
||||||
if (act is BulletDotNETPrim)
|
|
||||||
((BulletDotNETPrim)act).ProcessTaints(timeStep);
|
|
||||||
}
|
|
||||||
m_taintedActors.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (m_characters)
|
|
||||||
{
|
|
||||||
foreach (BulletDotNETCharacter chr in m_characters)
|
|
||||||
{
|
|
||||||
chr.Move(timeStep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (m_prims)
|
|
||||||
{
|
|
||||||
foreach (BulletDotNETPrim prim in m_prims)
|
|
||||||
{
|
|
||||||
if (prim != null)
|
|
||||||
prim.Move(timeStep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float steps = m_world.stepSimulation(timeStep, 10, WorldTimeComp);
|
|
||||||
|
|
||||||
foreach (BulletDotNETCharacter chr in m_characters)
|
|
||||||
{
|
|
||||||
chr.UpdatePositionAndVelocity();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (BulletDotNETPrim prm in m_activePrims)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (prm != null)
|
|
||||||
if (prm.Body != null)
|
|
||||||
*/
|
|
||||||
prm.UpdatePositionAndVelocity();
|
|
||||||
}
|
|
||||||
if (m_CollisionInterface != null)
|
|
||||||
{
|
|
||||||
List<BulletDotNETPrim> primsWithCollisions = new List<BulletDotNETPrim>();
|
|
||||||
List<BulletDotNETCharacter> charactersWithCollisions = new List<BulletDotNETCharacter>();
|
|
||||||
|
|
||||||
// get the collisions that happened this tick
|
|
||||||
List<BulletDotNET.ContactAddedCallbackHandler.ContactInfo> collisions = m_CollisionInterface.GetContactList();
|
|
||||||
// passed back the localID of the prim so we can associate the prim
|
|
||||||
foreach (BulletDotNET.ContactAddedCallbackHandler.ContactInfo ci in collisions)
|
|
||||||
{
|
|
||||||
// ContactPoint = { contactPoint, contactNormal, penetrationDepth }
|
|
||||||
ContactPoint contact = new ContactPoint(new Vector3(ci.pX, ci.pY, ci.pZ),
|
|
||||||
new Vector3(ci.nX, ci.nY, ci.nZ), ci.depth);
|
|
||||||
|
|
||||||
ProcessContact(ci.contact, ci.contactWith, contact, ref primsWithCollisions, ref charactersWithCollisions);
|
|
||||||
ProcessContact(ci.contactWith, ci.contact, contact, ref primsWithCollisions, ref charactersWithCollisions);
|
|
||||||
|
|
||||||
}
|
|
||||||
m_CollisionInterface.Clear();
|
|
||||||
// for those prims and characters that had collisions cause collision events
|
|
||||||
foreach (BulletDotNETPrim bdnp in primsWithCollisions)
|
|
||||||
{
|
|
||||||
bdnp.SendCollisions();
|
|
||||||
}
|
|
||||||
foreach (BulletDotNETCharacter bdnc in charactersWithCollisions)
|
|
||||||
{
|
|
||||||
bdnc.SendCollisions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return steps;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessContact(uint cont, uint contWith, ContactPoint contact,
|
|
||||||
ref List<BulletDotNETPrim> primsWithCollisions,
|
|
||||||
ref List<BulletDotNETCharacter> charactersWithCollisions)
|
|
||||||
{
|
|
||||||
BulletDotNETPrim bdnp;
|
|
||||||
// collisions with a normal prim?
|
|
||||||
if (m_primsLocalID.TryGetValue(cont, out bdnp))
|
|
||||||
{
|
|
||||||
// Added collision event to the prim. This creates a pile of events
|
|
||||||
// that will be sent to any subscribed listeners.
|
|
||||||
bdnp.AddCollision(contWith, contact);
|
|
||||||
if (!primsWithCollisions.Contains(bdnp))
|
|
||||||
{
|
|
||||||
primsWithCollisions.Add(bdnp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BulletDotNETCharacter bdnc;
|
|
||||||
// if not a prim, maybe it's one of the characters
|
|
||||||
if (m_charactersLocalID.TryGetValue(cont, out bdnc))
|
|
||||||
{
|
|
||||||
bdnc.AddCollision(contWith, contact);
|
|
||||||
if (!charactersWithCollisions.Contains(bdnc))
|
|
||||||
{
|
|
||||||
charactersWithCollisions.Add(bdnc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void GetResults()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetTerrain(float[] heightMap)
|
|
||||||
{
|
|
||||||
if (m_terrainShape != null)
|
|
||||||
DeleteTerrain();
|
|
||||||
|
|
||||||
float hfmax = -9000;
|
|
||||||
float hfmin = 90000;
|
|
||||||
|
|
||||||
for (int i = 0; i <heightMap.Length;i++)
|
|
||||||
{
|
|
||||||
if (Single.IsNaN(heightMap[i]) || Single.IsInfinity(heightMap[i]))
|
|
||||||
{
|
|
||||||
heightMap[i] = 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
hfmin = (heightMap[i] < hfmin) ? heightMap[i] : hfmin;
|
|
||||||
hfmax = (heightMap[i] > hfmax) ? heightMap[i] : hfmax;
|
|
||||||
}
|
|
||||||
// store this for later reference.
|
|
||||||
// Note, we're storing it after we check it for anomolies above
|
|
||||||
_origheightmap = heightMap;
|
|
||||||
|
|
||||||
hfmin = 0;
|
|
||||||
hfmax = 256;
|
|
||||||
|
|
||||||
m_terrainShape = new btHeightfieldTerrainShape((int)Constants.RegionSize, (int)Constants.RegionSize, heightMap,
|
|
||||||
1.0f, hfmin, hfmax, (int)btHeightfieldTerrainShape.UPAxis.Z,
|
|
||||||
(int)btHeightfieldTerrainShape.PHY_ScalarType.PHY_FLOAT, false);
|
|
||||||
float AabbCenterX = Constants.RegionSize/2f;
|
|
||||||
float AabbCenterY = Constants.RegionSize/2f;
|
|
||||||
|
|
||||||
float AabbCenterZ = 0;
|
|
||||||
float temphfmin, temphfmax;
|
|
||||||
|
|
||||||
temphfmin = hfmin;
|
|
||||||
temphfmax = hfmax;
|
|
||||||
|
|
||||||
if (temphfmin < 0)
|
|
||||||
{
|
|
||||||
temphfmax = 0 - temphfmin;
|
|
||||||
temphfmin = 0 - temphfmin;
|
|
||||||
}
|
|
||||||
else if (temphfmin > 0)
|
|
||||||
{
|
|
||||||
temphfmax = temphfmax + (0 - temphfmin);
|
|
||||||
//temphfmin = temphfmin + (0 - temphfmin);
|
|
||||||
}
|
|
||||||
AabbCenterZ = temphfmax/2f;
|
|
||||||
|
|
||||||
if (m_terrainPosition == null)
|
|
||||||
{
|
|
||||||
m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_terrainPosition.setValue(AabbCenterX, AabbCenterY, AabbCenterZ);
|
|
||||||
}
|
|
||||||
catch (ObjectDisposedException)
|
|
||||||
{
|
|
||||||
m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_terrainMotionState != null)
|
|
||||||
{
|
|
||||||
m_terrainMotionState.Dispose();
|
|
||||||
m_terrainMotionState = null;
|
|
||||||
}
|
|
||||||
m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition);
|
|
||||||
m_terrainMotionState = new btDefaultMotionState(m_terrainTransform);
|
|
||||||
TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape);
|
|
||||||
TerrainBody.setUserPointer((IntPtr)0);
|
|
||||||
m_world.addRigidBody(TerrainBody);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetWaterLevel(float baseheight)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void DeleteTerrain()
|
|
||||||
{
|
|
||||||
if (TerrainBody != null)
|
|
||||||
{
|
|
||||||
m_world.removeRigidBody(TerrainBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_terrainShape != null)
|
|
||||||
{
|
|
||||||
m_terrainShape.Dispose();
|
|
||||||
m_terrainShape = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_terrainMotionState != null)
|
|
||||||
{
|
|
||||||
m_terrainMotionState.Dispose();
|
|
||||||
m_terrainMotionState = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_terrainTransform != null)
|
|
||||||
{
|
|
||||||
m_terrainTransform.Dispose();
|
|
||||||
m_terrainTransform = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_terrainPosition != null)
|
|
||||||
{
|
|
||||||
m_terrainPosition.Dispose();
|
|
||||||
m_terrainPosition = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
disposeAllBodies();
|
|
||||||
m_world.Dispose();
|
|
||||||
m_broadphase.Dispose();
|
|
||||||
((btDefaultCollisionConfiguration) m_collisionConfiguration).Dispose();
|
|
||||||
((btSequentialImpulseConstraintSolver) m_solver).Dispose();
|
|
||||||
worldAabbMax.Dispose();
|
|
||||||
worldAabbMin.Dispose();
|
|
||||||
VectorZero.Dispose();
|
|
||||||
QuatIdentity.Dispose();
|
|
||||||
m_gravity.Dispose();
|
|
||||||
VectorZero = null;
|
|
||||||
QuatIdentity = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Dictionary<uint, float> GetTopColliders()
|
|
||||||
{
|
|
||||||
return new Dictionary<uint, float>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public btDiscreteDynamicsWorld getBulletWorld()
|
|
||||||
{
|
|
||||||
return m_world;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disposeAllBodies()
|
|
||||||
{
|
|
||||||
lock (m_prims)
|
|
||||||
{
|
|
||||||
m_primsLocalID.Clear();
|
|
||||||
foreach (BulletDotNETPrim prim in m_prims)
|
|
||||||
{
|
|
||||||
if (prim.Body != null)
|
|
||||||
m_world.removeRigidBody(prim.Body);
|
|
||||||
|
|
||||||
prim.Dispose();
|
|
||||||
}
|
|
||||||
m_prims.Clear();
|
|
||||||
|
|
||||||
foreach (BulletDotNETCharacter chr in m_characters)
|
|
||||||
{
|
|
||||||
if (chr.Body != null)
|
|
||||||
m_world.removeRigidBody(chr.Body);
|
|
||||||
chr.Dispose();
|
|
||||||
}
|
|
||||||
m_characters.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool IsThreaded
|
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void addCollisionEventReporting(PhysicsActor bulletDotNETCharacter)
|
|
||||||
{
|
|
||||||
//TODO: FIXME:
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void remCollisionEventReporting(PhysicsActor bulletDotNETCharacter)
|
|
||||||
{
|
|
||||||
//TODO: FIXME:
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void AddRigidBody(btRigidBody Body)
|
|
||||||
{
|
|
||||||
m_world.addRigidBody(Body);
|
|
||||||
}
|
|
||||||
[Obsolete("bad!")]
|
|
||||||
internal void removeFromWorld(btRigidBody body)
|
|
||||||
{
|
|
||||||
|
|
||||||
m_world.removeRigidBody(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void removeFromWorld(BulletDotNETPrim prm ,btRigidBody body)
|
|
||||||
{
|
|
||||||
lock (m_prims)
|
|
||||||
{
|
|
||||||
if (m_prims.Contains(prm))
|
|
||||||
{
|
|
||||||
m_world.removeRigidBody(body);
|
|
||||||
}
|
|
||||||
remActivePrim(prm);
|
|
||||||
m_primsLocalID.Remove(prm.m_localID);
|
|
||||||
m_prims.Remove(prm);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal float GetWaterLevel()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recovered for use by fly height. Kitto Flora
|
|
||||||
public float GetTerrainHeightAtXY(float x, float y)
|
|
||||||
{
|
|
||||||
// Teravus: Kitto, this code causes recurring errors that stall physics permenantly unless
|
|
||||||
// the values are checked, so checking below.
|
|
||||||
// Is there any reason that we don't do this in ScenePresence?
|
|
||||||
// The only physics engine that benefits from it in the physics plugin is this one
|
|
||||||
|
|
||||||
if (x > (int)Constants.RegionSize || y > (int)Constants.RegionSize ||
|
|
||||||
x < 0.001f || y < 0.001f)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return _origheightmap[(int)y * Constants.RegionSize + (int)x];
|
|
||||||
}
|
|
||||||
// End recovered. Kitto Flora
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Routine to figure out if we need to mesh this prim with our mesher
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pbs"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool needsMeshing(PrimitiveBaseShape pbs)
|
|
||||||
{
|
|
||||||
// most of this is redundant now as the mesher will return null if it cant mesh a prim
|
|
||||||
// but we still need to check for sculptie meshing being enabled so this is the most
|
|
||||||
// convenient place to do it for now...
|
|
||||||
|
|
||||||
// //if (pbs.PathCurve == (byte)Primitive.PathCurve.Circle && pbs.ProfileCurve == (byte)Primitive.ProfileCurve.Circle && pbs.PathScaleY <= 0.75f)
|
|
||||||
// //m_log.Debug("needsMeshing: " + " pathCurve: " + pbs.PathCurve.ToString() + " profileCurve: " + pbs.ProfileCurve.ToString() + " pathScaleY: " + Primitive.UnpackPathScale(pbs.PathScaleY).ToString());
|
|
||||||
int iPropertiesNotSupportedDefault = 0;
|
|
||||||
|
|
||||||
if (pbs.SculptEntry && !meshSculptedPrim)
|
|
||||||
{
|
|
||||||
#if SPAM
|
|
||||||
m_log.Warn("NonMesh");
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
|
|
||||||
if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
|
|
||||||
|| (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
|
|
||||||
&& pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
|
|
||||||
{
|
|
||||||
|
|
||||||
if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
|
|
||||||
&& pbs.ProfileHollow == 0
|
|
||||||
&& pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
|
|
||||||
&& pbs.PathBegin == 0 && pbs.PathEnd == 0
|
|
||||||
&& pbs.PathTaperX == 0 && pbs.PathTaperY == 0
|
|
||||||
&& pbs.PathScaleX == 100 && pbs.PathScaleY == 100
|
|
||||||
&& pbs.PathShearX == 0 && pbs.PathShearY == 0)
|
|
||||||
{
|
|
||||||
#if SPAM
|
|
||||||
m_log.Warn("NonMesh");
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pbs.ProfileHollow != 0)
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
|
|
||||||
// test for torus
|
|
||||||
if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
|
|
||||||
{
|
|
||||||
if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
|
||||||
{
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
|
|
||||||
{
|
|
||||||
if (pbs.PathCurve == (byte)Extrusion.Straight)
|
|
||||||
{
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
|
|
||||||
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
|
||||||
{
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
|
|
||||||
{
|
|
||||||
if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
|
|
||||||
{
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
|
|
||||||
{
|
|
||||||
if (pbs.PathCurve == (byte)Extrusion.Straight)
|
|
||||||
{
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
}
|
|
||||||
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
|
||||||
{
|
|
||||||
iPropertiesNotSupportedDefault++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (iPropertiesNotSupportedDefault == 0)
|
|
||||||
{
|
|
||||||
#if SPAM
|
|
||||||
m_log.Warn("NonMesh");
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#if SPAM
|
|
||||||
m_log.Debug("Mesh");
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void addActivePrim(BulletDotNETPrim pPrim)
|
|
||||||
{
|
|
||||||
lock (m_activePrims)
|
|
||||||
{
|
|
||||||
if (!m_activePrims.Contains(pPrim))
|
|
||||||
{
|
|
||||||
m_activePrims.Add(pPrim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remActivePrim(BulletDotNETPrim pDeactivatePrim)
|
|
||||||
{
|
|
||||||
lock (m_activePrims)
|
|
||||||
{
|
|
||||||
m_activePrims.Remove(pDeactivatePrim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void AddPrimToScene(BulletDotNETPrim pPrim)
|
|
||||||
{
|
|
||||||
lock (m_prims)
|
|
||||||
{
|
|
||||||
if (!m_prims.Contains(pPrim))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_prims.Add(pPrim);
|
|
||||||
m_primsLocalID.Add(pPrim.m_localID, pPrim);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// noop if it's already there
|
|
||||||
m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate prim localID");
|
|
||||||
}
|
|
||||||
m_world.addRigidBody(pPrim.Body);
|
|
||||||
// m_log.Debug("[PHYSICS] added prim to scene");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal void EnableCollisionInterface()
|
|
||||||
{
|
|
||||||
if (m_CollisionInterface == null)
|
|
||||||
{
|
|
||||||
m_CollisionInterface = new ContactAddedCallbackHandler(m_world);
|
|
||||||
// m_world.SetCollisionAddedCallback(m_CollisionInterface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// Information about this assembly is defined by the following
|
|
||||||
// attributes.
|
|
||||||
//
|
|
||||||
// change them to the information which is associated with the assembly
|
|
||||||
// you compile.
|
|
||||||
|
|
||||||
[assembly : AssemblyTitle("BulletXPlugin")]
|
|
||||||
[assembly : AssemblyDescription("")]
|
|
||||||
[assembly : AssemblyConfiguration("")]
|
|
||||||
[assembly : AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly : AssemblyProduct("BulletXPlugin")]
|
|
||||||
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
|
|
||||||
[assembly : AssemblyTrademark("")]
|
|
||||||
[assembly : AssemblyCulture("")]
|
|
||||||
|
|
||||||
// This sets the default COM visibility of types in the assembly to invisible.
|
|
||||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
|
||||||
|
|
||||||
[assembly : ComVisible(false)]
|
|
||||||
|
|
||||||
// The assembly version has following format :
|
|
||||||
//
|
|
||||||
// Major.Minor.Build.Revision
|
|
||||||
//
|
|
||||||
// You can specify all values by your own or you can build default build and revision
|
|
||||||
// numbers with the '*' character (the default):
|
|
||||||
|
|
||||||
[assembly : AssemblyVersion("0.6.5.*")]
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,197 +0,0 @@
|
||||||
/*
|
|
||||||
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
|
|
||||||
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file contains a class TriangleIndexVertexArray. I tried using the class with the same name
|
|
||||||
from the BulletX implementation and found it unusable for the purpose of using triangle meshes
|
|
||||||
within BulletX as the implementation was painfully incomplete.
|
|
||||||
The attempt to derive from the original class failed as viable members were hidden.
|
|
||||||
Fiddling around with BulletX itself was not my intention.
|
|
||||||
So I copied the class to the BulletX-plugin and modified it.
|
|
||||||
If you want to fiddle around with it it's up to you to move all this to BulletX.
|
|
||||||
If someone someday implements the missing functionality in BulletX, feel free to remove this class.
|
|
||||||
It's just an ugly hack.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MonoXnaCompactMaths;
|
|
||||||
using XnaDevRu.BulletX;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BulletXPlugin
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
|
|
||||||
/// instead of the number of indices, we pass the number of triangles
|
|
||||||
/// </summary>
|
|
||||||
public struct IndexedMesh
|
|
||||||
{
|
|
||||||
private int _numTriangles;
|
|
||||||
private int[] _triangleIndexBase;
|
|
||||||
private int _triangleIndexStride;
|
|
||||||
private int _numVertices;
|
|
||||||
private Vector3[] _vertexBase;
|
|
||||||
private int _vertexStride;
|
|
||||||
|
|
||||||
public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices,
|
|
||||||
Vector3[] vertexBase, int vertexStride)
|
|
||||||
{
|
|
||||||
_numTriangles = numTriangleIndices;
|
|
||||||
_triangleIndexBase = triangleIndexBase;
|
|
||||||
_triangleIndexStride = triangleIndexStride;
|
|
||||||
_vertexBase = vertexBase;
|
|
||||||
_numVertices = numVertices;
|
|
||||||
_vertexStride = vertexStride;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
|
|
||||||
{
|
|
||||||
_numTriangles = triangleIndexBase.Length;
|
|
||||||
_triangleIndexBase = triangleIndexBase;
|
|
||||||
_triangleIndexStride = 32;
|
|
||||||
_vertexBase = vertexBase;
|
|
||||||
_numVertices = vertexBase.Length;
|
|
||||||
_vertexStride = 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int TriangleCount
|
|
||||||
{
|
|
||||||
get { return _numTriangles; }
|
|
||||||
set { _numTriangles = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] TriangleIndexBase
|
|
||||||
{
|
|
||||||
get { return _triangleIndexBase; }
|
|
||||||
set { _triangleIndexBase = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int TriangleIndexStride
|
|
||||||
{
|
|
||||||
get { return _triangleIndexStride; }
|
|
||||||
set { _triangleIndexStride = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int VertexCount
|
|
||||||
{
|
|
||||||
get { return _numVertices; }
|
|
||||||
set { _numVertices = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3[] VertexBase
|
|
||||||
{
|
|
||||||
get { return _vertexBase; }
|
|
||||||
set { _vertexBase = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int VertexStride
|
|
||||||
{
|
|
||||||
get { return _vertexStride; }
|
|
||||||
set { _vertexStride = value; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
|
|
||||||
/// Additional meshes can be added using addIndexedMesh
|
|
||||||
/// </summary>
|
|
||||||
public class TriangleIndexVertexArray : StridingMeshInterface
|
|
||||||
{
|
|
||||||
private List<IndexedMesh> _indexedMeshes = new List<IndexedMesh>();
|
|
||||||
|
|
||||||
public TriangleIndexVertexArray()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride,
|
|
||||||
int numVertices, Vector3[] vertexBase, int vertexStride)
|
|
||||||
{
|
|
||||||
IndexedMesh mesh = new IndexedMesh();
|
|
||||||
mesh.TriangleCount = numTriangleIndices;
|
|
||||||
mesh.TriangleIndexBase = triangleIndexBase;
|
|
||||||
mesh.TriangleIndexStride = triangleIndexStride;
|
|
||||||
mesh.VertexBase = vertexBase;
|
|
||||||
mesh.VertexCount = numVertices;
|
|
||||||
mesh.VertexStride = vertexStride;
|
|
||||||
|
|
||||||
AddIndexedMesh(mesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
|
|
||||||
: this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddIndexedMesh(IndexedMesh indexedMesh)
|
|
||||||
{
|
|
||||||
_indexedMeshes.Add(indexedMesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces,
|
|
||||||
int subpart)
|
|
||||||
{
|
|
||||||
throw new Exception("The method or operation is not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies,
|
|
||||||
out int numfaces, int subpart)
|
|
||||||
{
|
|
||||||
IndexedMesh m = _indexedMeshes[0];
|
|
||||||
Vector3[] vertexBase = m.VertexBase;
|
|
||||||
verts = new List<Vector3>();
|
|
||||||
foreach (Vector3 v in vertexBase)
|
|
||||||
{
|
|
||||||
verts.Add(v);
|
|
||||||
}
|
|
||||||
int[] indexBase = m.TriangleIndexBase;
|
|
||||||
indicies = new List<int>();
|
|
||||||
foreach (int i in indexBase)
|
|
||||||
{
|
|
||||||
indicies.Add(i);
|
|
||||||
}
|
|
||||||
numfaces = vertexBase.GetLength(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void UnLockVertexBase(int subpart)
|
|
||||||
{
|
|
||||||
throw new Exception("The method or operation is not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void UnLockReadOnlyVertexBase(int subpart)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int SubPartsCount()
|
|
||||||
{
|
|
||||||
return _indexedMeshes.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreallocateVertices(int numverts)
|
|
||||||
{
|
|
||||||
throw new Exception("The method or operation is not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreallocateIndices(int numindices)
|
|
||||||
{
|
|
||||||
throw new Exception("The method or operation is not implemented.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -464,10 +464,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
m_pidControllerActive = true;
|
m_pidControllerActive = true;
|
||||||
|
|
||||||
Vector3 SetSize = value;
|
Vector3 SetSize = value;
|
||||||
m_tainted_CAPSULE_LENGTH = (SetSize.Z*1.15f) - CAPSULE_RADIUS*2.0f;
|
m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
|
||||||
//m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
|
// m_log.Info("[SIZE]: " + CAPSULE_LENGTH);
|
||||||
|
|
||||||
Velocity = Vector3.Zero;
|
// If we reset velocity here, then an avatar stalls when it crosses a border for the first time
|
||||||
|
// (as the height of the new root agent is set).
|
||||||
|
// Velocity = Vector3.Zero;
|
||||||
|
|
||||||
_parent_scene.AddPhysicsActorTaint(this);
|
_parent_scene.AddPhysicsActorTaint(this);
|
||||||
}
|
}
|
||||||
|
@ -785,6 +787,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character");
|
m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[PHYSICS]: Set target velocity of {0}", _target_velocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1325,7 +1329,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
|
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat("[PHYSICS]: Changing capsule size");
|
||||||
|
|
||||||
m_pidControllerActive = true;
|
m_pidControllerActive = true;
|
||||||
// no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
|
// no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
|
||||||
d.JointDestroy(Amotor);
|
d.JointDestroy(Amotor);
|
||||||
|
@ -1336,7 +1341,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.GeomDestroy(Shell);
|
d.GeomDestroy(Shell);
|
||||||
AvatarGeomAndBodyCreation(_position.X, _position.Y,
|
AvatarGeomAndBodyCreation(_position.X, _position.Y,
|
||||||
_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
|
_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
|
||||||
Velocity = Vector3.Zero;
|
|
||||||
|
// As with Size, we reset velocity. However, this isn't strictly necessary since it doesn't
|
||||||
|
// appear to stall initial region crossings when done here. Being done for consistency.
|
||||||
|
// Velocity = Vector3.Zero;
|
||||||
|
|
||||||
_parent_scene.geom_name_map[Shell] = m_name;
|
_parent_scene.geom_name_map[Shell] = m_name;
|
||||||
_parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
|
_parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
|
||||||
|
@ -1361,7 +1369,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
_position.Z = m_taintPosition.Z;
|
_position.Z = m_taintPosition.Z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddCollisionFrameTime(int p)
|
internal void AddCollisionFrameTime(int p)
|
||||||
|
|
|
@ -1526,6 +1526,7 @@ Console.WriteLine("changeadd 1");
|
||||||
{
|
{
|
||||||
if (Body == IntPtr.Zero)
|
if (Body == IntPtr.Zero)
|
||||||
enableBody();
|
enableBody();
|
||||||
|
|
||||||
//Prim auto disable after 20 frames,
|
//Prim auto disable after 20 frames,
|
||||||
//if you move it, re-enable the prim manually.
|
//if you move it, re-enable the prim manually.
|
||||||
if (_parent != null)
|
if (_parent != null)
|
||||||
|
@ -1536,6 +1537,7 @@ Console.WriteLine("changeadd 1");
|
||||||
m_linkJoint = IntPtr.Zero;
|
m_linkJoint = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Body != IntPtr.Zero)
|
if (Body != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
|
d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
|
||||||
|
@ -1599,7 +1601,6 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
float fy = 0;
|
float fy = 0;
|
||||||
float fz = 0;
|
float fz = 0;
|
||||||
|
|
||||||
|
|
||||||
if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
|
if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
|
||||||
{
|
{
|
||||||
if (m_vehicle.Type != Vehicle.TYPE_NONE)
|
if (m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||||
|
@ -1818,7 +1819,6 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
// 35x10 = 350n times the mass per second applied maximum.
|
// 35x10 = 350n times the mass per second applied maximum.
|
||||||
float nmax = 35f * m_mass;
|
float nmax = 35f * m_mass;
|
||||||
float nmin = -35f * m_mass;
|
float nmin = -35f * m_mass;
|
||||||
|
|
||||||
|
|
||||||
if (fx > nmax)
|
if (fx > nmax)
|
||||||
fx = nmax;
|
fx = nmax;
|
||||||
|
|
|
@ -3591,7 +3591,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
parentPrim.ScheduleGroupForFullUpdate();
|
parentPrim.ScheduleGroupForFullUpdate();
|
||||||
|
|
||||||
if (client != null)
|
if (client != null)
|
||||||
parentPrim.GetProperties(client);
|
parentPrim.SendPropertiesToClient(client);
|
||||||
|
|
||||||
ScriptSleep(1000);
|
ScriptSleep(1000);
|
||||||
}
|
}
|
||||||
|
@ -6570,6 +6570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
|
protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
|
||||||
{
|
{
|
||||||
|
float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
|
||||||
ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
|
ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
|
||||||
|
|
||||||
if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
|
if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
|
||||||
|
@ -6651,8 +6652,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
twist.y = 1.0f;
|
twist.y = 1.0f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x);
|
// A fairly large precision error occurs for some calculations,
|
||||||
shapeBlock.PathTwist = (sbyte)(100 * twist.y);
|
// if a float or double is directly cast to a byte or sbyte
|
||||||
|
// variable, in both .Net and Mono. In .Net, coding
|
||||||
|
// "(sbyte)(float)(some expression)" corrects the precision
|
||||||
|
// errors. But this does not work for Mono. This longer coding
|
||||||
|
// form of creating a tempoary float variable from the
|
||||||
|
// expression first, then casting that variable to a byte or
|
||||||
|
// sbyte, works for both .Net and Mono. These types of
|
||||||
|
// assignments occur in SetPrimtiveBlockShapeParams and
|
||||||
|
// SetPrimitiveShapeParams in support of llSetPrimitiveParams.
|
||||||
|
tempFloat = (float)(100.0d * twist.x);
|
||||||
|
shapeBlock.PathTwistBegin = (sbyte)tempFloat;
|
||||||
|
tempFloat = (float)(100.0d * twist.y);
|
||||||
|
shapeBlock.PathTwist = (sbyte)tempFloat;
|
||||||
|
|
||||||
shapeBlock.ObjectLocalID = part.LocalId;
|
shapeBlock.ObjectLocalID = part.LocalId;
|
||||||
|
|
||||||
|
@ -6663,6 +6676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// Prim type box, cylinder and prism.
|
// Prim type box, cylinder and prism.
|
||||||
protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
|
protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
|
||||||
{
|
{
|
||||||
|
float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
|
||||||
ObjectShapePacket.ObjectDataBlock shapeBlock;
|
ObjectShapePacket.ObjectDataBlock shapeBlock;
|
||||||
|
|
||||||
shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
|
shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
|
||||||
|
@ -6683,8 +6697,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
taper_b.y = 2f;
|
taper_b.y = 2f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x));
|
tempFloat = (float)(100.0d * (2.0d - taper_b.x));
|
||||||
shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y));
|
shapeBlock.PathScaleX = (byte)tempFloat;
|
||||||
|
tempFloat = (float)(100.0d * (2.0d - taper_b.y));
|
||||||
|
shapeBlock.PathScaleY = (byte)tempFloat;
|
||||||
if (topshear.x < -0.5f)
|
if (topshear.x < -0.5f)
|
||||||
{
|
{
|
||||||
topshear.x = -0.5f;
|
topshear.x = -0.5f;
|
||||||
|
@ -6701,8 +6717,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
topshear.y = 0.5f;
|
topshear.y = 0.5f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathShearX = (byte)(100 * topshear.x);
|
tempFloat = (float)(100.0d * topshear.x);
|
||||||
shapeBlock.PathShearY = (byte)(100 * topshear.y);
|
shapeBlock.PathShearX = (byte)tempFloat;
|
||||||
|
tempFloat = (float)(100.0d * topshear.y);
|
||||||
|
shapeBlock.PathShearY = (byte)tempFloat;
|
||||||
|
|
||||||
part.Shape.SculptEntry = false;
|
part.Shape.SculptEntry = false;
|
||||||
part.UpdateShape(shapeBlock);
|
part.UpdateShape(shapeBlock);
|
||||||
|
@ -6752,6 +6770,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// Prim type torus, tube and ring.
|
// Prim type torus, tube and ring.
|
||||||
protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
|
protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
|
||||||
{
|
{
|
||||||
|
float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
|
||||||
ObjectShapePacket.ObjectDataBlock shapeBlock;
|
ObjectShapePacket.ObjectDataBlock shapeBlock;
|
||||||
|
|
||||||
shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
|
shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
|
||||||
|
@ -6776,8 +6795,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
holesize.y = 0.5f;
|
holesize.y = 0.5f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x));
|
tempFloat = (float)(100.0d * (2.0d - holesize.x));
|
||||||
shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y));
|
shapeBlock.PathScaleX = (byte)tempFloat;
|
||||||
|
tempFloat = (float)(100.0d * (2.0d - holesize.y));
|
||||||
|
shapeBlock.PathScaleY = (byte)tempFloat;
|
||||||
if (topshear.x < -0.5f)
|
if (topshear.x < -0.5f)
|
||||||
{
|
{
|
||||||
topshear.x = -0.5f;
|
topshear.x = -0.5f;
|
||||||
|
@ -6794,8 +6815,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
topshear.y = 0.5f;
|
topshear.y = 0.5f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathShearX = (byte)(100 * topshear.x);
|
tempFloat = (float)(100.0d * topshear.x);
|
||||||
shapeBlock.PathShearY = (byte)(100 * topshear.y);
|
shapeBlock.PathShearX = (byte)tempFloat;
|
||||||
|
tempFloat = (float)(100.0d * topshear.y);
|
||||||
|
shapeBlock.PathShearY = (byte)tempFloat;
|
||||||
if (profilecut.x < 0f)
|
if (profilecut.x < 0f)
|
||||||
{
|
{
|
||||||
profilecut.x = 0f;
|
profilecut.x = 0f;
|
||||||
|
@ -6839,8 +6862,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
taper_a.y = 1f;
|
taper_a.y = 1f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x);
|
tempFloat = (float)(100.0d * taper_a.x);
|
||||||
shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y);
|
shapeBlock.PathTaperX = (sbyte)tempFloat;
|
||||||
|
tempFloat = (float)(100.0d * taper_a.y);
|
||||||
|
shapeBlock.PathTaperY = (sbyte)tempFloat;
|
||||||
if (revolutions < 1f)
|
if (revolutions < 1f)
|
||||||
{
|
{
|
||||||
revolutions = 1f;
|
revolutions = 1f;
|
||||||
|
@ -6849,7 +6874,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
revolutions = 4f;
|
revolutions = 4f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathRevolutions = (byte)(66.666667 * (revolutions - 1.0));
|
tempFloat = 66.66667f * (revolutions - 1.0f);
|
||||||
|
shapeBlock.PathRevolutions = (byte)tempFloat;
|
||||||
// limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1
|
// limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1
|
||||||
if (radiusoffset < 0f)
|
if (radiusoffset < 0f)
|
||||||
{
|
{
|
||||||
|
@ -6859,7 +6885,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
radiusoffset = 1f;
|
radiusoffset = 1f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset);
|
tempFloat = 100.0f * radiusoffset;
|
||||||
|
shapeBlock.PathRadiusOffset = (sbyte)tempFloat;
|
||||||
if (skew < -0.95f)
|
if (skew < -0.95f)
|
||||||
{
|
{
|
||||||
skew = -0.95f;
|
skew = -0.95f;
|
||||||
|
@ -6868,7 +6895,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
skew = 0.95f;
|
skew = 0.95f;
|
||||||
}
|
}
|
||||||
shapeBlock.PathSkew = (sbyte)(100 * skew);
|
tempFloat = 100.0f * skew;
|
||||||
|
shapeBlock.PathSkew = (sbyte)tempFloat;
|
||||||
|
|
||||||
part.Shape.SculptEntry = false;
|
part.Shape.SculptEntry = false;
|
||||||
part.UpdateShape(shapeBlock);
|
part.UpdateShape(shapeBlock);
|
||||||
|
@ -7681,10 +7709,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
|
res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
|
||||||
|
|
||||||
// float revolutions
|
// float revolutions
|
||||||
res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned
|
res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
|
||||||
// byte is being used to represent the entire
|
// Slightly inaccurate, because an unsigned byte is being used to represent
|
||||||
// range of floating-point values from 1.0
|
// the entire range of floating-point values from 1.0 through 4.0 (which is how
|
||||||
// through 4.0 (which is how SL does it).
|
// SL does it).
|
||||||
|
//
|
||||||
|
// Using these formulas to store and retrieve PathRevolutions, it is not
|
||||||
|
// possible to use all values between 1.00 and 4.00. For instance, you can't
|
||||||
|
// represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
|
||||||
|
// use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
|
||||||
|
// with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
|
||||||
|
// behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
|
||||||
|
// In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
|
||||||
|
// such as 1.10. So, SL must store and retreive the actual user input rather
|
||||||
|
// than only storing the encoded value.
|
||||||
|
|
||||||
// float radiusoffset
|
// float radiusoffset
|
||||||
res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
|
res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
|
|
||||||
private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
|
private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
|
||||||
private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
|
private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
|
||||||
private const double FLOAT_ACCURACY = 0.00005d;
|
private const float FLOAT_ACCURACY = 0.00005f;
|
||||||
private LSL_Api m_lslApi;
|
private LSL_Api m_lslApi;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
|
@ -194,10 +194,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
|
ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
|
||||||
ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
|
ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
|
||||||
new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut
|
new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut
|
||||||
0.80d, // Prim hollow
|
0.80f, // Prim hollow
|
||||||
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
|
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
|
||||||
new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple
|
new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple
|
||||||
0.80d); // Prim hollow check
|
0.80f); // Prim hollow check
|
||||||
|
|
||||||
// Test a prism.
|
// Test a prism.
|
||||||
CheckllSetPrimitiveParams(
|
CheckllSetPrimitiveParams(
|
||||||
|
@ -206,11 +206,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
|
ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
|
||||||
ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
|
ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
|
||||||
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
|
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
|
||||||
0.90d, // Prim hollow
|
0.90f, // Prim hollow
|
||||||
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
|
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
|
||||||
new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
|
new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
|
||||||
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
|
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
|
||||||
0.90d); // Prim hollow check
|
0.90f); // Prim hollow check
|
||||||
|
|
||||||
// Test a box.
|
// Test a box.
|
||||||
CheckllSetPrimitiveParams(
|
CheckllSetPrimitiveParams(
|
||||||
|
@ -219,11 +219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
|
ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
|
||||||
ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
|
ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
|
||||||
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
|
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
|
||||||
0.95d, // Prim hollow
|
0.95f, // Prim hollow
|
||||||
new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist
|
new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist
|
||||||
new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper
|
new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper
|
||||||
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
|
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
|
||||||
0.95d); // Prim hollow check
|
0.95f); // Prim hollow check
|
||||||
|
|
||||||
// Test a tube.
|
// Test a tube.
|
||||||
CheckllSetPrimitiveParams(
|
CheckllSetPrimitiveParams(
|
||||||
|
@ -232,16 +232,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
|
ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
|
||||||
ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
|
ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
|
||||||
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
|
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
|
||||||
0.00d, // Prim hollow
|
0.00f, // Prim hollow
|
||||||
new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist
|
new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist
|
||||||
new LSL_Types.Vector3(1.0d, 0.5d, 0.0d), // Prim hole size
|
new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size
|
||||||
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
|
// Expression for y selected to test precision problems during byte
|
||||||
|
// cast in SetPrimitiveShapeParams.
|
||||||
|
new LSL_Types.Vector3(0.0d, 0.35d + 0.1d, 0.0d), // Prim shear
|
||||||
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut
|
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut
|
||||||
new LSL_Types.Vector3(-1.0d, 1.0d, 0.0d), // Prim taper
|
// Expression for y selected to test precision problems during sbyte
|
||||||
1.0d, // Prim revolutions
|
// cast in SetPrimitiveShapeParams.
|
||||||
1.0d, // Prim radius
|
new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper
|
||||||
0.0d, // Prim skew
|
1.11f, // Prim revolutions
|
||||||
0.00d); // Prim hollow check
|
0.88f, // Prim radius
|
||||||
|
0.95f, // Prim skew
|
||||||
|
0.00f); // Prim hollow check
|
||||||
|
|
||||||
// Test a prism.
|
// Test a prism.
|
||||||
CheckllSetPrimitiveParams(
|
CheckllSetPrimitiveParams(
|
||||||
|
@ -250,11 +254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
|
ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
|
||||||
ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
|
ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
|
||||||
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
|
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
|
||||||
0.95d, // Prim hollow
|
0.95f, // Prim hollow
|
||||||
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
|
// Expression for x selected to test precision problems during sbyte
|
||||||
new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
|
// cast in SetPrimitiveShapeBlockParams.
|
||||||
|
new LSL_Types.Vector3(0.7d + 0.2d, 0.0d, 0.0d), // Prim twist
|
||||||
|
// Expression for y selected to test precision problems during sbyte
|
||||||
|
// cast in SetPrimitiveShapeParams.
|
||||||
|
new LSL_Types.Vector3(2.0d, (1.3d + 0.1d), 0.0d), // Prim taper
|
||||||
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
|
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
|
||||||
0.70d); // Prim hollow check
|
0.70f); // Prim hollow check
|
||||||
|
|
||||||
// Test a sculpted prim.
|
// Test a sculpted prim.
|
||||||
CheckllSetPrimitiveParams(
|
CheckllSetPrimitiveParams(
|
||||||
|
@ -268,8 +276,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
// Set prim params for a box, cylinder or prism and check results.
|
// Set prim params for a box, cylinder or prism and check results.
|
||||||
public void CheckllSetPrimitiveParams(string primTest,
|
public void CheckllSetPrimitiveParams(string primTest,
|
||||||
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
|
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
|
||||||
double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
|
float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
|
||||||
double primHollowCheck)
|
float primHollowCheck)
|
||||||
{
|
{
|
||||||
// Set the prim params.
|
// Set the prim params.
|
||||||
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
|
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
|
||||||
|
@ -297,7 +305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
// Set prim params for a sphere and check results.
|
// Set prim params for a sphere and check results.
|
||||||
public void CheckllSetPrimitiveParams(string primTest,
|
public void CheckllSetPrimitiveParams(string primTest,
|
||||||
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
|
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
|
||||||
double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, double primHollowCheck)
|
float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, float primHollowCheck)
|
||||||
{
|
{
|
||||||
// Set the prim params.
|
// Set the prim params.
|
||||||
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
|
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
|
||||||
|
@ -324,9 +332,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
// Set prim params for a torus, tube or ring and check results.
|
// Set prim params for a torus, tube or ring and check results.
|
||||||
public void CheckllSetPrimitiveParams(string primTest,
|
public void CheckllSetPrimitiveParams(string primTest,
|
||||||
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
|
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
|
||||||
double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
|
float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
|
||||||
LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper,
|
LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper,
|
||||||
double primRev, double primRadius, double primSkew, double primHollowCheck)
|
float primRev, float primRadius, float primSkew, float primHollowCheck)
|
||||||
{
|
{
|
||||||
// Set the prim params.
|
// Set the prim params.
|
||||||
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
|
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
|
||||||
|
@ -353,7 +361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut");
|
CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut");
|
||||||
CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper");
|
CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper");
|
||||||
Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY,
|
Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY,
|
||||||
"TestllSetPrimitiveParams " + primTest + " prim revolution fail");
|
"TestllSetPrimitiveParams " + primTest + " prim revolutions fail");
|
||||||
Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY,
|
Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY,
|
||||||
"TestllSetPrimitiveParams " + primTest + " prim radius fail");
|
"TestllSetPrimitiveParams " + primTest + " prim radius fail");
|
||||||
Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY,
|
Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY,
|
||||||
|
|
|
@ -339,7 +339,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup),
|
m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup),
|
||||||
new Object[] { m_SaveTime });
|
new Object[] { m_SaveTime });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartProcessing()
|
||||||
|
{
|
||||||
m_ThreadPool.Start();
|
m_ThreadPool.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,7 +594,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
|
SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
|
||||||
if (part == null)
|
if (part == null)
|
||||||
{
|
{
|
||||||
m_log.Error("[Script] SceneObjectPart unavailable. Script NOT started.");
|
m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID);
|
||||||
m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n";
|
m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n";
|
||||||
m_ScriptFailCount++;
|
m_ScriptFailCount++;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -90,6 +90,11 @@ namespace OpenSim.Services.Connectors
|
||||||
{
|
{
|
||||||
return m_database.LoadEstateSettings(estateID);
|
return m_database.LoadEstateSettings(estateID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EstateSettings CreateNewEstate()
|
||||||
|
{
|
||||||
|
return m_database.CreateNewEstate();
|
||||||
|
}
|
||||||
|
|
||||||
public List<EstateSettings> LoadEstateSettingsAll()
|
public List<EstateSettings> LoadEstateSettingsAll()
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService
|
||||||
{
|
{
|
||||||
public class XInventoryService : ServiceBase, IInventoryService
|
public class XInventoryService : ServiceBase, IInventoryService
|
||||||
{
|
{
|
||||||
//private static readonly ILog m_log =
|
// private static readonly ILog m_log =
|
||||||
// LogManager.GetLogger(
|
// LogManager.GetLogger(
|
||||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected IXInventoryData m_Database;
|
protected IXInventoryData m_Database;
|
||||||
protected bool m_AllowDelete = true;
|
protected bool m_AllowDelete = true;
|
||||||
|
@ -385,18 +385,22 @@ namespace OpenSim.Services.InventoryService
|
||||||
|
|
||||||
public virtual bool AddItem(InventoryItemBase item)
|
public virtual bool AddItem(InventoryItemBase item)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner);
|
// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner);
|
||||||
|
|
||||||
return m_Database.StoreItem(ConvertFromOpenSim(item));
|
return m_Database.StoreItem(ConvertFromOpenSim(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool UpdateItem(InventoryItemBase item)
|
public virtual bool UpdateItem(InventoryItemBase item)
|
||||||
{
|
{
|
||||||
|
// throw new Exception("urrgh");
|
||||||
if (!m_AllowDelete)
|
if (!m_AllowDelete)
|
||||||
if (item.AssetType == (sbyte)AssetType.Link || item.AssetType == (sbyte)AssetType.LinkFolder)
|
if (item.AssetType == (sbyte)AssetType.Link || item.AssetType == (sbyte)AssetType.LinkFolder)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// m_log.InfoFormat(
|
||||||
|
// "[XINVENTORY SERVICE]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder);
|
||||||
|
|
||||||
return m_Database.StoreItem(ConvertFromOpenSim(item));
|
return m_Database.StoreItem(ConvertFromOpenSim(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,15 +28,15 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
using OpenSim.Data;
|
using OpenSim.Data;
|
||||||
|
using OpenSim.Framework;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework.Console;
|
||||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Services.UserAccountService
|
namespace OpenSim.Services.UserAccountService
|
||||||
{
|
{
|
||||||
public class UserAccountService : UserAccountServiceBase, IUserAccountService
|
public class UserAccountService : UserAccountServiceBase, IUserAccountService
|
||||||
|
@ -44,10 +44,16 @@ namespace OpenSim.Services.UserAccountService
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static UserAccountService m_RootInstance;
|
private static UserAccountService m_RootInstance;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should we create default entries (minimum body parts/clothing, avatar wearable entries) for a new avatar?
|
||||||
|
/// </summary>
|
||||||
|
private bool m_CreateDefaultAvatarEntries;
|
||||||
|
|
||||||
protected IGridService m_GridService;
|
protected IGridService m_GridService;
|
||||||
protected IAuthenticationService m_AuthenticationService;
|
protected IAuthenticationService m_AuthenticationService;
|
||||||
protected IGridUserService m_GridUserService;
|
protected IGridUserService m_GridUserService;
|
||||||
protected IInventoryService m_InventoryService;
|
protected IInventoryService m_InventoryService;
|
||||||
|
protected IAvatarService m_AvatarService;
|
||||||
|
|
||||||
public UserAccountService(IConfigSource config)
|
public UserAccountService(IConfigSource config)
|
||||||
: base(config)
|
: base(config)
|
||||||
|
@ -77,6 +83,12 @@ namespace OpenSim.Services.UserAccountService
|
||||||
if (invServiceDll != string.Empty)
|
if (invServiceDll != string.Empty)
|
||||||
m_InventoryService = LoadPlugin<IInventoryService>(invServiceDll, new Object[] { config });
|
m_InventoryService = LoadPlugin<IInventoryService>(invServiceDll, new Object[] { config });
|
||||||
|
|
||||||
|
string avatarServiceDll = userConfig.GetString("AvatarService", string.Empty);
|
||||||
|
if (avatarServiceDll != string.Empty)
|
||||||
|
m_AvatarService = LoadPlugin<IAvatarService>(avatarServiceDll, new Object[] { config });
|
||||||
|
|
||||||
|
m_CreateDefaultAvatarEntries = userConfig.GetBoolean("CreateDefaultAvatarEntries", false);
|
||||||
|
|
||||||
if (MainConsole.Instance != null)
|
if (MainConsole.Instance != null)
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Commands.AddCommand("UserService", false,
|
MainConsole.Instance.Commands.AddCommand("UserService", false,
|
||||||
|
@ -102,9 +114,7 @@ namespace OpenSim.Services.UserAccountService
|
||||||
"show account <first> <last>",
|
"show account <first> <last>",
|
||||||
"Show account details for the given user", HandleShowAccount);
|
"Show account details for the given user", HandleShowAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IUserAccountService
|
#region IUserAccountService
|
||||||
|
@ -330,7 +340,7 @@ namespace OpenSim.Services.UserAccountService
|
||||||
email = MainConsole.Instance.CmdPrompt("Email", "");
|
email = MainConsole.Instance.CmdPrompt("Email", "");
|
||||||
else email = cmdparams[5];
|
else email = cmdparams[5];
|
||||||
|
|
||||||
CreateUser(firstName, lastName, password, email);
|
CreateUser(UUID.Zero, firstName, lastName, password, email);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void HandleShowAccount(string module, string[] cmdparams)
|
protected void HandleShowAccount(string module, string[] cmdparams)
|
||||||
|
@ -442,11 +452,12 @@ namespace OpenSim.Services.UserAccountService
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a user
|
/// Create a user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="scopeID">Allows hosting of multiple grids in a single database. Normally left as UUID.Zero</param>
|
||||||
/// <param name="firstName"></param>
|
/// <param name="firstName"></param>
|
||||||
/// <param name="lastName"></param>
|
/// <param name="lastName"></param>
|
||||||
/// <param name="password"></param>
|
/// <param name="password"></param>
|
||||||
/// <param name="email"></param>
|
/// <param name="email"></param>
|
||||||
private void CreateUser(string firstName, string lastName, string password, string email)
|
public UserAccount CreateUser(UUID scopeID, string firstName, string lastName, string password, string email)
|
||||||
{
|
{
|
||||||
UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
|
UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
|
||||||
if (null == account)
|
if (null == account)
|
||||||
|
@ -493,12 +504,20 @@ namespace OpenSim.Services.UserAccountService
|
||||||
{
|
{
|
||||||
success = m_InventoryService.CreateUserInventory(account.PrincipalID);
|
success = m_InventoryService.CreateUserInventory(account.PrincipalID);
|
||||||
if (!success)
|
if (!success)
|
||||||
|
{
|
||||||
m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
|
m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
|
||||||
firstName, lastName);
|
firstName, lastName);
|
||||||
|
}
|
||||||
|
else if (m_CreateDefaultAvatarEntries)
|
||||||
|
{
|
||||||
|
CreateDefaultAppearanceEntries(account.PrincipalID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", firstName, lastName);
|
m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", firstName, lastName);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName);
|
m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -506,6 +525,128 @@ namespace OpenSim.Services.UserAccountService
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName);
|
m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateDefaultAppearanceEntries(UUID principalID)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID);
|
||||||
|
|
||||||
|
InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Bodypart);
|
||||||
|
|
||||||
|
InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID);
|
||||||
|
eyes.AssetID = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
|
||||||
|
eyes.Name = "Default Eyes";
|
||||||
|
eyes.CreatorId = principalID.ToString();
|
||||||
|
eyes.AssetType = (int)AssetType.Bodypart;
|
||||||
|
eyes.InvType = (int)InventoryType.Wearable;
|
||||||
|
eyes.Folder = bodyPartsFolder.ID;
|
||||||
|
eyes.BasePermissions = (uint)PermissionMask.All;
|
||||||
|
eyes.CurrentPermissions = (uint)PermissionMask.All;
|
||||||
|
eyes.EveryOnePermissions = (uint)PermissionMask.All;
|
||||||
|
eyes.GroupPermissions = (uint)PermissionMask.All;
|
||||||
|
eyes.NextPermissions = (uint)PermissionMask.All;
|
||||||
|
eyes.Flags = (uint)WearableType.Eyes;
|
||||||
|
m_InventoryService.AddItem(eyes);
|
||||||
|
|
||||||
|
InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID);
|
||||||
|
shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET;
|
||||||
|
shape.Name = "Default Shape";
|
||||||
|
shape.CreatorId = principalID.ToString();
|
||||||
|
shape.AssetType = (int)AssetType.Bodypart;
|
||||||
|
shape.InvType = (int)InventoryType.Wearable;
|
||||||
|
shape.Folder = bodyPartsFolder.ID;
|
||||||
|
shape.BasePermissions = (uint)PermissionMask.All;
|
||||||
|
shape.CurrentPermissions = (uint)PermissionMask.All;
|
||||||
|
shape.EveryOnePermissions = (uint)PermissionMask.All;
|
||||||
|
shape.GroupPermissions = (uint)PermissionMask.All;
|
||||||
|
shape.NextPermissions = (uint)PermissionMask.All;
|
||||||
|
shape.Flags = (uint)WearableType.Shape;
|
||||||
|
m_InventoryService.AddItem(shape);
|
||||||
|
|
||||||
|
InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID);
|
||||||
|
skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET;
|
||||||
|
skin.Name = "Default Skin";
|
||||||
|
skin.CreatorId = principalID.ToString();
|
||||||
|
skin.AssetType = (int)AssetType.Bodypart;
|
||||||
|
skin.InvType = (int)InventoryType.Wearable;
|
||||||
|
skin.Folder = bodyPartsFolder.ID;
|
||||||
|
skin.BasePermissions = (uint)PermissionMask.All;
|
||||||
|
skin.CurrentPermissions = (uint)PermissionMask.All;
|
||||||
|
skin.EveryOnePermissions = (uint)PermissionMask.All;
|
||||||
|
skin.GroupPermissions = (uint)PermissionMask.All;
|
||||||
|
skin.NextPermissions = (uint)PermissionMask.All;
|
||||||
|
skin.Flags = (uint)WearableType.Skin;
|
||||||
|
m_InventoryService.AddItem(skin);
|
||||||
|
|
||||||
|
InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID);
|
||||||
|
hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET;
|
||||||
|
hair.Name = "Default Hair";
|
||||||
|
hair.CreatorId = principalID.ToString();
|
||||||
|
hair.AssetType = (int)AssetType.Bodypart;
|
||||||
|
hair.InvType = (int)InventoryType.Wearable;
|
||||||
|
hair.Folder = bodyPartsFolder.ID;
|
||||||
|
hair.BasePermissions = (uint)PermissionMask.All;
|
||||||
|
hair.CurrentPermissions = (uint)PermissionMask.All;
|
||||||
|
hair.EveryOnePermissions = (uint)PermissionMask.All;
|
||||||
|
hair.GroupPermissions = (uint)PermissionMask.All;
|
||||||
|
hair.NextPermissions = (uint)PermissionMask.All;
|
||||||
|
hair.Flags = (uint)WearableType.Hair;
|
||||||
|
m_InventoryService.AddItem(hair);
|
||||||
|
|
||||||
|
InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Clothing);
|
||||||
|
|
||||||
|
InventoryItemBase shirt = new InventoryItemBase(UUID.Random(), principalID);
|
||||||
|
shirt.AssetID = AvatarWearable.DEFAULT_SHIRT_ASSET;
|
||||||
|
shirt.Name = "Default Shirt";
|
||||||
|
shirt.CreatorId = principalID.ToString();
|
||||||
|
shirt.AssetType = (int)AssetType.Clothing;
|
||||||
|
shirt.InvType = (int)InventoryType.Wearable;
|
||||||
|
shirt.Folder = clothingFolder.ID;
|
||||||
|
shirt.BasePermissions = (uint)PermissionMask.All;
|
||||||
|
shirt.CurrentPermissions = (uint)PermissionMask.All;
|
||||||
|
shirt.EveryOnePermissions = (uint)PermissionMask.All;
|
||||||
|
shirt.GroupPermissions = (uint)PermissionMask.All;
|
||||||
|
shirt.NextPermissions = (uint)PermissionMask.All;
|
||||||
|
shirt.Flags = (uint)WearableType.Shirt;
|
||||||
|
m_InventoryService.AddItem(shirt);
|
||||||
|
|
||||||
|
InventoryItemBase pants = new InventoryItemBase(UUID.Random(), principalID);
|
||||||
|
pants.AssetID = AvatarWearable.DEFAULT_PANTS_ASSET;
|
||||||
|
pants.Name = "Default Pants";
|
||||||
|
pants.CreatorId = principalID.ToString();
|
||||||
|
pants.AssetType = (int)AssetType.Clothing;
|
||||||
|
pants.InvType = (int)InventoryType.Wearable;
|
||||||
|
pants.Folder = clothingFolder.ID;
|
||||||
|
pants.BasePermissions = (uint)PermissionMask.All;
|
||||||
|
pants.CurrentPermissions = (uint)PermissionMask.All;
|
||||||
|
pants.EveryOnePermissions = (uint)PermissionMask.All;
|
||||||
|
pants.GroupPermissions = (uint)PermissionMask.All;
|
||||||
|
pants.NextPermissions = (uint)PermissionMask.All;
|
||||||
|
pants.Flags = (uint)WearableType.Pants;
|
||||||
|
m_InventoryService.AddItem(pants);
|
||||||
|
|
||||||
|
if (m_AvatarService != null)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default avatar entries for {0}", principalID);
|
||||||
|
|
||||||
|
AvatarWearable[] wearables = new AvatarWearable[6];
|
||||||
|
wearables[AvatarWearable.EYES] = new AvatarWearable(eyes.ID, eyes.AssetID);
|
||||||
|
wearables[AvatarWearable.BODY] = new AvatarWearable(shape.ID, shape.AssetID);
|
||||||
|
wearables[AvatarWearable.SKIN] = new AvatarWearable(skin.ID, skin.AssetID);
|
||||||
|
wearables[AvatarWearable.HAIR] = new AvatarWearable(hair.ID, hair.AssetID);
|
||||||
|
wearables[AvatarWearable.SHIRT] = new AvatarWearable(shirt.ID, shirt.AssetID);
|
||||||
|
wearables[AvatarWearable.PANTS] = new AvatarWearable(pants.ID, pants.AssetID);
|
||||||
|
|
||||||
|
AvatarAppearance ap = new AvatarAppearance();
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
ap.SetWearable(i, wearables[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AvatarService.SetAppearance(principalID, ap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -234,7 +234,7 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
public event ScriptReset OnScriptReset;
|
public event ScriptReset OnScriptReset;
|
||||||
public event GetScriptRunning OnGetScriptRunning;
|
public event GetScriptRunning OnGetScriptRunning;
|
||||||
public event SetScriptRunning OnSetScriptRunning;
|
public event SetScriptRunning OnSetScriptRunning;
|
||||||
public event Action<Vector3, bool> OnAutoPilotGo;
|
public event Action<Vector3, bool, bool> OnAutoPilotGo;
|
||||||
|
|
||||||
public event TerrainUnacked OnUnackedTerrain;
|
public event TerrainUnacked OnUnackedTerrain;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenMetaverse;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NUnit.Framework.Constraints;
|
||||||
|
|
||||||
|
namespace OpenSim.Tests.Common
|
||||||
|
{
|
||||||
|
public class QuaternionToleranceConstraint : ANumericalToleranceConstraint
|
||||||
|
{
|
||||||
|
private Quaternion _baseValue;
|
||||||
|
private Quaternion _valueToBeTested;
|
||||||
|
|
||||||
|
public QuaternionToleranceConstraint(Quaternion baseValue, double tolerance) : base(tolerance)
|
||||||
|
{
|
||||||
|
_baseValue = baseValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test whether the constraint is satisfied by a given value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="valueToBeTested">The value to be tested</param>
|
||||||
|
/// <returns>
|
||||||
|
/// True for success, false for failure
|
||||||
|
/// </returns>
|
||||||
|
public override bool Matches(object valueToBeTested)
|
||||||
|
{
|
||||||
|
if (valueToBeTested == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Constraint cannot be used upon null values.");
|
||||||
|
}
|
||||||
|
if (valueToBeTested.GetType() != typeof (Quaternion))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Constraint cannot be used upon non quaternion values.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_valueToBeTested = (Quaternion)valueToBeTested;
|
||||||
|
|
||||||
|
return (IsWithinDoubleConstraint(_valueToBeTested.X, _baseValue.X) &&
|
||||||
|
IsWithinDoubleConstraint(_valueToBeTested.Y, _baseValue.Y) &&
|
||||||
|
IsWithinDoubleConstraint(_valueToBeTested.Z, _baseValue.Z) &&
|
||||||
|
IsWithinDoubleConstraint(_valueToBeTested.W, _baseValue.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteDescriptionTo(MessageWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteExpectedValue(
|
||||||
|
string.Format("A value {0} within tolerance of plus or minus {1}", _baseValue, _tolerance));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteActualValueTo(MessageWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteActualValue(_valueToBeTested);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -149,14 +149,13 @@
|
||||||
|
|
||||||
;; Choose one of the physics engines below
|
;; Choose one of the physics engines below
|
||||||
;; OpenDynamicsEngine is by some distance the most developed physics engine
|
;; OpenDynamicsEngine is by some distance the most developed physics engine
|
||||||
;; basicphysics effectively does not model physics at all, making all
|
;; BulletSim is incomplete and experimental but in active development
|
||||||
;; objects phantom
|
;; basicphysics effectively does not model physics at all, making all objects phantom
|
||||||
;; The Bullet plugins do not work properly right now. A better Bullet plugin is on the way.
|
|
||||||
;; Default is OpenDynamicsEngine
|
;; Default is OpenDynamicsEngine
|
||||||
; physics = OpenDynamicsEngine
|
; physics = OpenDynamicsEngine
|
||||||
|
; physics = BulletSim
|
||||||
; physics = basicphysics
|
; physics = basicphysics
|
||||||
; physics = POS
|
; physics = POS
|
||||||
; physics = modified_BulletX
|
|
||||||
|
|
||||||
;# {permissionmodules} {} {Permission modules to use (may specify multiple modules, separated by space} {} DefaultPermissionsModule
|
;# {permissionmodules} {} {Permission modules to use (may specify multiple modules, separated by space} {} DefaultPermissionsModule
|
||||||
;; Permission modules to use, separated by space.
|
;; Permission modules to use, separated by space.
|
||||||
|
|
|
@ -166,6 +166,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
|
||||||
PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
|
PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
|
||||||
GridService = "OpenSim.Services.GridService.dll:GridService"
|
GridService = "OpenSim.Services.GridService.dll:GridService"
|
||||||
InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
|
InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
|
||||||
|
; AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
|
||||||
|
|
||||||
|
;; This switch creates the minimum set of body parts and avatar entries for a viewer 2
|
||||||
|
;; to show a default "Ruth" avatar rather than a cloud for a newly created user.
|
||||||
|
;; Default is false
|
||||||
|
;; If you enable this you will also need to uncomment the AvatarService line above
|
||||||
|
; CreateDefaultAvatarEntries = false
|
||||||
|
|
||||||
|
|
||||||
[GridUserService]
|
[GridUserService]
|
||||||
; for the server connector
|
; for the server connector
|
||||||
|
|
|
@ -149,6 +149,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
|
||||||
PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
|
PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
|
||||||
GridService = "OpenSim.Services.GridService.dll:GridService"
|
GridService = "OpenSim.Services.GridService.dll:GridService"
|
||||||
InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
|
InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
|
||||||
|
; AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
|
||||||
|
|
||||||
|
;; This switch creates the minimum set of body parts and avatar entries for a viewer 2
|
||||||
|
;; to show a default "Ruth" avatar rather than a cloud for a newly created user.
|
||||||
|
;; Default is false
|
||||||
|
;; If you enable this you will also need to uncomment the AvatarService line above
|
||||||
|
; CreateDefaultAvatarEntries = false
|
||||||
|
|
||||||
|
|
||||||
[GridUserService]
|
[GridUserService]
|
||||||
; for the server connector
|
; for the server connector
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66"/>
|
<Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66"/>
|
||||||
<Key Name="name" Value="Hair"/>
|
<Key Name="name" Value="Hair"/>
|
||||||
<Key Name="assetType" Value="13" />
|
<Key Name="assetType" Value="13" />
|
||||||
<Key Name="fileName" Value="newhair.dat"/>
|
<Key Name="fileName" Value="base_hair.dat"/>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
<Section Name="Skin">
|
<Section Name="Skin">
|
||||||
|
@ -34,6 +34,14 @@
|
||||||
<Key Name="assetType" Value="13" />
|
<Key Name="assetType" Value="13" />
|
||||||
<Key Name="fileName" Value="base_shape.dat"/>
|
<Key Name="fileName" Value="base_shape.dat"/>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
|
<Section Name="Eyes">
|
||||||
|
<Key Name="assetID" Value="4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7"/>
|
||||||
|
<Key Name="name" Value="Eyes"/>
|
||||||
|
<Key Name="assetType" Value="13" />
|
||||||
|
<Key Name="fileName" Value="base_eyes.dat"/>
|
||||||
|
</Section>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<Section Name="Jim Shape">
|
<Section Name="Jim Shape">
|
||||||
<Key Name="assetID" Value="66c41e39-38f9-f75a-024e-585989bfab74"/>
|
<Key Name="assetID" Value="66c41e39-38f9-f75a-024e-585989bfab74"/>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
LLWearable version 22
|
||||||
|
New Eyes
|
||||||
|
|
||||||
|
permissions 0
|
||||||
|
{
|
||||||
|
base_mask 7fffffff
|
||||||
|
owner_mask 7fffffff
|
||||||
|
group_mask 00000000
|
||||||
|
everyone_mask 00000000
|
||||||
|
next_owner_mask 00082000
|
||||||
|
creator_id 11111111-1111-0000-0000-000100bba000
|
||||||
|
owner_id 11111111-1111-0000-0000-000100bba000
|
||||||
|
last_owner_id 00000000-0000-0000-0000-000000000000
|
||||||
|
group_id 00000000-0000-0000-0000-000000000000
|
||||||
|
}
|
||||||
|
sale_info 0
|
||||||
|
{
|
||||||
|
sale_type not
|
||||||
|
sale_price 10
|
||||||
|
}
|
||||||
|
type 3
|
||||||
|
parameters 2
|
||||||
|
98 0
|
||||||
|
99 0
|
||||||
|
textures 1
|
||||||
|
3 6522e74d-1660-4e7f-b601-6f48c1659a77
|
|
@ -8,8 +8,8 @@ New Hair
|
||||||
group_mask 00000000
|
group_mask 00000000
|
||||||
everyone_mask 00000000
|
everyone_mask 00000000
|
||||||
next_owner_mask 00082000
|
next_owner_mask 00082000
|
||||||
creator_id a52db6d0-e96c-4454-85e5-3523722daa25
|
creator_id 11111111-1111-0000-0000-000100bba000
|
||||||
owner_id a52db6d0-e96c-4454-85e5-3523722daa25
|
owner_id 11111111-1111-0000-0000-000100bba000
|
||||||
last_owner_id 00000000-0000-0000-0000-000000000000
|
last_owner_id 00000000-0000-0000-0000-000000000000
|
||||||
group_id 00000000-0000-0000-0000-000000000000
|
group_id 00000000-0000-0000-0000-000000000000
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ New Hair
|
||||||
sale_price 10
|
sale_price 10
|
||||||
}
|
}
|
||||||
type 2
|
type 2
|
||||||
parameters 39
|
parameters 90
|
||||||
16 0
|
16 0
|
||||||
31 .5
|
31 .5
|
||||||
112 0
|
112 0
|
||||||
|
@ -38,26 +38,77 @@ parameters 39
|
||||||
140 0
|
140 0
|
||||||
141 0
|
141 0
|
||||||
142 0
|
142 0
|
||||||
143 .13
|
143 .12
|
||||||
|
144 .1
|
||||||
|
145 0
|
||||||
|
146 0
|
||||||
|
147 0
|
||||||
|
148 .22
|
||||||
|
149 0
|
||||||
166 0
|
166 0
|
||||||
167 0
|
167 0
|
||||||
168 0
|
168 0
|
||||||
169 0
|
169 0
|
||||||
|
171 0
|
||||||
|
172 .5
|
||||||
|
173 0
|
||||||
|
174 0
|
||||||
|
175 .3
|
||||||
|
176 0
|
||||||
177 0
|
177 0
|
||||||
|
178 0
|
||||||
|
179 0
|
||||||
|
180 .13
|
||||||
181 .14
|
181 .14
|
||||||
182 .7
|
182 .7
|
||||||
183 .05
|
183 .05
|
||||||
184 0
|
184 0
|
||||||
|
190 0
|
||||||
|
191 0
|
||||||
192 0
|
192 0
|
||||||
|
400 .75
|
||||||
|
640 0
|
||||||
|
641 0
|
||||||
|
642 0
|
||||||
|
643 0
|
||||||
|
644 0
|
||||||
|
645 0
|
||||||
674 -.3
|
674 -.3
|
||||||
750 .7
|
750 .7
|
||||||
|
751 0
|
||||||
752 .5
|
752 .5
|
||||||
754 0
|
754 0
|
||||||
755 .05
|
755 .05
|
||||||
757 -1
|
757 -1
|
||||||
|
761 0
|
||||||
762 0
|
762 0
|
||||||
763 .55
|
763 .55
|
||||||
|
771 0
|
||||||
|
774 0
|
||||||
|
782 0
|
||||||
|
783 0
|
||||||
|
784 0
|
||||||
785 0
|
785 0
|
||||||
|
786 0
|
||||||
|
787 0
|
||||||
|
788 0
|
||||||
789 0
|
789 0
|
||||||
|
790 0
|
||||||
|
870 -.29
|
||||||
|
871 0
|
||||||
|
872 .25
|
||||||
|
1000 .5
|
||||||
|
1001 .5
|
||||||
|
1002 .7
|
||||||
|
1003 .7
|
||||||
|
1004 0
|
||||||
|
1005 0
|
||||||
|
1006 0
|
||||||
|
1007 0
|
||||||
|
1008 0
|
||||||
|
1009 0
|
||||||
|
1010 0
|
||||||
|
1011 0
|
||||||
|
1012 .25
|
||||||
textures 1
|
textures 1
|
||||||
4 7ca39b4c-bd19-4699-aff7-f93fd03d3e7b
|
4 7ca39b4c-bd19-4699-aff7-f93fd03d3e7b
|
|
@ -1,105 +1,165 @@
|
||||||
LLWearable version 22
|
LLWearable version 22
|
||||||
Female Shape and Outfit 3 Shape
|
New Shape
|
||||||
Created by system from avatar's appearance.
|
|
||||||
permissions 0
|
permissions 0
|
||||||
{
|
{
|
||||||
base_mask 00000000
|
base_mask 7fffffff
|
||||||
owner_mask 00000000
|
owner_mask 7fffffff
|
||||||
group_mask 00000000
|
group_mask 00000000
|
||||||
everyone_mask 00000000
|
everyone_mask 00000000
|
||||||
next_owner_mask 00000000
|
next_owner_mask 00082000
|
||||||
creator_id 11111111-1111-0000-0000-000100bba000
|
creator_id 11111111-1111-0000-0000-000100bba000
|
||||||
owner_id 11111111-1111-0000-0000-000100bba000
|
owner_id 11111111-1111-0000-0000-000100bba000
|
||||||
last_owner_id 11111111-1111-0000-0000-000100bba000
|
last_owner_id 00000000-0000-0000-0000-000000000000
|
||||||
group_id 00000000-0000-0000-0000-000000000000
|
group_id 00000000-0000-0000-0000-000000000000
|
||||||
}
|
}
|
||||||
sale_info 0
|
sale_info 0
|
||||||
{
|
{
|
||||||
sale_type not
|
sale_type not
|
||||||
sale_price 0
|
sale_price 10
|
||||||
}
|
}
|
||||||
type 0
|
type 0
|
||||||
parameters 82
|
parameters 142
|
||||||
1 .21
|
1 0
|
||||||
2 -.5
|
2 0
|
||||||
4 -.11
|
4 0
|
||||||
5 -.1
|
5 0
|
||||||
6 -.3
|
6 0
|
||||||
7 -.4
|
7 0
|
||||||
8 -.5
|
8 0
|
||||||
10 .7
|
10 0
|
||||||
11 .34
|
11 0
|
||||||
12 -.5
|
12 0
|
||||||
13 0
|
13 0
|
||||||
14 .04
|
14 0
|
||||||
15 .58
|
15 0
|
||||||
17 .56
|
17 0
|
||||||
18 -.26
|
18 0
|
||||||
19 -.73
|
19 0
|
||||||
20 -.34
|
20 0
|
||||||
21 -.01
|
21 0
|
||||||
22 1
|
22 0
|
||||||
23 -.5
|
23 0
|
||||||
24 -.63
|
24 0
|
||||||
25 .44
|
25 0
|
||||||
27 .05
|
26 0
|
||||||
33 -.24
|
27 0
|
||||||
34 -.7
|
28 0
|
||||||
35 -.16
|
29 .12
|
||||||
36 -.2
|
30 .12
|
||||||
37 -.98
|
32 0
|
||||||
38 -.5
|
33 0
|
||||||
|
34 0
|
||||||
|
35 0
|
||||||
|
36 -.5
|
||||||
|
37 0
|
||||||
|
38 0
|
||||||
|
40 0
|
||||||
80 0
|
80 0
|
||||||
105 .07
|
100 0
|
||||||
155 -.22
|
104 0
|
||||||
|
105 .5
|
||||||
|
106 0
|
||||||
|
151 0
|
||||||
|
152 0
|
||||||
|
153 0
|
||||||
|
155 0
|
||||||
|
156 0
|
||||||
157 0
|
157 0
|
||||||
185 -1
|
185 0
|
||||||
193 .86
|
186 0
|
||||||
196 -.74
|
187 0
|
||||||
505 .65
|
188 0
|
||||||
506 .12
|
189 0
|
||||||
507 -1.5
|
193 .5
|
||||||
|
194 .67
|
||||||
|
195 .33
|
||||||
|
196 0
|
||||||
|
505 .5
|
||||||
|
506 0
|
||||||
|
507 0
|
||||||
515 0
|
515 0
|
||||||
517 .16
|
517 0
|
||||||
518 .8
|
518 0
|
||||||
629 0
|
626 0
|
||||||
|
627 0
|
||||||
|
629 .5
|
||||||
|
630 0
|
||||||
|
631 0
|
||||||
|
633 0
|
||||||
|
634 0
|
||||||
|
635 0
|
||||||
637 0
|
637 0
|
||||||
646 .4
|
646 0
|
||||||
647 1
|
647 0
|
||||||
649 .36
|
648 0
|
||||||
650 .85
|
649 .5
|
||||||
652 .49
|
650 0
|
||||||
653 -1
|
651 0
|
||||||
|
652 .5
|
||||||
|
653 0
|
||||||
|
655 -.08
|
||||||
656 0
|
656 0
|
||||||
659 .65
|
657 0
|
||||||
|
658 0
|
||||||
|
659 .5
|
||||||
|
660 0
|
||||||
|
661 0
|
||||||
662 .5
|
662 .5
|
||||||
663 0
|
663 0
|
||||||
664 0
|
664 0
|
||||||
665 0
|
665 0
|
||||||
675 -.15
|
675 0
|
||||||
676 .26
|
676 0
|
||||||
678 .28
|
677 0
|
||||||
682 .27
|
678 .5
|
||||||
683 -.19
|
679 -.08
|
||||||
684 -.09
|
680 -.08
|
||||||
|
681 -.08
|
||||||
|
682 .5
|
||||||
|
683 -.15
|
||||||
|
684 0
|
||||||
685 0
|
685 0
|
||||||
690 .45
|
686 0
|
||||||
692 .4
|
687 0
|
||||||
693 -0
|
688 0
|
||||||
753 -.5
|
689 0
|
||||||
756 -.08
|
690 .5
|
||||||
758 .24
|
691 0
|
||||||
759 .6
|
692 0
|
||||||
760 .11
|
693 .6
|
||||||
764 -.38
|
694 -.08
|
||||||
765 -.3
|
695 0
|
||||||
769 .42
|
753 0
|
||||||
773 .51
|
756 0
|
||||||
795 .16
|
758 0
|
||||||
796 .11
|
759 .5
|
||||||
799 .36
|
760 0
|
||||||
|
764 0
|
||||||
|
765 0
|
||||||
|
767 0
|
||||||
|
768 0
|
||||||
|
769 .5
|
||||||
|
770 0
|
||||||
|
772 0
|
||||||
|
773 .5
|
||||||
|
794 .17
|
||||||
|
795 .25
|
||||||
|
796 0
|
||||||
|
797 0
|
||||||
|
798 0
|
||||||
|
799 .5
|
||||||
841 0
|
841 0
|
||||||
842 -.82
|
842 0
|
||||||
|
843 0
|
||||||
|
853 0
|
||||||
|
854 0
|
||||||
|
855 0
|
||||||
879 0
|
879 0
|
||||||
880 0
|
880 0
|
||||||
|
1103 0
|
||||||
|
1104 0
|
||||||
|
1105 0
|
||||||
|
1200 0
|
||||||
|
1201 0
|
||||||
textures 0
|
textures 0
|
||||||
|
|
|
@ -430,6 +430,13 @@
|
||||||
<Key Name="fileName" Value="default_avatar.jp2" />
|
<Key Name="fileName" Value="default_avatar.jp2" />
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
|
<Section Name="Default Iris">
|
||||||
|
<Key Name="assetID" Value="6522e74d-1660-4e7f-b601-6f48c1659a77"/>
|
||||||
|
<Key Name="name" Value="Default Iris"/>
|
||||||
|
<Key Name="assetType" Value="0" />
|
||||||
|
<Key Name="fileName" Value="default_iris.jp2" />
|
||||||
|
</Section>
|
||||||
|
|
||||||
<Section Name="Cypress 1">
|
<Section Name="Cypress 1">
|
||||||
<Key Name="assetID" Value="fb2ae204-3fd1-df33-594f-c9f882830e66"/>
|
<Key Name="assetID" Value="fb2ae204-3fd1-df33-594f-c9f882830e66"/>
|
||||||
<Key Name="name" Value="Cypress 1"/>
|
<Key Name="name" Value="Cypress 1"/>
|
||||||
|
|
Binary file not shown.
|
@ -17,12 +17,12 @@
|
||||||
AvatarServices = "LocalAvatarServicesConnector"
|
AvatarServices = "LocalAvatarServicesConnector"
|
||||||
EntityTransferModule = "BasicEntityTransferModule"
|
EntityTransferModule = "BasicEntityTransferModule"
|
||||||
InventoryAccessModule = "BasicInventoryAccessModule"
|
InventoryAccessModule = "BasicInventoryAccessModule"
|
||||||
MapImageService = "MapImageServiceModule"
|
MapImageService = "MapImageServiceModule"
|
||||||
|
|
||||||
LibraryModule = true
|
LibraryModule = true
|
||||||
LLLoginServiceInConnector = true
|
LLLoginServiceInConnector = true
|
||||||
GridInfoServiceInConnector = true
|
GridInfoServiceInConnector = true
|
||||||
MapImageServiceInConnector = true
|
MapImageServiceInConnector = true
|
||||||
|
|
||||||
[Profile]
|
[Profile]
|
||||||
Module = "BasicProfileModule"
|
Module = "BasicProfileModule"
|
||||||
|
@ -70,6 +70,10 @@
|
||||||
GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService"
|
GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService"
|
||||||
GridService = "OpenSim.Services.GridService.dll:GridService"
|
GridService = "OpenSim.Services.GridService.dll:GridService"
|
||||||
InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
|
InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
|
||||||
|
AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
|
||||||
|
|
||||||
|
;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 to show a default "Ruth" avatar rather than a cloud.
|
||||||
|
CreateDefaultAvatarEntries = true
|
||||||
|
|
||||||
[GridUserService]
|
[GridUserService]
|
||||||
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"
|
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"
|
||||||
|
|
|
@ -561,4 +561,14 @@
|
||||||
<Key Name="assetType" Value="0" />
|
<Key Name="assetType" Value="0" />
|
||||||
<Key Name="inventoryType" Value="0" />
|
<Key Name="inventoryType" Value="0" />
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
|
<Section Name="Default Iris Texture">
|
||||||
|
<Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000013"/>
|
||||||
|
<Key Name="assetID" Value="6522e74d-1660-4e7f-b601-6f48c1659a77"/>
|
||||||
|
<Key Name="folderID" Value="00000112-000f-0000-0000-000100bba001"/>
|
||||||
|
<Key Name="description" Value=""/>
|
||||||
|
<Key Name="name" Value="Default Iris Texture" />
|
||||||
|
<Key Name="assetType" Value="0" />
|
||||||
|
<Key Name="inventoryType" Value="0" />
|
||||||
|
</Section>
|
||||||
</Nini>
|
</Nini>
|
||||||
|
|
59
prebuild.xml
59
prebuild.xml
|
@ -573,34 +573,6 @@
|
||||||
</Files>
|
</Files>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletXPlugin" path="OpenSim/Region/Physics/BulletXPlugin" type="Library">
|
|
||||||
<Configuration name="Debug">
|
|
||||||
<Options>
|
|
||||||
<OutputPath>../../../../bin/Physics/</OutputPath>
|
|
||||||
</Options>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration name="Release">
|
|
||||||
<Options>
|
|
||||||
<OutputPath>../../../../bin/Physics/</OutputPath>
|
|
||||||
</Options>
|
|
||||||
</Configuration>
|
|
||||||
|
|
||||||
<ReferencePath>../../../../bin/</ReferencePath>
|
|
||||||
<Reference name="System"/>
|
|
||||||
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
|
|
||||||
<Reference name="Nini" path="../../../../bin/"/>
|
|
||||||
<Reference name="OpenSim.Framework"/>
|
|
||||||
<Reference name="OpenSim.Framework.Console"/>
|
|
||||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
|
||||||
<Reference name="MonoXnaCompactMaths" path="../../../../bin/"/>
|
|
||||||
<Reference name="Modified.XnaDevRu.BulletX" path="../../../../bin/"/>
|
|
||||||
<Reference name="log4net" path="../../../../bin/"/>
|
|
||||||
|
|
||||||
<Files>
|
|
||||||
<Match pattern="*.cs" recurse="true"/>
|
|
||||||
</Files>
|
|
||||||
</Project>
|
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library">
|
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library">
|
||||||
<Configuration name="Debug">
|
<Configuration name="Debug">
|
||||||
<Options>
|
<Options>
|
||||||
|
@ -690,34 +662,6 @@
|
||||||
</Files>
|
</Files>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletDotNETPlugin" path="OpenSim/Region/Physics/BulletDotNETPlugin" type="Library">
|
|
||||||
<Configuration name="Debug">
|
|
||||||
<Options>
|
|
||||||
<OutputPath>../../../../bin/Physics/</OutputPath>
|
|
||||||
</Options>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration name="Release">
|
|
||||||
<Options>
|
|
||||||
<OutputPath>../../../../bin/Physics/</OutputPath>
|
|
||||||
</Options>
|
|
||||||
</Configuration>
|
|
||||||
|
|
||||||
<ReferencePath>../../../../bin/</ReferencePath>
|
|
||||||
<Reference name="System"/>
|
|
||||||
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
|
|
||||||
<Reference name="Nini" path="../../../../bin/"/>
|
|
||||||
<Reference name="OpenSim.Framework"/>
|
|
||||||
<Reference name="OpenSim.Framework.Console"/>
|
|
||||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
|
||||||
<Reference name="BulletDotNET" path="../../../../bin/"/>
|
|
||||||
<Reference name="nunit.framework" path="../../../../bin/"/>
|
|
||||||
<Reference name="log4net" path="../../../../bin/"/>
|
|
||||||
|
|
||||||
<Files>
|
|
||||||
<Match pattern="*.cs" recurse="true"/>
|
|
||||||
</Files>
|
|
||||||
</Project>
|
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Capabilities" path="OpenSim/Capabilities" type="Library">
|
<Project frameworkVersion="v3_5" name="OpenSim.Capabilities" path="OpenSim/Capabilities" type="Library">
|
||||||
<Configuration name="Debug">
|
<Configuration name="Debug">
|
||||||
<Options>
|
<Options>
|
||||||
|
@ -1840,6 +1784,9 @@
|
||||||
<Reference name="OpenSim.Region.ClientStack"/>
|
<Reference name="OpenSim.Region.ClientStack"/>
|
||||||
<Reference name="OpenSim.Framework.Communications"/>
|
<Reference name="OpenSim.Framework.Communications"/>
|
||||||
<Reference name="OpenSim.Server.Base"/>
|
<Reference name="OpenSim.Server.Base"/>
|
||||||
|
<Reference name="OpenSim.Services.Base"/>
|
||||||
|
<Reference name="OpenSim.Services.Interfaces"/>
|
||||||
|
<Reference name="OpenSim.Services.UserAccountService"/>
|
||||||
<Reference name="XMLRPC" path="../../../bin/"/>
|
<Reference name="XMLRPC" path="../../../bin/"/>
|
||||||
<Reference name="Nini" path="../../../bin/"/>
|
<Reference name="Nini" path="../../../bin/"/>
|
||||||
<Reference name="log4net" path="../../../bin/"/>
|
<Reference name="log4net" path="../../../bin/"/>
|
||||||
|
|
Loading…
Reference in New Issue