Merge branch 'master' into 0.7.2-post-fixes

0.7.2-post-fixes
Justin Clark-Casey (justincc) 2011-09-23 22:36:20 +01:00
commit 8c4dd6b330
97 changed files with 2689 additions and 8334 deletions

View File

@ -117,6 +117,7 @@ what it is today.
* nornalbion
* Omar Vera Ustariz (IBM)
* openlifegrid.com
* Oren Hurvitz (Kitely)
* otakup0pe
* ralphos
* RemedyTomm

View File

@ -709,6 +709,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// ok, client wants us to use an explicit UUID
// regardless of what the avatar name provided
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"))
{
@ -720,6 +728,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
IUserAccountService accountService = currentOrFirst.UserAccountService;
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
ownerFirst, ownerLast);
// Check that the specified user exists
if (user == null)
throw new Exception("Specified user was not found.");
userID = user.PrincipalID;
}
else
@ -728,22 +741,31 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
// 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.EstateOwner = userID;
// Persistence does not seem to effect the need to save a new estate
region.EstateSettings.Save();
if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID))
throw new Exception("Failed to join estate.");
}
else
{
int estateID = estateIDs[0];
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false);
if (region.EstateSettings.EstateID != estateID)
{
// 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

View File

@ -169,7 +169,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]);
float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]);
Vector3 vector = new Vector3(x, y, z);
presence.MoveToTarget(vector, false);
presence.MoveToTarget(vector, false, false);
}
catch (Exception e)
{

View File

@ -148,14 +148,46 @@ namespace OpenSim.Data.MSSQL
}
}
if (insertEstate && create)
{
DoCreate(es);
LinkRegion(regionID, (int)es.EstateID);
}
LoadBanList(es);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
//Set event
es.OnSave += StoreEstateSettings;
return es;
}
public 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");
sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
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))
@ -176,40 +208,10 @@ namespace OpenSim.Data.MSSQL
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);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
//Set event
es.OnSave += StoreEstateSettings;
return es;
}
/// <summary>
/// Stores the estate settings.
/// </summary>
@ -498,24 +500,43 @@ namespace OpenSim.Data.MSSQL
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))
{
conn.Open();
SqlTransaction transaction = conn.BeginTransaction();
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);
int ret = cmd.ExecuteNonQuery();
if (ret != 0)
transaction.Commit();
else
transaction.Rollback();
return (ret != 0);
}
}
catch (Exception ex)
{
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
transaction.Rollback();
}
}
return false;

View File

@ -218,23 +218,27 @@ namespace OpenSim.Data.MSSQL
if (words.Length > 2)
return new UserAccountData[0];
string sql = "";
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand())
{
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("@search", "%" + words[0] + "%"));
}
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("@searchLast", "%" + words[1] + "%"));
cmd.Parameters.Add(m_database.CreateParameter("@ScopeID", scopeID.ToString()));
}
cmd.Connection = conn;
cmd.CommandText = sql;
conn.Open();
return DoQuery(cmd);
}
}

View File

@ -20,3 +20,31 @@ INSERT INTO Friends (PrincipalID, Friend, Flags, Offered)
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

View File

@ -245,3 +245,35 @@ ADD CONSTRAINT DF_inventoryitems_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

View File

@ -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>

View File

@ -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)
{
EstateSettings es = new EstateSettings();
@ -187,6 +203,21 @@ namespace OpenSim.Data.MySQL
}
if (!found && create)
{
DoCreate(es);
LinkRegion(regionID, (int)es.EstateID);
}
}
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)
{
// Migration case
List<string> names = new List<string>(FieldList);
@ -195,6 +226,9 @@ namespace OpenSim.Data.MySQL
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;
@ -226,27 +260,11 @@ namespace OpenSim.Data.MySQL
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();
}
}
}
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;
}
public void StoreEstateSettings(EstateSettings es)
{
string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")";
@ -477,7 +495,6 @@ namespace OpenSim.Data.MySQL
}
}
dbcon.Close();
}
@ -507,7 +524,6 @@ namespace OpenSim.Data.MySQL
}
}
dbcon.Close();
}
@ -519,16 +535,34 @@ namespace OpenSim.Data.MySQL
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlTransaction transaction = dbcon.BeginTransaction();
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())
{
cmd.Transaction = transaction;
cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
cmd.Parameters.AddWithValue("?RegionID", regionID);
cmd.Parameters.AddWithValue("?EstateID", estateID);
int ret = cmd.ExecuteNonQuery();
if (ret != 0)
transaction.Commit();
else
transaction.Rollback();
dbcon.Close();
return (ret != 0);
@ -537,6 +571,7 @@ namespace OpenSim.Data.MySQL
catch (MySqlException ex)
{
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
transaction.Rollback();
}
dbcon.Close();

View File

@ -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>

View File

@ -85,6 +85,11 @@ namespace OpenSim.Data.Null
return new EstateSettings();
}
public EstateSettings CreateNewEstate()
{
return new EstateSettings();
}
public List<EstateSettings> LoadEstateSettingsAll()
{
List<EstateSettings> allEstateSettings = new List<EstateSettings>();

View File

@ -78,7 +78,9 @@ namespace OpenSim.Data.Null
public RegionSettings LoadRegionSettings(UUID regionUUID)
{
return null;
RegionSettings rs = new RegionSettings();
rs.RegionUUID = regionUUID;
return rs;
}
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)

View File

@ -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>

View File

@ -151,10 +151,41 @@ namespace OpenSim.Data.SQLite
}
else if (create)
{
r.Close();
DoCreate(es);
LinkRegion(regionID, (int)es.EstateID);
}
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;
}
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())+")";
@ -190,30 +221,9 @@ namespace OpenSim.Data.SQLite
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);
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
return es;
}
public void StoreEstateSettings(EstateSettings es)
{
List<string> fields = new List<string>(FieldList);
@ -440,17 +450,37 @@ namespace OpenSim.Data.SQLite
public bool LinkRegion(UUID regionID, int estateID)
{
SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
SqliteTransaction transaction = m_connection.BeginTransaction();
// Delete any existing estate mapping for this region.
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = "delete from estate_map where RegionID = :RegionID";
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
cmd.ExecuteNonQuery();
}
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)
{

View File

@ -167,6 +167,7 @@ namespace OpenSim.Framework
get { return m_metadata.FullID; }
set { m_metadata.FullID = value; }
}
/// <summary>
/// Asset MetaData ID (transferring from UUID to string ID)
/// </summary>

View File

@ -225,6 +225,8 @@ namespace OpenSim.Framework
/// </summary>
public virtual void ResetAppearance()
{
// m_log.WarnFormat("[AVATAR APPEARANCE]: Reset appearance");
m_serial = 0;
SetDefaultTexture();
@ -391,11 +393,15 @@ namespace OpenSim.Framework
public List<AvatarAttachment> GetAttachments()
{
List<AvatarAttachment> alist = new List<AvatarAttachment>();
lock (m_attachments)
{
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{
foreach (AvatarAttachment attach in kvp.Value)
alist.Add(new AvatarAttachment(attach));
}
}
return alist;
}
@ -406,11 +412,14 @@ namespace OpenSim.Framework
// "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}",
// attach.ItemID, attach.AssetID, attach.AttachPoint);
lock (m_attachments)
{
if (!m_attachments.ContainsKey(attach.AttachPoint))
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
m_attachments[attach.AttachPoint].Add(attach);
}
}
internal void ReplaceAttachment(AvatarAttachment attach)
{
@ -418,9 +427,12 @@ namespace OpenSim.Framework
// "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
// attach.ItemID, attach.AssetID, attach.AttachPoint);
lock (m_attachments)
{
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
m_attachments[attach.AttachPoint].Add(attach);
}
}
/// <summary>
/// Set an attachment
@ -447,12 +459,15 @@ namespace OpenSim.Framework
return false;
if (item == UUID.Zero)
{
lock (m_attachments)
{
if (m_attachments.ContainsKey(attachpoint))
{
m_attachments.Remove(attachpoint);
return true;
}
}
return false;
}
@ -493,6 +508,8 @@ namespace OpenSim.Framework
/// <param name="itemID"></param>
/// <returns>Returns null if this item is not attached.</returns>
public AvatarAttachment GetAttachmentForItem(UUID itemID)
{
lock (m_attachments)
{
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{
@ -500,11 +517,14 @@ namespace OpenSim.Framework
if (index >= 0)
return kvp.Value[index];
}
}
return null;
}
public int GetAttachpoint(UUID itemID)
{
lock (m_attachments)
{
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{
@ -512,11 +532,14 @@ namespace OpenSim.Framework
if (index >= 0)
return kvp.Key;
}
}
return 0;
}
public bool DetachAttachment(UUID itemID)
{
lock (m_attachments)
{
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{
@ -533,11 +556,14 @@ namespace OpenSim.Framework
return true;
}
}
}
return false;
}
public void ClearAttachments()
{
lock (m_attachments)
m_attachments.Clear();
}
@ -576,7 +602,8 @@ namespace OpenSim.Framework
data["visualparams"] = visualparams;
// Attachments
OSDArray attachs = new OSDArray(m_attachments.Count);
List<AvatarAttachment> attachments = GetAttachments();
OSDArray attachs = new OSDArray(attachments.Count);
foreach (AvatarAttachment attach in GetAttachments())
attachs.Add(attach.Pack());
data["attachments"] = attachs;

View File

@ -441,7 +441,6 @@ namespace OpenSim.Framework
args["controllers"] = controls;
}
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
args["callback_uri"] = OSD.FromString(CallbackURI);

View File

@ -46,12 +46,11 @@ namespace OpenSim.Framework.Console
// private readonly object m_syncRoot = new object();
private const string LOGLEVEL_NONE = "(none)";
private int y = -1;
private int cp = 0;
private int h = 1;
private StringBuilder cmdline = new StringBuilder();
private bool echo = true;
private List<string> history = new List<string>();
private int m_cursorYPosition = -1;
private int m_cursorXPosition = 0;
private StringBuilder m_commandLine = new StringBuilder();
private bool m_echo = true;
private List<string> m_history = new List<string>();
private static readonly ConsoleColor[] Colors = {
// 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)
{
while (history.Count >= 100)
history.RemoveAt(0);
while (m_history.Count >= 100)
m_history.RemoveAt(0);
history.Add(text);
m_history.Add(text);
}
/// <summary>
@ -111,11 +110,11 @@ namespace OpenSim.Framework.Console
}
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)
if (bw > 0 && left >= bw)
System.Console.CursorLeft = bw - 1;
if (bufferWidth > 0 && left >= bufferWidth)
System.Console.CursorLeft = bufferWidth - 1;
}
if (top < 0)
@ -124,11 +123,11 @@ namespace OpenSim.Framework.Console
}
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)
if (bh > 0 && top >= bh)
top = bh - 1;
if (bufferHeight > 0 && top >= bufferHeight)
top = bufferHeight - 1;
}
System.Console.CursorTop = top;
@ -160,10 +159,10 @@ namespace OpenSim.Framework.Console
}
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)
if (bh > 0 && top >= bh)
System.Console.CursorTop = bh - 1;
if (bufferHeight > 0 && top >= bufferHeight)
System.Console.CursorTop = bufferHeight - 1;
}
if (left < 0)
@ -172,11 +171,11 @@ namespace OpenSim.Framework.Console
}
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)
if (bw > 0 && left >= bw)
left = bw - 1;
if (bufferWidth > 0 && left >= bufferWidth)
left = bufferWidth - 1;
}
System.Console.CursorLeft = left;
@ -186,31 +185,30 @@ namespace OpenSim.Framework.Console
private void Show()
{
lock (cmdline)
lock (m_commandLine)
{
if (y == -1 || System.Console.BufferWidth == 0)
if (m_cursorYPosition == -1 || System.Console.BufferWidth == 0)
return;
int xc = prompt.Length + cp;
int xc = prompt.Length + m_cursorXPosition;
int new_x = xc % System.Console.BufferWidth;
int new_y = y + xc / System.Console.BufferWidth;
int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
if (end_y / System.Console.BufferWidth >= h)
h++;
int new_y = m_cursorYPosition + xc / System.Console.BufferWidth;
int end_y = m_cursorYPosition + (m_commandLine.Length + prompt.Length) / System.Console.BufferWidth;
if (end_y >= System.Console.BufferHeight) // wrap
{
y--;
m_cursorYPosition--;
new_y--;
SetCursorLeft(0);
SetCursorTop(System.Console.BufferHeight - 1);
System.Console.WriteLine(" ");
}
y = SetCursorTop(y);
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
SetCursorLeft(0);
if (echo)
System.Console.Write("{0}{1}", prompt, cmdline);
if (m_echo)
System.Console.Write("{0}{1}", prompt, m_commandLine);
else
System.Console.Write("{0}", prompt);
@ -221,20 +219,20 @@ namespace OpenSim.Framework.Console
public override void LockOutput()
{
Monitor.Enter(cmdline);
Monitor.Enter(m_commandLine);
try
{
if (y != -1)
if (m_cursorYPosition != -1)
{
y = SetCursorTop(y);
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
System.Console.CursorLeft = 0;
int count = cmdline.Length + prompt.Length;
int count = m_commandLine.Length + prompt.Length;
while (count-- > 0)
System.Console.Write(" ");
y = SetCursorTop(y);
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
SetCursorLeft(0);
}
}
@ -245,12 +243,12 @@ namespace OpenSim.Framework.Console
public override void UnlockOutput()
{
if (y != -1)
if (m_cursorYPosition != -1)
{
y = System.Console.CursorTop;
m_cursorYPosition = System.Console.CursorTop;
Show();
}
Monitor.Exit(cmdline);
Monitor.Exit(m_commandLine);
}
private void WriteColorText(ConsoleColor color, string sender)
@ -317,29 +315,29 @@ namespace OpenSim.Framework.Console
public override void Output(string text, string level)
{
lock (cmdline)
lock (m_commandLine)
{
if (y == -1)
if (m_cursorYPosition == -1)
{
WriteLocalText(text, level);
return;
}
y = SetCursorTop(y);
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
SetCursorLeft(0);
int count = cmdline.Length + prompt.Length;
int count = m_commandLine.Length + prompt.Length;
while (count-- > 0)
System.Console.Write(" ");
y = SetCursorTop(y);
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
SetCursorLeft(0);
WriteLocalText(text, level);
y = System.Console.CursorTop;
m_cursorYPosition = System.Console.CursorTop;
Show();
}
@ -347,9 +345,9 @@ namespace OpenSim.Framework.Console
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
//
@ -368,19 +366,18 @@ namespace OpenSim.Framework.Console
public override string ReadLine(string p, bool isCommand, bool e)
{
h = 1;
cp = 0;
m_cursorXPosition = 0;
prompt = p;
echo = e;
int historyLine = history.Count;
m_echo = e;
int historyLine = m_history.Count;
SetCursorLeft(0); // Needed for mono
System.Console.Write(" "); // Needed for mono
lock (cmdline)
lock (m_commandLine)
{
y = System.Console.CursorTop;
cmdline.Remove(0, cmdline.Length);
m_cursorYPosition = System.Console.CursorTop;
m_commandLine.Remove(0, m_commandLine.Length);
}
while (true)
@ -388,92 +385,95 @@ namespace OpenSim.Framework.Console
Show();
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;
if (c == '?' && isCommand)
if (enteredChar == '?' && isCommand)
{
if (ContextHelp())
continue;
}
cmdline.Insert(cp, c);
cp++;
m_commandLine.Insert(m_cursorXPosition, enteredChar);
m_cursorXPosition++;
}
else
{
switch (key.Key)
{
case ConsoleKey.Backspace:
if (cp == 0)
if (m_cursorXPosition == 0)
break;
cmdline.Remove(cp-1, 1);
cp--;
m_commandLine.Remove(m_cursorXPosition-1, 1);
m_cursorXPosition--;
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;
case ConsoleKey.End:
cp = cmdline.Length;
m_cursorXPosition = m_commandLine.Length;
break;
case ConsoleKey.Home:
cp = 0;
m_cursorXPosition = 0;
break;
case ConsoleKey.UpArrow:
if (historyLine < 1)
break;
historyLine--;
LockOutput();
cmdline.Remove(0, cmdline.Length);
cmdline.Append(history[historyLine]);
cp = cmdline.Length;
m_commandLine.Remove(0, m_commandLine.Length);
m_commandLine.Append(m_history[historyLine]);
m_cursorXPosition = m_commandLine.Length;
UnlockOutput();
break;
case ConsoleKey.DownArrow:
if (historyLine >= history.Count)
if (historyLine >= m_history.Count)
break;
historyLine++;
LockOutput();
if (historyLine == history.Count)
if (historyLine == m_history.Count)
{
cmdline.Remove(0, cmdline.Length);
m_commandLine.Remove(0, m_commandLine.Length);
}
else
{
cmdline.Remove(0, cmdline.Length);
cmdline.Append(history[historyLine]);
m_commandLine.Remove(0, m_commandLine.Length);
m_commandLine.Append(m_history[historyLine]);
}
cp = cmdline.Length;
m_cursorXPosition = m_commandLine.Length;
UnlockOutput();
break;
case ConsoleKey.LeftArrow:
if (cp > 0)
cp--;
if (m_cursorXPosition > 0)
m_cursorXPosition--;
break;
case ConsoleKey.RightArrow:
if (cp < cmdline.Length)
cp++;
if (m_cursorXPosition < m_commandLine.Length)
m_cursorXPosition++;
break;
case ConsoleKey.Enter:
SetCursorLeft(0);
y = SetCursorTop(y);
m_cursorYPosition = SetCursorTop(m_cursorYPosition);
System.Console.WriteLine();
//Show();
lock (cmdline)
lock (m_commandLine)
{
y = -1;
m_cursorYPosition = -1;
}
string commandLine = cmdline.ToString();
string commandLine = m_commandLine.ToString();
if (isCommand)
{
@ -481,12 +481,12 @@ namespace OpenSim.Framework.Console
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(" "))
cmd[i] = "\"" + cmd[i] + "\"";
if (cmd[index].Contains(" "))
cmd[index] = "\"" + cmd[index] + "\"";
}
AddToHistory(String.Join(" ", cmd));
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 (echo && commandLine != "")
if (m_echo && commandLine != "")
AddToHistory(commandLine);
return commandLine;

View File

@ -935,7 +935,7 @@ namespace OpenSim.Framework
event ScriptReset OnScriptReset;
event GetScriptRunning OnGetScriptRunning;
event SetScriptRunning OnSetScriptRunning;
event Action<Vector3, bool> OnAutoPilotGo;
event Action<Vector3, bool, bool> OnAutoPilotGo;
event TerrainUnacked OnUnackedTerrain;
event ActivateGesture OnActivateGesture;

View File

@ -1372,11 +1372,30 @@ namespace OpenSim.Framework
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)
{
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)
{
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
@ -1395,11 +1414,30 @@ namespace OpenSim.Framework
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)
{
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)
{
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }

View File

@ -269,13 +269,15 @@ namespace OpenSim
m_console.Commands.AddCommand("region", false, "save oar",
//"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.",
// "-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
+ "--noassets stops assets being saved to the OAR." + Environment.NewLine
+ "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine
+ " <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." + Environment.NewLine
+ "--noassets stops assets being saved to the OAR.",
+ " If this is not given then the oar is saved to region.oar in the current directory.",
SaveOar);
m_console.Commands.AddCommand("region", false, "edit scale",

View File

@ -41,11 +41,15 @@ using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Statistics;
using OpenSim.Region.ClientStack;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Physics.Manager;
using OpenSim.Server.Base;
using OpenSim.Services.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Services.UserAccountService;
namespace OpenSim
{
@ -362,6 +366,9 @@ namespace OpenSim
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
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
@ -411,9 +418,69 @@ namespace OpenSim
scene.StartTimer();
scene.StartScripts();
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)
{
m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);

View File

@ -231,7 +231,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event ScriptReset OnScriptReset;
public event GetScriptRunning OnGetScriptRunning;
public event SetScriptRunning OnSetScriptRunning;
public event Action<Vector3, bool> OnAutoPilotGo;
public event Action<Vector3, bool, bool> OnAutoPilotGo;
public event TerrainUnacked OnUnackedTerrain;
public event ActivateGesture OnActivateGesture;
public event DeactivateGesture OnDeactivateGesture;
@ -11640,9 +11640,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
locy = Convert.ToSingle(args[1]) - (float)regionY;
locz = Convert.ToSingle(args[2]);
Action<Vector3, bool> handlerAutoPilotGo = OnAutoPilotGo;
Action<Vector3, bool, bool> handlerAutoPilotGo = OnAutoPilotGo;
if (handlerAutoPilotGo != null)
handlerAutoPilotGo(new Vector3(locx, locy, locz), false);
handlerAutoPilotGo(new Vector3(locx, locy, locz), false, false);
}
/// <summary>

View File

@ -41,14 +41,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
/// </summary>
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
private bool m_dumpAssetsToFile;
private Scene m_Scene;
public UUID UserID;
public Dictionary<UUID, AssetXferUploader> XferUploaders =
new Dictionary<UUID, AssetXferUploader>();
private UUID UserID;
private Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>();
// Methods
public AgentAssetTransactions(UUID agentID, Scene scene,
@ -59,36 +58,94 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
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)
{
lock (XferUploaders)
{
if (!XferUploaders.ContainsKey(transactionID))
{
AssetXferUploader uploader = new AssetXferUploader(m_Scene,
m_dumpAssetsToFile);
AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile);
// m_log.DebugFormat(
// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID);
lock (XferUploaders)
{
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;
}
public void HandleXfer(ulong xferID, uint packetID, byte[] data)
{
AssetXferUploader foundUploader = null;
lock (XferUploaders)
{
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)
{
uploader.HandleXferPacket(xferID, packetID, data);
foundUploader = uploader;
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,
@ -96,16 +153,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask)
{
if (XferUploaders.ContainsKey(transactionID))
AssetXferUploader uploader = null;
lock (XferUploaders)
{
XferUploaders[transactionID].RequestCreateInventoryItem(
if (XferUploaders.ContainsKey(transactionID))
uploader = XferUploaders[transactionID];
}
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>
/// Get an uploaded asset. If the data is successfully retrieved,
@ -113,20 +178,19 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
/// </summary>
/// <param name="transactionID"></param>
/// <returns>The asset if the upload has completed, null if it has not.</returns>
public AssetBase GetTransactionAsset(UUID transactionID)
private AssetBase GetTransactionAsset(UUID transactionID)
{
lock (XferUploaders)
{
if (XferUploaders.ContainsKey(transactionID))
{
AssetXferUploader uploader = XferUploaders[transactionID];
AssetBase asset = uploader.GetAssetData();
lock (XferUploaders)
{
XferUploaders.Remove(transactionID);
}
RemoveXferUploader(transactionID);
return asset;
}
}
return null;
}
@ -134,8 +198,16 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
SceneObjectPart part, UUID transactionID,
TaskInventoryItem item)
{
AssetXferUploader uploader = null;
lock (XferUploaders)
{
if (XferUploaders.ContainsKey(transactionID))
uploader = XferUploaders[transactionID];
}
if (uploader != null)
{
AssetBase asset = GetTransactionAsset(transactionID);
@ -161,28 +233,34 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
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,
UUID transactionID, InventoryItemBase item)
{
AssetXferUploader uploader = null;
lock (XferUploaders)
{
if (XferUploaders.ContainsKey(transactionID))
uploader = XferUploaders[transactionID];
}
if (uploader != null)
{
AssetBase asset = GetTransactionAsset(transactionID);
if (asset != null)
uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item);
}
else
{
asset.FullID = UUID.Random();
asset.Name = item.Name;
asset.Description = item.Description;
asset.Type = (sbyte)item.AssetType;
item.AssetID = asset.FullID;
m_Scene.AssetService.Store(asset);
IInventoryService invService = m_Scene.InventoryService;
invService.UpdateItem(item);
}
m_log.ErrorFormat(
"[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}",
transactionID, item.Name, remoteClient.Name);
}
}
}

View File

@ -172,11 +172,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
/// <summary>
/// Update an inventory item with data that has been received through a
/// transaction.
///
/// </summary>
/// <remarks>
/// This is called when clothing or body parts are updated (for
/// instance, with new textures or colours). It may also be called in
/// other situations.
/// </summary>
/// </remarks>
/// <param name="remoteClient"></param>
/// <param name="transactionID"></param>
/// <param name="item"></param>
@ -184,14 +185,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
UUID transactionID, InventoryItemBase item)
{
// m_log.DebugFormat(
// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
// "[ASSET TRANSACTION MODULE]: Called HandleItemUpdateFromTransaction with item {0}",
// item.Name);
AgentAssetTransactions transactions =
GetUserTransactions(remoteClient.AgentId);
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
transactions.RequestUpdateInventoryItem(remoteClient,
transactionID, item);
transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
}
/// <summary>
@ -255,11 +254,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
}
}
AgentAssetTransactions transactions =
GetUserTransactions(remoteClient.AgentId);
AssetXferUploader uploader =
transactions.RequestXferUploader(transaction);
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID);
if (uploader != null)
{
@ -279,9 +275,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
public void HandleXfer(IClientAPI remoteClient, ulong xferID,
uint packetID, byte[] data)
{
//m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!");
AgentAssetTransactions transactions =
GetUserTransactions(remoteClient.AgentId);
// m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data length " + data.Length);
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
transactions.HandleXfer(xferID, packetID, data);
}

View File

@ -40,11 +40,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
{
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 UUID InventFolder = UUID.Zero;
private sbyte invType = 0;
private bool m_createItem = false;
private uint m_createItemCallback = 0;
private bool m_updateItem = false;
private InventoryItemBase m_updateItemData;
private string m_description = String.Empty;
private bool m_dumpAssetToFile;
private bool m_finished = false;
@ -58,9 +68,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
public ulong XferID;
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_asset = new AssetBase() { FullID = assetID };
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>
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 (m_asset.Data.Length > 1)
@ -107,16 +123,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
/// <param name="xferID"></param>
/// <param name="packetID"></param>
/// <param name="data"></param>
/// <returns>True if the transfer is complete, false otherwise</returns>
public bool Initialise(IClientAPI remoteClient, UUID assetID,
public void Initialise(IClientAPI remoteClient, UUID assetID,
UUID transaction, sbyte type, byte[] data, bool storeLocal,
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;
m_asset = new AssetBase(assetID, "blank", type,
remoteClient.AgentId.ToString());
m_asset.Data = data;
m_asset.Name = "blank";
m_asset.Description = "empty";
m_asset.Type = type;
m_asset.CreatorID = remoteClient.AgentId.ToString();
m_asset.Data = data;
m_asset.Local = storeLocal;
m_asset.Temporary = tempFile;
@ -126,21 +146,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
if (m_asset.Data.Length > 2)
{
SendCompleteMessage();
return true;
}
else
{
RequestStartXfer();
}
return false;
}
protected void RequestStartXfer()
{
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()
@ -148,18 +169,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
m_asset.FullID);
// We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
// message from other client UDP.
lock (this)
{
m_finished = true;
if (m_createItem)
{
DoCreateItem(m_createItemCallback);
}
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(
"[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}",
"[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
m_asset.FullID, TransactionID);
if (m_dumpAssetToFile)
@ -205,6 +240,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
m_asset.Description = description;
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);
@ -216,6 +254,51 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
}
}
}
}
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)
{
StoreAssetForItemUpdate(item);
}
else
{
// m_log.DebugFormat(
// "[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)
{

View File

@ -143,20 +143,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
public void SaveChangedAttachments(IScenePresence sp)
{
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
foreach (SceneObjectGroup grp in sp.GetAttachments())
{
if (grp.HasGroupChanged) // Resizer scripts?
{
// if (grp.HasGroupChanged) // Resizer scripts?
// {
grp.IsAttachment = false;
grp.AbsolutePosition = grp.RootPart.AttachedPos;
UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID);
UpdateKnownItem(sp.ControllingClient, grp);
grp.IsAttachment = true;
}
// }
}
}
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())
{
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);
// Save avatar attachment information
m_log.Info(
m_log.Debug(
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
+ ", AttachmentPoint: " + AttachmentPt);
@ -240,6 +246,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
{
lock (sp.AttachmentsSyncLock)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
@ -313,6 +321,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
}
return true;
}
@ -322,14 +331,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects)
{
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
if (sp == null)
{
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(remoteClient, obj.ItemID, obj.AttachmentPt);
RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt);
}
}
}
public ISceneEntity RezSingleAttachmentFromInventory(
IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}",
@ -345,10 +368,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
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
// be removed when that functionality is implemented in opensim
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);
if (att == null)
@ -362,6 +420,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null)
{
lock (sp.AttachmentsSyncLock)
{
SceneObjectGroup objatt;
@ -413,6 +473,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// 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);
return objatt;
}
else
{
@ -420,8 +482,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
"[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
itemID, sp.Name, attachmentPt);
}
return objatt;
}
}
return null;
@ -439,7 +500,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
// m_log.DebugFormat(
// "[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)
{
@ -462,6 +523,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
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);
if (group != null)
{
@ -473,6 +537,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
ScenePresence presence;
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
lock (presence.AttachmentsSyncLock)
{
// Save avatar attachment information
m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
@ -484,12 +550,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
DetachSingleAttachmentToInv(itemID, presence);
}
}
}
public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
// remoteClient.Name, sceneObjectID);
// remoteClient.Name, soLocalId);
SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
@ -507,6 +574,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ScenePresence presence;
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
lock (presence.AttachmentsSyncLock)
{
if (!m_scene.Permissions.CanRezObject(
so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
@ -527,6 +596,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
}
}
/// <summary>
/// Detach the given scene object to the ground.
@ -559,6 +629,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
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....
return;
@ -567,6 +639,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
EntityBase[] detachEntities = m_scene.GetEntities();
SceneObjectGroup group;
lock (sp.AttachmentsSyncLock)
{
foreach (EntityBase entity in detachEntities)
{
if (entity is SceneObjectGroup)
@ -579,22 +653,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// Prepare sog for storage
group.AttachedAvatar = UUID.Zero;
group.ForEachPart(
delegate(SceneObjectPart part)
{
// 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);
group.IsAttachment = false;
group.AbsolutePosition = group.RootPart.AttachedPos;
UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID);
UpdateKnownItem(sp.ControllingClient, group);
m_scene.DeleteSceneObject(group, false);
return;
@ -602,6 +665,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
}
}
}
public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
{
@ -628,28 +692,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// </remarks>
/// <param name="remoteClient"></param>
/// <param name="grp"></param>
/// <param name="itemID"></param>
/// <param name="agentID"></param>
public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp)
{
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(
"[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
grp.UUID, grp.AttachmentPoint);
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);
if (item != null)
@ -675,6 +728,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
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>
@ -692,7 +751,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
private void AttachToAgent(
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.DetachFromBackup();
@ -745,7 +805,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// <returns>The user inventory item created that holds the attachment.</returns>
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
(((grp.AbsolutePosition.X > (int)Constants.RegionSize)

View File

@ -220,6 +220,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
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]
public void TestRezAttachmentsOnAvatarEntrance()
{

View File

@ -211,8 +211,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// Process the visual params, this may change height as well
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);
if (sp.Appearance.AvatarHeight > 0)
if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
sp.SetHeight(sp.Appearance.AvatarHeight);
}
@ -416,6 +425,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// 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);
}
@ -467,7 +483,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
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++);
}
@ -502,9 +518,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
avatAppearance.GetAssetsFrom(sp.Appearance);
// This could take awhile since it needs to pull inventory
SetAppearanceAssets(sp.UUID, ref avatAppearance);
lock (m_setAppearanceLock)
{
// 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;
}
private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
{
IInventoryService invService = m_scene.InventoryService;

View File

@ -24,6 +24,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
@ -145,14 +146,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
scene.Entities[toAgentID] is ScenePresence)
{
// 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);
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
if (!user.IsChildAgent)
{
// Local message
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
user.ControllingClient.SendInstantMessage(im);
// Message sent
@ -166,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
foreach (Scene scene in m_Scenes)
{
// 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) &&
scene.Entities[toAgentID] is ScenePresence)
@ -174,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
// Local message
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);
// 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?
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
string url = string.Empty;

View File

@ -154,14 +154,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
{
UUID sessionID = new UUID(im.imSessionID);
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
// IMs of this type
if (m_TransferModule != null)
m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
}
}
@ -177,13 +180,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
UUID sessionID = UUID.Random();
GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
client.FirstName+" "+client.LastName, targetid,
(byte)InstantMessageDialog.RequestTeleport, false,
message, UUID.Random(), false, presence.AbsolutePosition,
message, sessionID, false, presence.AbsolutePosition,
new Byte[0]);
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)
{
m_TransferModule.SendInstantMessage(m,

View File

@ -60,7 +60,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
set { m_MaxTransferDistance = value; }
}
protected bool m_Enabled = false;
protected Scene m_aScene;
protected List<Scene> m_Scenes = new List<Scene>();
@ -68,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
#region ISharedRegionModule
public Type ReplaceableInterface
@ -329,6 +327,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (sp.ParentID != (uint)0)
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())
// {
// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
@ -939,7 +942,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// This Closes child agents on neighbouring regions
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </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));
@ -949,7 +954,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
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);

View File

@ -363,9 +363,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
lock (m_UserCache)
m_UserCache[user.Id] = user;
m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
user.Id, user.FirstName, user.LastName, user.HomeURL);
// m_log.DebugFormat(
// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
// user.Id, user.FirstName, user.LastName, user.HomeURL);
}
//public void AddUser(UUID uuid, string userData)

View File

@ -185,15 +185,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID);
Util.FireAndForget(delegate
{
if (UserManager != null)
{
// Protect ourselves against the caller subsequently modifying the items list
foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
Util.FireAndForget(delegate
{
foreach (InventoryItemBase item in items)
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
}
});
}
return invCol;
}

View File

@ -193,15 +193,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
Util.FireAndForget(delegate
{
if (UserManager != null)
{
// Protect ourselves against the caller subsequently modifying the items list
foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
Util.FireAndForget(delegate
{
foreach (InventoryItemBase item in items)
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
}
});
}
return invCol;
}

View File

@ -45,7 +45,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
LogManager.GetLogger(
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 bool m_Enabled = false;
@ -86,9 +91,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
}
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(
"[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)
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)
@ -147,7 +154,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
if (inCache)
return account;
account = m_UserService.GetUserAccount(scopeID, userID);
account = UserAccountService.GetUserAccount(scopeID, userID);
m_Cache.Cache(userID, account);
return account;
@ -160,7 +167,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
if (inCache)
return account;
account = m_UserService.GetUserAccount(scopeID, firstName, lastName);
account = UserAccountService.GetUserAccount(scopeID, firstName, lastName);
if (account != null)
m_Cache.Cache(account.PrincipalID, account);
@ -169,22 +176,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
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)
{
return m_UserService.GetUserAccounts(scopeID, query);
return UserAccountService.GetUserAccounts(scopeID, query);
}
// Update all updatable fields
//
public bool StoreUserAccount(UserAccount data)
{
return m_UserService.StoreUserAccount(data);
return UserAccountService.StoreUserAccount(data);
}
#endregion
}
}

View File

@ -284,8 +284,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
// And zap any troublesome sit target information
part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
part.SitTargetPosition = new Vector3(0, 0, 0);
// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
// part.SitTargetPosition = new Vector3(0, 0, 0);
// Fix ownership/creator of inventory items
// Not doing so results in inventory items

View File

@ -128,6 +128,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
EntityBase[] entities = m_scene.GetEntities();
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.
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
// end up having to do this
@ -138,7 +144,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
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);
}
}
}
}
@ -160,6 +176,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
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
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>
/// Create the control file for the most up to date archive
/// </summary>

View File

@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
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);

View File

@ -318,6 +318,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
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);
// 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");
Assert.That(
object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition));
TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");

View File

@ -968,10 +968,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3;
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 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 4 {0} for region {1}", args.terrainDetail3, 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 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);
remoteClient.SendRegionHandshake(Scene.RegionInfo,args);
}

View File

@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
part.ParentGroup.HasGroupChanged = true;
part.GetProperties(client);
part.SendPropertiesToClient(client);
}
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;
group.HasGroupChanged = true;
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
part.TriggerScriptChangedEvent(Changed.OWNER);
group.ResumeScripts();
part.ScheduleFullUpdate();

View File

@ -39,7 +39,7 @@ using OpenSim.Services.Interfaces;
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);
@ -150,6 +150,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
else
m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
scene.RegisterModuleInterface<IPermissionsModule>(this);
//Register functions with Scene External Checks!
m_scene.Permissions.OnBypassPermissions += BypassPermissions;
m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions;
@ -574,47 +576,19 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (objectOwner != UUID.Zero)
objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner;
if (m_bypassPermissions)
return objectOwnerMask;
PermissionClass permissionClass = GetPermissionClass(user, task);
// Object owners should be able to edit their own content
if (user == objectOwner)
return objectOwnerMask;
if (IsFriendWithPerms(user, objectOwner))
switch (permissionClass)
{
case PermissionClass.Owner:
return objectOwnerMask;
}
// 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;
}
}
// Group permissions
if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
case PermissionClass.Group:
return objectGroupMask | objectEveryoneMask;
case PermissionClass.Everyone:
default:
return objectEveryoneMask;
}
}
private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask)
{
@ -644,6 +618,47 @@ namespace OpenSim.Region.CoreModules.World.Permissions
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>
/// General permissions checks for any operation involving an object. These supplement more specific checks
/// implemented by callers.

View File

@ -222,7 +222,7 @@ namespace OpenSim.Region.Examples.SimpleModule
public event ScriptReset OnScriptReset;
public event GetScriptRunning OnGetScriptRunning;
public event SetScriptRunning OnSetScriptRunning;
public event Action<Vector3, bool> OnAutoPilotGo;
public event Action<Vector3, bool, bool> OnAutoPilotGo;
public event TerrainUnacked OnUnackedTerrain;

View File

@ -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>
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>
/// Rez multiple attachments from a user's inventory
/// </summary>
@ -129,14 +138,5 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="sog"></param>
/// <param name="pos"></param>
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);
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -49,6 +49,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns></returns>
EstateSettings LoadEstateSettings(int estateID);
/// <summary>
/// Create a new estate.
/// </summary>
/// <returns>
/// A <see cref="EstateSettings"/>
/// </returns>
EstateSettings CreateNewEstate();
/// <summary>
/// Load/Get all estate settings.
/// </summary>

View File

@ -54,6 +54,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns></returns>
EstateSettings LoadEstateSettings(int estateID);
/// <summary>
/// Create a new estate.
/// </summary>
/// <returns>
/// A <see cref="EstateSettings"/>
/// </returns>
EstateSettings CreateNewEstate();
/// <summary>
/// Load/Get all estate settings.
/// </summary>

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -25,36 +25,30 @@
* 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,
Start = 1,
End = 2
}
/// <value>
/// Which set of permissions a user has.
/// </value>
public enum PermissionClass
{
Owner,
Group,
Everyone
};
public struct sCollisionData
public interface IPermissionsModule
{
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
/// <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);
}
}

View File

@ -60,6 +60,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// </remarks>
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>
/// The scene objects attached to this avatar.
/// </summary>

View File

@ -52,5 +52,10 @@ namespace OpenSim.Region.Framework.Interfaces
ArrayList GetScriptErrors(UUID itemID);
void SaveAllState();
/// <summary>
/// Starts the processing threads.
/// </summary>
void StartProcessing();
}
}

View File

@ -26,8 +26,10 @@
*/
using System;
using System.Reflection;
using System.Runtime.Serialization;
using System.Security.Permissions;
using log4net;
using OpenSim.Framework;
using OpenMetaverse;
@ -35,6 +37,8 @@ namespace OpenSim.Region.Framework.Scenes
{
public abstract class EntityBase : ISceneEntity
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The scene to which this entity belongs
/// </summary>
@ -71,12 +75,15 @@ namespace OpenSim.Region.Framework.Scenes
protected Vector3 m_pos;
/// <summary>
///
/// Absolute position of this entity in a scene.
/// </summary>
public virtual Vector3 AbsolutePosition
{
get { return m_pos; }
set { m_pos = value; }
set
{
m_pos = value;
}
}
protected Vector3 m_velocity;

View File

@ -57,11 +57,11 @@ namespace OpenSim.Region.Framework.Scenes
protected AsyncInventorySender m_asyncInventorySender;
/// <summary>
/// Start all the scripts in the scene which should be started.
/// Creates all the scripts in the scene which should be started.
/// </summary>
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();
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)
{
IMoneyModule money = RequestModuleInterface<IMoneyModule>();
@ -254,7 +274,7 @@ namespace OpenSim.Region.Framework.Scenes
if (group.UpdateInventoryItem(item))
remoteClient.SendAgentAlertMessage("Script saved", false);
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
ArrayList errors = new ArrayList();
@ -314,6 +334,10 @@ namespace OpenSim.Region.Framework.Scenes
public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
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
// inventory. Rut-Roh. Whatever. Make this secure. Yeah.
//
@ -365,8 +389,7 @@ namespace OpenSim.Region.Framework.Scenes
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
if (agentTransactions != null)
{
agentTransactions.HandleItemUpdateFromTransaction(
remoteClient, transactionID, item);
agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
}
}
}
@ -979,7 +1002,7 @@ namespace OpenSim.Region.Framework.Scenes
}
group.RemoveInventoryItem(localID, itemID);
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
}
private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
@ -1252,7 +1275,7 @@ namespace OpenSim.Region.Framework.Scenes
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(
"[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
item.Name, primLocalID, remoteClient.Name);
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
if (!Permissions.BypassPermissions())
{
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
@ -1502,7 +1525,7 @@ namespace OpenSim.Region.Framework.Scenes
if (part.Inventory.UpdateInventoryItem(itemInfo))
{
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
}
}
}
@ -1554,7 +1577,7 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.InfoFormat("[PRIMINVENTORY]: " +
// "Rezzed script {0} into prim local ID {1} for user {2}",
// item.inventoryName, localID, remoteClient.Name);
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
part.ParentGroup.ResumeScripts();
}
else
@ -1612,7 +1635,7 @@ namespace OpenSim.Region.Framework.Scenes
taskItem.AssetID = asset.FullID;
part.Inventory.AddInventoryItem(taskItem, false);
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
part.ParentGroup.ResumeScripts();
@ -1726,7 +1749,7 @@ namespace OpenSim.Region.Framework.Scenes
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);
if (part == null)
continue;
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
}
}

View File

@ -144,7 +144,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (((SceneObjectGroup) ent).LocalId == primLocalID)
{
((SceneObjectGroup) ent).GetProperties(remoteClient);
((SceneObjectGroup) ent).SendPropertiesToClient(remoteClient);
((SceneObjectGroup) ent).IsSelected = true;
// 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)
@ -167,7 +167,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (part.LocalId == primLocalID)
{
part.GetProperties(remoteClient);
part.SendPropertiesToClient(remoteClient);
foundPrim = true;
break;
}

View File

@ -656,7 +656,7 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.OnLandObjectRemoved +=
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.
// 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)
m_eventManager.OnPermissionError += dm.SendAlertToUser;
m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
}
public override string GetSimulatorVersion()
@ -1170,87 +1172,6 @@ namespace OpenSim.Region.Framework.Scenes
m_dialogModule = RequestModuleInterface<IDialogModule>();
m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
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
@ -1579,7 +1500,9 @@ namespace OpenSim.Region.Framework.Scenes
msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
msg.Position = Vector3.Zero;
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)
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
@ -2459,14 +2382,16 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>False</returns>
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);
if (sp != null && AttachmentsModule != null)
{
uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
}
// Commented out since this is as yet unused and is arguably not the appropriate place to do this, as
// attachments are being rezzed elsewhere in AddNewClient()
// ScenePresence sp = GetScenePresence(userID);
// if (sp != null && AttachmentsModule != null)
// {
// uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
// AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
// }
return false;
}
@ -5215,5 +5140,70 @@ namespace OpenSim.Region.Framework.Scenes
reason = String.Empty;
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);
}
}
}
}
}

View File

@ -74,7 +74,6 @@ namespace OpenSim.Region.Framework.Scenes
protected internal EntityManager Entities = new EntityManager();
protected RegionInfo m_regInfo;
protected Scene m_parentScene;
protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
protected int m_numRootAgents = 0;
@ -108,10 +107,9 @@ namespace OpenSim.Region.Framework.Scenes
#endregion
protected internal SceneGraph(Scene parent, RegionInfo regInfo)
protected internal SceneGraph(Scene parent)
{
m_parentScene = parent;
m_regInfo = regInfo;
}
public PhysicsScene PhysicsScene
@ -122,7 +120,6 @@ namespace OpenSim.Region.Framework.Scenes
// If we're not doing the initial set
// Then we've got to remove the previous
// event handler
if (_PhyScene != null)
_PhyScene.OnPhysicsCrash -= physicsBasedCrash;
@ -372,12 +369,12 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
SceneObjectPart[] children = sceneObject.Parts;
SceneObjectPart[] parts = sceneObject.Parts;
// Clamp child prim sizes and add child prims to the m_numPrim count
if (m_parentScene.m_clampPrimSize)
{
foreach (SceneObjectPart part in children)
foreach (SceneObjectPart part in parts)
{
Vector3 scale = part.Shape.Scale;
@ -391,7 +388,7 @@ namespace OpenSim.Region.Framework.Scenes
part.Shape.Scale = scale;
}
}
m_numPrim += children.Length;
m_numPrim += parts.Length;
sceneObject.AttachToScene(m_parentScene);
@ -411,15 +408,17 @@ namespace OpenSim.Region.Framework.Scenes
lock (SceneObjectGroupsByFullPartID)
{
SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject;
foreach (SceneObjectPart part in children)
foreach (SceneObjectPart part in parts)
SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
}
lock (SceneObjectGroupsByLocalPartID)
{
SceneObjectGroupsByLocalPartID[sceneObject.LocalId] = sceneObject;
foreach (SceneObjectPart part in children)
// m_log.DebugFormat(
// "[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;
}
@ -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>
public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
{
// m_log.DebugFormat(
// "[SCENE GRAPH]: Deleting scene object with uuid {0}, resultOfObjectLinked = {1}",
// uuid, resultOfObjectLinked);
EntityBase entity;
if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup)))
return false;
@ -460,7 +463,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart[] parts = grp.Parts;
for (int i = 0; i < parts.Length; i++)
SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
SceneObjectGroupsByFullPartID.Remove(grp.RootPart.UUID);
}
lock (SceneObjectGroupsByLocalPartID)
@ -468,7 +470,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart[] parts = grp.Parts;
for (int i = 0; i < parts.Length; i++)
SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
SceneObjectGroupsByLocalPartID.Remove(grp.RootPart.LocalId);
}
return Entities.Remove(uuid);
@ -589,7 +590,7 @@ namespace OpenSim.Region.Framework.Scenes
ScenePresence newAvatar = null;
// 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);
@ -881,7 +882,8 @@ namespace OpenSim.Region.Framework.Scenes
if (Entities.TryGetValue(localID, out entity))
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;
lock (SceneObjectGroupsByLocalPartID)
SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
@ -889,9 +891,25 @@ namespace OpenSim.Region.Framework.Scenes
if (sog != null)
{
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;
}
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();
foreach (EntityBase ent in entityList)

View File

@ -389,5 +389,18 @@ namespace OpenSim.Region.Framework.Scenes
for (int i = 0; i < parts.Length; i++)
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;
}
}
}

View File

@ -1599,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes
ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
if (avatar != null)
{
avatar.MoveToTarget(target, false);
avatar.MoveToTarget(target, false, false);
}
}
else
@ -1728,8 +1728,6 @@ namespace OpenSim.Region.Framework.Scenes
#endregion
#region Scheduling
public override void Update()
{
// Check that the group was not deleted before the scheduled update
@ -1880,7 +1878,14 @@ namespace OpenSim.Region.Framework.Scenes
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
@ -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>
/// Set the name of a prim
/// </summary>

View File

@ -1305,8 +1305,6 @@ namespace OpenSim.Region.Framework.Scenes
#endregion Public Properties with only Get
#region Private Methods
private uint ApplyMask(uint val, bool set, uint mask)
{
if (set)
@ -1327,14 +1325,27 @@ namespace OpenSim.Region.Framework.Scenes
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)
{
// Ugly reference :(
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
public void ResetExpire()
@ -1705,20 +1714,6 @@ namespace OpenSim.Region.Framework.Scenes
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>
/// Do a physics property update for a NINJA joint.
/// </summary>
@ -2030,11 +2025,6 @@ namespace OpenSim.Region.Framework.Scenes
return Vector3.Zero;
}
public void GetProperties(IClientAPI client)
{
client.SendObjectPropertiesReply(this);
}
/// <summary>
/// Method for a prim to get it's world position from the group.
/// </summary>
@ -3453,7 +3443,7 @@ namespace OpenSim.Region.Framework.Scenes
{
_groupID = groupID;
if (client != null)
GetProperties(client);
SendPropertiesToClient(client);
m_updateFlag = 2;
}
@ -4273,10 +4263,10 @@ namespace OpenSim.Region.Framework.Scenes
break;
}
SendFullUpdateToAllClients();
SendObjectPropertiesToClient(AgentID);
SendRootPartPropertiesToClient(AgentID);
}
}

View File

@ -784,6 +784,10 @@ namespace OpenSim.Region.Framework.Scenes
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 ||
m_inventoryFileNameSerial < m_inventorySerial)
{
@ -797,6 +801,10 @@ namespace OpenSim.Region.Framework.Scenes
{
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;
uint everyoneMask = 0;
uint baseMask = item.BasePermissions;
@ -856,29 +864,44 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="xferManager"></param>
public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
{
CreateInventoryFile();
if (m_inventorySerial == 0) // No inventory
lock (m_items)
{
// Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing
// 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));
}
}
/// <summary>
/// Process inventory backup
@ -1035,10 +1058,15 @@ namespace OpenSim.Region.Framework.Scenes
item.BasePermissions = perms;
}
}
m_inventorySerial++;
HasInventoryChanged = true;
}
/// <summary>
/// Returns true if this part inventory contains any scripts. False otherwise.
/// </summary>
/// <returns></returns>
public bool ContainsScripts()
{
lock (m_items)

View File

@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes
{
// ~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);
@ -120,6 +120,8 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks>
protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
public Object AttachmentsSyncLock { get; private set; }
private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
private ScriptControlled IgnoredControls = 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_bodyRotPrevious = Quaternion.Identity;
private const int LAND_VELOCITYMAG_MAX = 12;
public bool IsRestrictedToRegion;
@ -186,7 +186,6 @@ namespace OpenSim.Region.Framework.Scenes
private float m_health = 100f;
protected RegionInfo m_regionInfo;
protected ulong crossingFromRegion;
private readonly Vector3[] Dir_Vectors = new Vector3[9];
@ -221,6 +220,11 @@ namespace OpenSim.Region.Framework.Scenes
public bool MovingToTarget { 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 int m_movementUpdateCount;
@ -466,7 +470,13 @@ namespace OpenSim.Region.Framework.Scenes
{
PhysicsActor actor = m_physicsActor;
if (actor != null)
{
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
{
// Obtain the correct position of a seated avatar.
@ -516,13 +526,20 @@ namespace OpenSim.Region.Framework.Scenes
m_pos = value;
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
{
get { return m_pos; }
set { m_pos = value; }
}
/// <summary>
@ -534,8 +551,14 @@ namespace OpenSim.Region.Framework.Scenes
{
PhysicsActor actor = m_physicsActor;
if (actor != null)
{
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;
}
set
@ -555,19 +578,21 @@ namespace OpenSim.Region.Framework.Scenes
}
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
{
get { return m_bodyRot; }
set { m_bodyRot = value; }
}
public Quaternion PreviousRotation
set
{
get { return m_bodyRotPrevious; }
set { m_bodyRotPrevious = value; }
m_bodyRot = value;
// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
}
}
/// <summary>
@ -707,21 +732,22 @@ namespace OpenSim.Region.Framework.Scenes
#region Constructor(s)
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_sceneViewer = new SceneViewer(this);
m_animator = new ScenePresenceAnimator(this);
PresenceType = type;
m_DrawDistance = world.DefaultDrawDistance;
m_rootRegionHandle = reginfo.RegionHandle;
m_rootRegionHandle = world.RegionInfo.RegionHandle;
m_controllingClient = client;
m_firstname = m_controllingClient.FirstName;
m_lastname = m_controllingClient.LastName;
m_name = String.Format("{0} {1}", m_firstname, m_lastname);
m_scene = world;
m_uuid = client.AgentId;
m_regionInfo = reginfo;
m_localId = m_scene.AllocateLocalId();
UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
@ -1150,9 +1176,9 @@ namespace OpenSim.Region.Framework.Scenes
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();
// Create child agents in neighbouring regions
@ -1217,7 +1243,9 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
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)
//{
@ -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
/// from start to finish.
/// </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(
"[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
// 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)
pos.Z = terrainHeight;
@ -1697,9 +1728,25 @@ namespace OpenSim.Region.Framework.Scenes
else if (pos.Z > terrainHeight)
PhysicsActor.Flying = true;
LandAtTarget = landAtTarget;
MovingToTarget = true;
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();
HandleMoveToTargetUpdate(ref agent_control_v3);
AddNewMovement(agent_control_v3);
@ -2389,7 +2436,7 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 pos = m_pos;
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(
this,
@ -2476,6 +2523,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
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
// the inventory arrives
// m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
@ -2520,6 +2568,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
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"
if (IsChildAgent)
{
@ -2573,7 +2622,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="avatar"></param>
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);
if (Animator != null)
@ -2586,6 +2635,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
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"
if (IsChildAgent)
{
@ -2615,6 +2665,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void SendOtherAgentsAppearanceToMe()
{
//m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} ({1})", Name, UUID);
m_perfMonMS = Util.EnvironmentTickCount();
int count = 0;
@ -2873,8 +2924,8 @@ namespace OpenSim.Region.Framework.Scenes
/// </returns>
protected int HaveNeighbor(Cardinals car, ref int[] fix)
{
uint neighbourx = m_regionInfo.RegionLocX;
uint neighboury = m_regionInfo.RegionLocY;
uint neighbourx = m_scene.RegionInfo.RegionLocX;
uint neighboury = m_scene.RegionInfo.RegionLocY;
int dir = (int)car;
@ -2894,8 +2945,8 @@ namespace OpenSim.Region.Framework.Scenes
if (neighbourRegion == null)
{
fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx);
fix[1] = (int)(m_regionInfo.RegionLocY - neighboury);
fix[0] = (int)(m_scene.RegionInfo.RegionLocX - neighbourx);
fix[1] = (int)(m_scene.RegionInfo.RegionLocY - neighboury);
return dir * (-1);
}
else
@ -3141,12 +3192,15 @@ namespace OpenSim.Region.Framework.Scenes
catch { }
// Attachment objects
if (m_attachments != null && m_attachments.Count > 0)
lock (m_attachments)
{
if (m_attachments.Count > 0)
{
cAgent.AttachmentObjects = new List<ISceneObject>();
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
@ -3164,6 +3218,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
}
public void CopyFrom(AgentData cAgent)
{
@ -3277,6 +3332,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
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)
m_appearance.SetHeight();
@ -3398,6 +3457,7 @@ namespace OpenSim.Region.Framework.Scenes
public void Close()
{
if (!IsChildAgent)
m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
lock (m_knownChildRegions)
@ -3501,8 +3561,10 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// This is currently just being done for information.
/// </summary>
public void ValidateAttachments()
public bool ValidateAttachments()
{
bool validated = true;
lock (m_attachments)
{
// Validate
@ -3512,15 +3574,21 @@ namespace OpenSim.Region.Framework.Scenes
{
m_log.WarnFormat(
"[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name);
validated = false;
}
else if (gobj.IsDeleted)
{
m_log.WarnFormat(
"[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing",
gobj.Name, gobj.UUID, Name);
validated = false;
}
}
}
return validated;
}
/// <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)
{
if (PhysicsActor != null)
@ -3602,6 +3647,7 @@ namespace OpenSim.Region.Framework.Scenes
obj.ignoreControls = (ScriptControlled)controls;
obj.eventControls = (ScriptControlled)controls;
}
if (pass_on == 1 && accept == 1)
{
IgnoredControls = ScriptControlled.CONTROL_ZERO;
@ -3622,6 +3668,7 @@ namespace OpenSim.Region.Framework.Scenes
scriptedcontrols[Script_item_UUID] = obj;
}
}
ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
}

View File

@ -52,22 +52,25 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestHelpers.InMethod();
Scene scene = SceneHelpers.SetupScene();
int partsToTestCount = 3;
string objName = "obj1";
UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
SceneObjectGroup so
= SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
SceneObjectPart[] parts = so.Parts;
SceneObjectPart part
= new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
{ Name = objName, UUID = objUuid };
Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True);
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid);
Assert.That(scene.AddNewSceneObject(so, false), Is.True);
SceneObjectGroup retrievedSo = scene.GetSceneObjectGroup(so.UUID);
SceneObjectPart[] retrievedParts = retrievedSo.Parts;
//m_log.Debug("retrievedPart : {0}", retrievedPart);
// 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(retrievedPart.UUID, Is.EqualTo(objUuid));
Assert.That(retrievedSo.PrimCount, Is.EqualTo(partsToTestCount));
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]
@ -104,6 +107,39 @@ namespace OpenSim.Region.Framework.Scenes.Tests
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>
/// Test deleting an object from a scene.
/// </summary>

View File

@ -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));
}
}
}

View File

@ -43,11 +43,12 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// Gather uuids for a given entity.
/// </summary>
///
/// <remarks>
/// 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
/// 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).
/// </remarks>
public class UuidGatherer
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -76,11 +77,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// Gather all the asset uuids associated with the asset referenced by a given uuid
/// </summary>
///
/// <remarks>
/// 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
/// within this object).
///
/// </remarks>
/// <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="assetUuids">The assets gathered</param>
@ -123,11 +124,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// Gather all the asset uuids associated with a given object.
/// </summary>
///
/// <remarks>
/// 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
/// within this object).
///
/// </remarks>
/// <param name="sceneObject">The scene object for which to gather assets</param>
/// <param name="assetUuids">The assets gathered</param>
public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids)

View File

@ -806,7 +806,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public event ScriptReset OnScriptReset;
public event GetScriptRunning OnGetScriptRunning;
public event SetScriptRunning OnSetScriptRunning;
public event Action<Vector3, bool> OnAutoPilotGo;
public event Action<Vector3, bool, bool> OnAutoPilotGo;
public event TerrainUnacked OnUnackedTerrain;
public event ActivateGesture OnActivateGesture;
public event DeactivateGesture OnDeactivateGesture;

View File

@ -37,11 +37,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
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_lastname;
private readonly Vector3 m_startPos;
@ -333,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public event ScriptReset OnScriptReset;
public event GetScriptRunning OnGetScriptRunning;
public event SetScriptRunning OnSetScriptRunning;
public event Action<Vector3, bool> OnAutoPilotGo;
public event Action<Vector3, bool, bool> OnAutoPilotGo;
public event TerrainUnacked OnUnackedTerrain;

View File

@ -53,78 +53,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (config != null && config.GetBoolean("Enabled", false))
{
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)
{
// FIXME: This implementation could not just use the ScenePresence.PresenceType (and callers could inspect
// that directly).
ScenePresence sp = scene.GetScenePresence(agentId);
if (sp == null || sp.IsChildAgent)
return false;
@ -218,8 +153,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
"[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
m_avatars[agentID].LandAtTarget = landAtTarget;
sp.MoveToTarget(pos, noFly);
sp.MoveToTarget(pos, noFly, landAtTarget);
return true;
}

View File

@ -182,18 +182,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
scene.Update();
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);
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();
// We should really check the exact figure.
Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z));
Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z));
Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
for (int i = 0; i < 10; i++)
scene.Update();
@ -208,6 +211,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
targetPos = startPos + new Vector3(10, 0, 0);
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();
// We should really check the exact figure.

View File

@ -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.*")]

View File

@ -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

View File

@ -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);
}
}
}
}

View File

@ -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

View File

@ -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.");
}
}
}

View File

@ -465,9 +465,11 @@ namespace OpenSim.Region.Physics.OdePlugin
Vector3 SetSize = value;
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);
}
@ -785,6 +787,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{
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,6 +1329,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
{
// m_log.DebugFormat("[PHYSICS]: Changing capsule size");
m_pidControllerActive = true;
// no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
@ -1336,7 +1341,10 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomDestroy(Shell);
AvatarGeomAndBodyCreation(_position.X, _position.Y,
_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.actor_name_map[Shell] = (PhysicsActor)this;
@ -1361,7 +1369,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_position.Z = m_taintPosition.Z;
}
}
}
internal void AddCollisionFrameTime(int p)

View File

@ -1526,6 +1526,7 @@ Console.WriteLine("changeadd 1");
{
if (Body == IntPtr.Zero)
enableBody();
//Prim auto disable after 20 frames,
//if you move it, re-enable the prim manually.
if (_parent != null)
@ -1536,6 +1537,7 @@ Console.WriteLine("changeadd 1");
m_linkJoint = IntPtr.Zero;
}
}
if (Body != IntPtr.Zero)
{
d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
@ -1599,7 +1601,6 @@ Console.WriteLine(" JointCreateFixed");
float fy = 0;
float fz = 0;
if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
{
if (m_vehicle.Type != Vehicle.TYPE_NONE)
@ -1819,7 +1820,6 @@ Console.WriteLine(" JointCreateFixed");
float nmax = 35f * m_mass;
float nmin = -35f * m_mass;
if (fx > nmax)
fx = nmax;
if (fx < nmin)

View File

@ -3591,7 +3591,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
parentPrim.ScheduleGroupForFullUpdate();
if (client != null)
parentPrim.GetProperties(client);
parentPrim.SendPropertiesToClient(client);
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)
{
float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
@ -6651,8 +6652,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
twist.y = 1.0f;
}
shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x);
shapeBlock.PathTwist = (sbyte)(100 * twist.y);
// A fairly large precision error occurs for some calculations,
// 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;
@ -6663,6 +6676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// 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)
{
float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
ObjectShapePacket.ObjectDataBlock shapeBlock;
shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@ -6683,8 +6697,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
taper_b.y = 2f;
}
shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x));
shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y));
tempFloat = (float)(100.0d * (2.0d - taper_b.x));
shapeBlock.PathScaleX = (byte)tempFloat;
tempFloat = (float)(100.0d * (2.0d - taper_b.y));
shapeBlock.PathScaleY = (byte)tempFloat;
if (topshear.x < -0.5f)
{
topshear.x = -0.5f;
@ -6701,8 +6717,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
topshear.y = 0.5f;
}
shapeBlock.PathShearX = (byte)(100 * topshear.x);
shapeBlock.PathShearY = (byte)(100 * topshear.y);
tempFloat = (float)(100.0d * topshear.x);
shapeBlock.PathShearX = (byte)tempFloat;
tempFloat = (float)(100.0d * topshear.y);
shapeBlock.PathShearY = (byte)tempFloat;
part.Shape.SculptEntry = false;
part.UpdateShape(shapeBlock);
@ -6752,6 +6770,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// 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)
{
float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
ObjectShapePacket.ObjectDataBlock shapeBlock;
shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@ -6776,8 +6795,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
holesize.y = 0.5f;
}
shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x));
shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y));
tempFloat = (float)(100.0d * (2.0d - holesize.x));
shapeBlock.PathScaleX = (byte)tempFloat;
tempFloat = (float)(100.0d * (2.0d - holesize.y));
shapeBlock.PathScaleY = (byte)tempFloat;
if (topshear.x < -0.5f)
{
topshear.x = -0.5f;
@ -6794,8 +6815,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
topshear.y = 0.5f;
}
shapeBlock.PathShearX = (byte)(100 * topshear.x);
shapeBlock.PathShearY = (byte)(100 * topshear.y);
tempFloat = (float)(100.0d * topshear.x);
shapeBlock.PathShearX = (byte)tempFloat;
tempFloat = (float)(100.0d * topshear.y);
shapeBlock.PathShearY = (byte)tempFloat;
if (profilecut.x < 0f)
{
profilecut.x = 0f;
@ -6839,8 +6862,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
taper_a.y = 1f;
}
shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x);
shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y);
tempFloat = (float)(100.0d * taper_a.x);
shapeBlock.PathTaperX = (sbyte)tempFloat;
tempFloat = (float)(100.0d * taper_a.y);
shapeBlock.PathTaperY = (sbyte)tempFloat;
if (revolutions < 1f)
{
revolutions = 1f;
@ -6849,7 +6874,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
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
if (radiusoffset < 0f)
{
@ -6859,7 +6885,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
radiusoffset = 1f;
}
shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset);
tempFloat = 100.0f * radiusoffset;
shapeBlock.PathRadiusOffset = (sbyte)tempFloat;
if (skew < -0.95f)
{
skew = -0.95f;
@ -6868,7 +6895,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
skew = 0.95f;
}
shapeBlock.PathSkew = (sbyte)(100 * skew);
tempFloat = 100.0f * skew;
shapeBlock.PathSkew = (sbyte)tempFloat;
part.Shape.SculptEntry = false;
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));
// float revolutions
res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned
// byte is being used to represent the entire
// range of floating-point values from 1.0
// through 4.0 (which is how SL does it).
res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
// Slightly inaccurate, because an unsigned byte is being used to represent
// the entire range of floating-point values from 1.0 through 4.0 (which is how
// 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
res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));

View File

@ -49,7 +49,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
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;
[SetUp]
@ -194,10 +194,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
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.32d, 0.76d, 0.0d), // Prim dimple
0.80d); // Prim hollow check
0.80f); // Prim hollow check
// Test a prism.
CheckllSetPrimitiveParams(
@ -206,11 +206,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
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(2.0d, 1.0d, 0.0d), // Prim taper
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.
CheckllSetPrimitiveParams(
@ -219,11 +219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
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, 1.0d, 0.0d), // Prim taper
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.
CheckllSetPrimitiveParams(
@ -232,16 +232,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
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, 0.5d, 0.0d), // Prim hole size
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size
// 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(-1.0d, 1.0d, 0.0d), // Prim taper
1.0d, // Prim revolutions
1.0d, // Prim radius
0.0d, // Prim skew
0.00d); // Prim hollow check
// Expression for y selected to test precision problems during sbyte
// cast in SetPrimitiveShapeParams.
new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper
1.11f, // Prim revolutions
0.88f, // Prim radius
0.95f, // Prim skew
0.00f); // Prim hollow check
// Test a prism.
CheckllSetPrimitiveParams(
@ -250,11 +254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
0.95d, // Prim hollow
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
0.95f, // Prim hollow
// Expression for x selected to test precision problems during sbyte
// 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
0.70d); // Prim hollow check
0.70f); // Prim hollow check
// Test a sculpted prim.
CheckllSetPrimitiveParams(
@ -268,8 +276,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
// Set prim params for a box, cylinder or prism and check results.
public void CheckllSetPrimitiveParams(string primTest,
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,
double primHollowCheck)
float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
float primHollowCheck)
{
// Set the prim params.
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.
public void CheckllSetPrimitiveParams(string primTest,
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.
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.
public void CheckllSetPrimitiveParams(string primTest,
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,
double primRev, double primRadius, double primSkew, double primHollowCheck)
float primRev, float primRadius, float primSkew, float primHollowCheck)
{
// Set the prim params.
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(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper");
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,
"TestllSetPrimitiveParams " + primTest + " prim radius fail");
Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY,

View File

@ -339,7 +339,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup),
new Object[] { m_SaveTime });
}
}
public void StartProcessing()
{
m_ThreadPool.Start();
}
@ -591,7 +594,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
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_ScriptFailCount++;
return false;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -91,6 +91,11 @@ namespace OpenSim.Services.Connectors
return m_database.LoadEstateSettings(estateID);
}
public EstateSettings CreateNewEstate()
{
return m_database.CreateNewEstate();
}
public List<EstateSettings> LoadEstateSettingsAll()
{
return m_database.LoadEstateSettingsAll();

View File

@ -393,10 +393,14 @@ namespace OpenSim.Services.InventoryService
public virtual bool UpdateItem(InventoryItemBase item)
{
// throw new Exception("urrgh");
if (!m_AllowDelete)
if (item.AssetType == (sbyte)AssetType.Link || item.AssetType == (sbyte)AssetType.LinkFolder)
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));
}

View File

@ -28,15 +28,15 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Data;
using OpenSim.Framework;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Console;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenMetaverse;
using log4net;
namespace OpenSim.Services.UserAccountService
{
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 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 IAuthenticationService m_AuthenticationService;
protected IGridUserService m_GridUserService;
protected IInventoryService m_InventoryService;
protected IAvatarService m_AvatarService;
public UserAccountService(IConfigSource config)
: base(config)
@ -77,6 +83,12 @@ namespace OpenSim.Services.UserAccountService
if (invServiceDll != string.Empty)
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)
{
MainConsole.Instance.Commands.AddCommand("UserService", false,
@ -102,9 +114,7 @@ namespace OpenSim.Services.UserAccountService
"show account <first> <last>",
"Show account details for the given user", HandleShowAccount);
}
}
}
#region IUserAccountService
@ -330,7 +340,7 @@ namespace OpenSim.Services.UserAccountService
email = MainConsole.Instance.CmdPrompt("Email", "");
else email = cmdparams[5];
CreateUser(firstName, lastName, password, email);
CreateUser(UUID.Zero, firstName, lastName, password, email);
}
protected void HandleShowAccount(string module, string[] cmdparams)
@ -442,11 +452,12 @@ namespace OpenSim.Services.UserAccountService
/// <summary>
/// Create a user
/// </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="lastName"></param>
/// <param name="password"></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);
if (null == account)
@ -493,12 +504,20 @@ namespace OpenSim.Services.UserAccountService
{
success = m_InventoryService.CreateUserInventory(account.PrincipalID);
if (!success)
{
m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
firstName, lastName);
}
else if (m_CreateDefaultAvatarEntries)
{
CreateDefaultAppearanceEntries(account.PrincipalID);
}
}
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);
}
}
@ -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);
}
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);
}
}
}
}

View File

@ -234,7 +234,7 @@ namespace OpenSim.Tests.Common.Mock
public event ScriptReset OnScriptReset;
public event GetScriptRunning OnGetScriptRunning;
public event SetScriptRunning OnSetScriptRunning;
public event Action<Vector3, bool> OnAutoPilotGo;
public event Action<Vector3, bool, bool> OnAutoPilotGo;
public event TerrainUnacked OnUnackedTerrain;

View File

@ -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);
}
}
}

View File

@ -149,14 +149,13 @@
;; Choose one of the physics engines below
;; OpenDynamicsEngine is by some distance the most developed physics engine
;; 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.
;; BulletSim is incomplete and experimental but in active development
;; basicphysics effectively does not model physics at all, making all objects phantom
;; Default is OpenDynamicsEngine
; physics = OpenDynamicsEngine
; physics = BulletSim
; physics = basicphysics
; physics = POS
; physics = modified_BulletX
;# {permissionmodules} {} {Permission modules to use (may specify multiple modules, separated by space} {} DefaultPermissionsModule
;; Permission modules to use, separated by space.

View File

@ -166,6 +166,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
GridService = "OpenSim.Services.GridService.dll:GridService"
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]
; for the server connector

View File

@ -149,6 +149,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
GridService = "OpenSim.Services.GridService.dll:GridService"
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]
; for the server connector

View File

@ -4,7 +4,7 @@
<Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66"/>
<Key Name="name" Value="Hair"/>
<Key Name="assetType" Value="13" />
<Key Name="fileName" Value="newhair.dat"/>
<Key Name="fileName" Value="base_hair.dat"/>
</Section>
<Section Name="Skin">
@ -34,6 +34,14 @@
<Key Name="assetType" Value="13" />
<Key Name="fileName" Value="base_shape.dat"/>
</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">
<Key Name="assetID" Value="66c41e39-38f9-f75a-024e-585989bfab74"/>

View File

@ -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

View File

@ -8,8 +8,8 @@ New Hair
group_mask 00000000
everyone_mask 00000000
next_owner_mask 00082000
creator_id a52db6d0-e96c-4454-85e5-3523722daa25
owner_id a52db6d0-e96c-4454-85e5-3523722daa25
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
}
@ -19,7 +19,7 @@ New Hair
sale_price 10
}
type 2
parameters 39
parameters 90
16 0
31 .5
112 0
@ -38,26 +38,77 @@ parameters 39
140 0
141 0
142 0
143 .13
143 .12
144 .1
145 0
146 0
147 0
148 .22
149 0
166 0
167 0
168 0
169 0
171 0
172 .5
173 0
174 0
175 .3
176 0
177 0
178 0
179 0
180 .13
181 .14
182 .7
183 .05
184 0
190 0
191 0
192 0
400 .75
640 0
641 0
642 0
643 0
644 0
645 0
674 -.3
750 .7
751 0
752 .5
754 0
755 .05
757 -1
761 0
762 0
763 .55
771 0
774 0
782 0
783 0
784 0
785 0
786 0
787 0
788 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
4 7ca39b4c-bd19-4699-aff7-f93fd03d3e7b

View File

@ -1,105 +1,165 @@
LLWearable version 22
Female Shape and Outfit 3 Shape
Created by system from avatar's appearance.
New Shape
permissions 0
{
base_mask 00000000
owner_mask 00000000
base_mask 7fffffff
owner_mask 7fffffff
group_mask 00000000
everyone_mask 00000000
next_owner_mask 00000000
next_owner_mask 00082000
creator_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
}
sale_info 0
{
sale_type not
sale_price 0
sale_price 10
}
type 0
parameters 82
1 .21
2 -.5
4 -.11
5 -.1
6 -.3
7 -.4
8 -.5
10 .7
11 .34
12 -.5
parameters 142
1 0
2 0
4 0
5 0
6 0
7 0
8 0
10 0
11 0
12 0
13 0
14 .04
15 .58
17 .56
18 -.26
19 -.73
20 -.34
21 -.01
22 1
23 -.5
24 -.63
25 .44
27 .05
33 -.24
34 -.7
35 -.16
36 -.2
37 -.98
38 -.5
14 0
15 0
17 0
18 0
19 0
20 0
21 0
22 0
23 0
24 0
25 0
26 0
27 0
28 0
29 .12
30 .12
32 0
33 0
34 0
35 0
36 -.5
37 0
38 0
40 0
80 0
105 .07
155 -.22
100 0
104 0
105 .5
106 0
151 0
152 0
153 0
155 0
156 0
157 0
185 -1
193 .86
196 -.74
505 .65
506 .12
507 -1.5
185 0
186 0
187 0
188 0
189 0
193 .5
194 .67
195 .33
196 0
505 .5
506 0
507 0
515 0
517 .16
518 .8
629 0
517 0
518 0
626 0
627 0
629 .5
630 0
631 0
633 0
634 0
635 0
637 0
646 .4
647 1
649 .36
650 .85
652 .49
653 -1
646 0
647 0
648 0
649 .5
650 0
651 0
652 .5
653 0
655 -.08
656 0
659 .65
657 0
658 0
659 .5
660 0
661 0
662 .5
663 0
664 0
665 0
675 -.15
676 .26
678 .28
682 .27
683 -.19
684 -.09
675 0
676 0
677 0
678 .5
679 -.08
680 -.08
681 -.08
682 .5
683 -.15
684 0
685 0
690 .45
692 .4
693 -0
753 -.5
756 -.08
758 .24
759 .6
760 .11
764 -.38
765 -.3
769 .42
773 .51
795 .16
796 .11
799 .36
686 0
687 0
688 0
689 0
690 .5
691 0
692 0
693 .6
694 -.08
695 0
753 0
756 0
758 0
759 .5
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
842 -.82
842 0
843 0
853 0
854 0
855 0
879 0
880 0
1103 0
1104 0
1105 0
1200 0
1201 0
textures 0

View File

@ -430,6 +430,13 @@
<Key Name="fileName" Value="default_avatar.jp2" />
</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">
<Key Name="assetID" Value="fb2ae204-3fd1-df33-594f-c9f882830e66"/>
<Key Name="name" Value="Cypress 1"/>

Binary file not shown.

View File

@ -70,6 +70,10 @@
GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService"
GridService = "OpenSim.Services.GridService.dll:GridService"
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]
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"

View File

@ -561,4 +561,14 @@
<Key Name="assetType" Value="0" />
<Key Name="inventoryType" Value="0" />
</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>

View File

@ -573,34 +573,6 @@
</Files>
</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">
<Configuration name="Debug">
<Options>
@ -690,34 +662,6 @@
</Files>
</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">
<Configuration name="Debug">
<Options>
@ -1840,6 +1784,9 @@
<Reference name="OpenSim.Region.ClientStack"/>
<Reference name="OpenSim.Framework.Communications"/>
<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="Nini" path="../../../bin/"/>
<Reference name="log4net" path="../../../bin/"/>