diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 597b4397c5..1ee24689dc 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -359,6 +359,42 @@ namespace OpenSim.ApplicationPlugins.RemoteController notice = false; } + if (startupConfig.GetBoolean("SkipDelayOnEmptyRegion", false)) + { + m_log.Info("[RADMIN]: Counting affected avatars"); + int agents = 0; + + if (restartAll) + { + foreach (Scene s in m_application.SceneManager.Scenes) + { + foreach (ScenePresence sp in s.GetScenePresences()) + { + if (!sp.IsChildAgent && !sp.IsNPC) + agents++; + } + } + } + else + { + foreach (ScenePresence sp in rebootedScene.GetScenePresences()) + { + if (!sp.IsChildAgent && !sp.IsNPC) + agents++; + } + } + + m_log.InfoFormat("[RADMIN]: Avatars in region: {0}", agents); + + if (agents == 0) + { + m_log.Info("[RADMIN]: No avatars detected, shutting down without delay"); + + times.Clear(); + times.Add(0); + } + } + List restartList; if (restartAll) @@ -376,10 +412,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController } catch (Exception e) { -// m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); + m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); responseData["rebooting"] = false; - throw e; + throw; } m_log.Info("[RADMIN]: Restart Region request complete"); diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index 34791cf6be..93662db875 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -36,7 +36,7 @@ using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { /// - /// A database interface class to a user profile storage system + /// Common code for a number of database modules /// public class MySqlFramework { @@ -44,14 +44,24 @@ namespace OpenSim.Data.MySQL log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - protected string m_connectionString; - protected object m_dbLock = new object(); + protected string m_connectionString = String.Empty; + protected MySqlTransaction m_trans = null; + // Constructor using a connection string. Instances constructed + // this way will open a new connection for each call. protected MySqlFramework(string connectionString) { m_connectionString = connectionString; } + // Constructor using a connection object. Instances constructed + // this way will use the connection object and never create + // new connections. + protected MySqlFramework(MySqlTransaction trans) + { + m_trans = trans; + } + ////////////////////////////////////////////////////////////// // // All non queries are funneled through one connection @@ -59,33 +69,48 @@ namespace OpenSim.Data.MySQL // protected int ExecuteNonQuery(MySqlCommand cmd) { - lock (m_dbLock) + if (m_trans == null) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - try - { - dbcon.Open(); - cmd.Connection = dbcon; - - try - { - return cmd.ExecuteNonQuery(); - } - catch (Exception e) - { - m_log.Error(e.Message, e); - m_log.Error(Environment.StackTrace.ToString()); - return 0; - } - } - catch (Exception e) - { - m_log.Error(e.Message, e); - return 0; - } + dbcon.Open(); + return ExecuteNonQueryWithConnection(cmd, dbcon); } } + else + { + return ExecuteNonQueryWithTransaction(cmd, m_trans); + } + } + + private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans) + { + cmd.Transaction = trans; + return ExecuteNonQueryWithConnection(cmd, trans.Connection); + } + + private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon) + { + try + { + cmd.Connection = dbcon; + + try + { + return cmd.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error(e.Message, e); + m_log.Error(Environment.StackTrace.ToString()); + return 0; + } + } + catch (Exception e) + { + m_log.Error(e.Message, e); + return 0; + } } } -} \ No newline at end of file +} diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 6aae9c644b..bd8bbd5920 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -53,14 +53,27 @@ namespace OpenSim.Data.MySQL get { return GetType().Assembly; } } + public MySQLGenericTableHandler(MySqlTransaction trans, + string realm, string storeName) : base(trans) + { + m_Realm = realm; + + CommonConstruct(storeName); + } + public MySQLGenericTableHandler(string connectionString, string realm, string storeName) : base(connectionString) { m_Realm = realm; - m_connectionString = connectionString; + CommonConstruct(storeName); + } + + protected void CommonConstruct(string storeName) + { if (storeName != String.Empty) { + // We always use a new connection for any Migrations using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); @@ -110,6 +123,11 @@ namespace OpenSim.Data.MySQL } public virtual T[] Get(string[] fields, string[] keys) + { + return Get(fields, keys, String.Empty); + } + + public virtual T[] Get(string[] fields, string[] keys, string options) { if (fields.Length != keys.Length) return new T[0]; @@ -126,8 +144,8 @@ namespace OpenSim.Data.MySQL string where = String.Join(" and ", terms.ToArray()); - string query = String.Format("select * from {0} where {1}", - m_Realm, where); + string query = String.Format("select * from {0} where {1} {2}", + m_Realm, where, options); cmd.CommandText = query; @@ -136,73 +154,93 @@ namespace OpenSim.Data.MySQL } protected T[] DoQuery(MySqlCommand cmd) + { + if (m_trans == null) + { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + return DoQueryWithConnection(cmd, dbcon); + } + } + else + { + return DoQueryWithTransaction(cmd, m_trans); + } + } + + protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans) + { + cmd.Transaction = trans; + + return DoQueryWithConnection(cmd, trans.Connection); + } + + protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon) { List result = new List(); - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + cmd.Connection = dbcon; + + using (IDataReader reader = cmd.ExecuteReader()) { - dbcon.Open(); - cmd.Connection = dbcon; + if (reader == null) + return new T[0]; - using (IDataReader reader = cmd.ExecuteReader()) + CheckColumnNames(reader); + + while (reader.Read()) { - if (reader == null) - return new T[0]; + T row = new T(); - CheckColumnNames(reader); - - while (reader.Read()) + foreach (string name in m_Fields.Keys) { - T row = new T(); - - foreach (string name in m_Fields.Keys) + if (reader[name] is DBNull) { - if (reader[name] is DBNull) - { - continue; - } - if (m_Fields[name].FieldType == typeof(bool)) - { - int v = Convert.ToInt32(reader[name]); - m_Fields[name].SetValue(row, v != 0 ? true : false); - } - else if (m_Fields[name].FieldType == typeof(UUID)) - { - m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); - } - else if (m_Fields[name].FieldType == typeof(int)) - { - int v = Convert.ToInt32(reader[name]); - m_Fields[name].SetValue(row, v); - } - else if (m_Fields[name].FieldType == typeof(uint)) - { - uint v = Convert.ToUInt32(reader[name]); - m_Fields[name].SetValue(row, v); - } - else - { - m_Fields[name].SetValue(row, reader[name]); - } + continue; } - - if (m_DataField != null) + if (m_Fields[name].FieldType == typeof(bool)) { - Dictionary data = - new Dictionary(); - - foreach (string col in m_ColumnNames) - { - data[col] = reader[col].ToString(); - if (data[col] == null) - data[col] = String.Empty; - } - - m_DataField.SetValue(row, data); + int v = Convert.ToInt32(reader[name]); + m_Fields[name].SetValue(row, v != 0 ? true : false); + } + else if (m_Fields[name].FieldType == typeof(UUID)) + { + m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); + } + else if (m_Fields[name].FieldType == typeof(int)) + { + int v = Convert.ToInt32(reader[name]); + m_Fields[name].SetValue(row, v); + } + else if (m_Fields[name].FieldType == typeof(uint)) + { + uint v = Convert.ToUInt32(reader[name]); + m_Fields[name].SetValue(row, v); + } + else + { + m_Fields[name].SetValue(row, reader[name]); } - - result.Add(row); } + + if (m_DataField != null) + { + Dictionary data = + new Dictionary(); + + foreach (string col in m_ColumnNames) + { + data[col] = reader[col].ToString(); + if (data[col] == null) + data[col] = String.Empty; + } + + m_DataField.SetValue(row, data); + } + + result.Add(row); } } @@ -357,14 +395,23 @@ namespace OpenSim.Data.MySQL public object DoQueryScalar(MySqlCommand cmd) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + if (m_trans == null) { - dbcon.Open(); - cmd.Connection = dbcon; + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + cmd.Connection = dbcon; + + return cmd.ExecuteScalar(); + } + } + else + { + cmd.Connection = m_trans.Connection; + cmd.Transaction = m_trans; return cmd.ExecuteScalar(); } } - } } diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 8278c0ec20..5740b916db 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -187,7 +187,7 @@ namespace OpenSim.Data.MySQL "LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " + "AttachedPosY, AttachedPosZ, " + "PhysicsShapeType, Density, GravityModifier, " + - "Friction, Restitution, Vehicle, DynAttrs, " + + "Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " + "RotationAxisLocks" + ") values (" + "?UUID, " + "?CreationDate, ?Name, ?Text, " + @@ -224,7 +224,7 @@ namespace OpenSim.Data.MySQL "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " + "?AttachedPosY, ?AttachedPosZ, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " + - "?Friction, ?Restitution, ?Vehicle, ?DynAttrs," + + "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," + "?RotationAxisLocks)"; FillPrimCommand(cmd, prim, obj.UUID, regionUUID); @@ -1452,6 +1452,11 @@ namespace OpenSim.Data.MySQL prim.VehicleParams = vehicle; } + PhysicsInertiaData pdata = null; + if (row["PhysInertia"].ToString() != String.Empty) + pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; + return prim; } @@ -1810,6 +1815,11 @@ namespace OpenSim.Data.MySQL else cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); + if (prim.PhysicsInertia != null) + cmd.Parameters.AddWithValue("PhysInertia", prim.PhysicsInertia.ToXml2()); + else + cmd.Parameters.AddWithValue("PhysInertia", String.Empty); + if (prim.VehicleParams != null) cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); else diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index c63cc95d22..0577392184 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -461,3 +461,9 @@ BEGIN; ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; COMMIT; + +:VERSION 57 #----- Add physics inertia data + +BEGIN; +ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; +COMMIT; diff --git a/OpenSim/Data/PGSQL/PGSQLGroupsData.cs b/OpenSim/Data/PGSQL/PGSQLGroupsData.cs index 6ef576bccc..f398256863 100755 --- a/OpenSim/Data/PGSQL/PGSQLGroupsData.cs +++ b/OpenSim/Data/PGSQL/PGSQLGroupsData.cs @@ -435,7 +435,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); + cmd.CommandText = String.Format("delete from {0} where \"TMStamp\"::abstime::timestamp < now() - INTERVAL '2 week'", m_Realm); ExecuteNonQuery(cmd); } @@ -461,7 +461,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); + cmd.CommandText = String.Format("delete from {0} where \"TMStamp\"::abstime::timestamp < now() - INTERVAL '2 week'", m_Realm); ExecuteNonQuery(cmd); } diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index 33d12bd71e..625120b841 100755 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -350,10 +350,11 @@ namespace OpenSim.Data.PGSQL ""CameraEyeOffsetY"" = :CameraEyeOffsetY, ""CameraEyeOffsetZ"" = :CameraEyeOffsetZ, ""CameraAtOffsetX"" = :CameraAtOffsetX, ""CameraAtOffsetY"" = :CameraAtOffsetY, ""CameraAtOffsetZ"" = :CameraAtOffsetZ, ""ForceMouselook"" = :ForceMouselook, ""ScriptAccessPin"" = :ScriptAccessPin, ""AllowedDrop"" = :AllowedDrop, ""DieAtEdge"" = :DieAtEdge, ""SalePrice"" = :SalePrice, - ""SaleType"" = :SaleType, ""ColorR"" = :ColorR, ""ColorG"" = :ColorG, ""ColorB"" = :ColorB, ""ColorA"" = :ColorA, ""ParticleSystem"" = :ParticleSystem, + ""PhysicsShapeType"" = :PhysicsShapeType, ""Density"" = :Density, ""GravityModifier"" = :GravityModifier, ""Friction"" = :Friction, ""Restitution"" = :Restitution, + ""PassCollisions"" = :PassCollisions, ""RotationAxisLocks"" = :RotationAxisLocks, ""RezzerID"" = :RezzerID, ""ClickAction"" = :ClickAction, ""Material"" = :Material, ""CollisionSound"" = :CollisionSound, ""CollisionSoundVolume"" = :CollisionSoundVolume, ""PassTouches"" = :PassTouches, ""LinkNumber"" = :LinkNumber, ""MediaURL"" = :MediaURL, ""DynAttrs"" = :DynAttrs, - ""PhysicsShapeType"" = :PhysicsShapeType, ""Density"" = :Density, ""GravityModifier"" = :GravityModifier, ""Friction"" = :Friction, ""Restitution"" = :Restitution + ""PhysInertia"" = :PhysInertia WHERE ""UUID"" = :UUID ; INSERT INTO @@ -367,7 +368,7 @@ namespace OpenSim.Data.PGSQL ""OmegaY"", ""OmegaZ"", ""CameraEyeOffsetX"", ""CameraEyeOffsetY"", ""CameraEyeOffsetZ"", ""CameraAtOffsetX"", ""CameraAtOffsetY"", ""CameraAtOffsetZ"", ""ForceMouselook"", ""ScriptAccessPin"", ""AllowedDrop"", ""DieAtEdge"", ""SalePrice"", ""SaleType"", ""ColorR"", ""ColorG"", ""ColorB"", ""ColorA"", ""ParticleSystem"", ""ClickAction"", ""Material"", ""CollisionSound"", ""CollisionSoundVolume"", ""PassTouches"", ""LinkNumber"", ""MediaURL"", ""DynAttrs"", - ""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"" + ""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"", ""PassCollisions"", ""RotationAxisLocks"", ""RezzerID"" , ""PhysInertia"" ) Select :UUID, :CreationDate, :Name, :Text, :Description, :SitName, :TouchName, :ObjectFlags, :OwnerMask, :NextOwnerMask, :GroupMask, :EveryoneMask, :BaseMask, :PositionX, :PositionY, :PositionZ, :GroupPositionX, :GroupPositionY, :GroupPositionZ, :VelocityX, @@ -378,7 +379,7 @@ namespace OpenSim.Data.PGSQL :OmegaY, :OmegaZ, :CameraEyeOffsetX, :CameraEyeOffsetY, :CameraEyeOffsetZ, :CameraAtOffsetX, :CameraAtOffsetY, :CameraAtOffsetZ, :ForceMouselook, :ScriptAccessPin, :AllowedDrop, :DieAtEdge, :SalePrice, :SaleType, :ColorR, :ColorG, :ColorB, :ColorA, :ParticleSystem, :ClickAction, :Material, :CollisionSound, :CollisionSoundVolume, :PassTouches, :LinkNumber, :MediaURL, :DynAttrs, - :PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution + :PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution, :PassCollisions, :RotationAxisLocks, :RezzerID, :PhysInertia where not EXISTS (SELECT ""UUID"" FROM prims WHERE ""UUID"" = :UUID); "; @@ -1678,6 +1679,12 @@ namespace OpenSim.Data.PGSQL prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); prim.GroupID = new UUID((Guid)primRow["GroupID"]); prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); + + if (primRow["RezzerID"] != DBNull.Value) + prim.RezzerID = new UUID((Guid)primRow["RezzerID"]); + else + prim.RezzerID = UUID.Zero; + prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]); prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]); prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]); @@ -1796,6 +1803,13 @@ namespace OpenSim.Data.PGSQL prim.GravityModifier = Convert.ToSingle(primRow["GravityModifier"]); prim.Friction = Convert.ToSingle(primRow["Friction"]); prim.Restitution = Convert.ToSingle(primRow["Restitution"]); + prim.RotationAxisLocks = Convert.ToByte(primRow["RotationAxisLocks"]); + + + PhysicsInertiaData pdata = null; + if (!(primRow["PhysInertia"] is System.DBNull)) + pdata = PhysicsInertiaData.FromXml2(primRow["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; return prim; } @@ -2097,6 +2111,7 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID)); parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID)); parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID)); + parameters.Add(_Database.CreateParameter("RezzerID", prim.RezzerID)); parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask)); parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask)); parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask)); @@ -2196,10 +2211,28 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); - parameters.Add(_Database.CreateParameter("PassTouches", prim.PassTouches)); + parameters.Add(_Database.CreateParameter("PassTouches", (bool)prim.PassTouches)); + parameters.Add(_Database.CreateParameter("PassCollisions", prim.PassCollisions)); + + + if (prim.PassTouches) + parameters.Add(_Database.CreateParameter("PassTouches", true)); + else + parameters.Add(_Database.CreateParameter("PassTouches", false)); + + if (prim.PassCollisions) + parameters.Add(_Database.CreateParameter("PassCollisions", 1)); + else + parameters.Add(_Database.CreateParameter("PassCollisions", 0)); parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl)); + + if (prim.PhysicsInertia != null) + parameters.Add(_Database.CreateParameter("PhysInertia", prim.PhysicsInertia.ToXml2())); + else + parameters.Add(_Database.CreateParameter("PhysInertia", String.Empty)); + if (prim.DynAttrs.CountNamespaces > 0) parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml())); @@ -2211,12 +2244,13 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("GravityModifier", (double)prim.GravityModifier)); parameters.Add(_Database.CreateParameter("Friction", (double)prim.Friction)); parameters.Add(_Database.CreateParameter("Restitution", (double)prim.Restitution)); + parameters.Add(_Database.CreateParameter("RotationAxisLocks", prim.RotationAxisLocks)); return parameters.ToArray(); } /// - /// Creates the primshape parameters for stroing in DB. + /// Creates the primshape parameters for storing in DB. /// /// Basic data of SceneObjectpart prim. /// The scene group ID. diff --git a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations index c08593917d..948d17714e 100644 --- a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations @@ -1195,3 +1195,19 @@ CREATE TABLE bakedterrain ); COMMIT; + +:VERSION 45 #---- Add RezzerID filed in table prims + +BEGIN TRANSACTION; + +ALTER TABLE prims ADD "RezzerID" uuid NULL; + +COMMIT; + +:VERSION 46 #---- Add physics inertia data to table prims + +BEGIN TRANSACTION; + +ALTER TABLE prims ADD "PhysInertia" TEXT; + +COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index eef14d6a46..fb154cf84a 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -371,3 +371,9 @@ BEGIN; ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; COMMIT; + +:VERSION 36 #----- Add physics inertia data + +BEGIN; +ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; +COMMIT; diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index eec386fcb0..19880dec20 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -1843,6 +1843,12 @@ namespace OpenSim.Data.SQLite if (vehicle != null) prim.VehicleParams = vehicle; } + + PhysicsInertiaData pdata = null; + if (!(row["PhysInertia"] is DBNull) && row["PhysInertia"].ToString() != String.Empty) + pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; + return prim; } @@ -2266,6 +2272,11 @@ namespace OpenSim.Data.SQLite else row["Vehicle"] = String.Empty; + if (prim.PhysicsInertia != null) + row["PhysInertia"] = prim.PhysicsInertia.ToXml2(); + else + row["PhysInertia"] = String.Empty; + } /// diff --git a/OpenSim/Framework/IAssetCache.cs b/OpenSim/Framework/IAssetCache.cs index 8477116403..2df9199a26 100644 --- a/OpenSim/Framework/IAssetCache.cs +++ b/OpenSim/Framework/IAssetCache.cs @@ -47,8 +47,9 @@ namespace OpenSim.Framework /// Get an asset by its id. /// /// - /// null if the asset does not exist. - AssetBase Get(string id); + /// Will be set to null if no asset was found + /// False if the asset has been negative-cached + bool Get(string id, out AssetBase asset); /// /// Check whether an asset with the specified id exists in the cache. diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 1267993d1f..5ca8c88ecb 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -107,7 +107,7 @@ namespace OpenSim.Framework public delegate void GenericCall4(Packet packet, IClientAPI remoteClient); public delegate void DeRezObject( - IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID); + IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID, bool AddToReturns = true); public delegate void GenericCall5(IClientAPI remoteClient, bool status); @@ -685,9 +685,10 @@ namespace OpenSim.Framework ExtraData = 1 << 20, Sound = 1 << 21, Joint = 1 << 22, - FullUpdate = 0x3fffffff, - CancelKill = 0x7fffffff, - Kill = 0x80000000 + FullUpdate = 0x0fffffff, + SendInTransit = 0x20000000, + CancelKill = 0x4fffffff, // 1 << 30 + Kill = 0x80000000 // 1 << 31 } /* included in .net 4.0 @@ -1112,7 +1113,7 @@ namespace OpenSim.Framework /// void SendKillObject(List localID); - void SendPartFullUpdate(ISceneEntity ent, uint? parentID); +// void SendPartFullUpdate(ISceneEntity ent, uint? parentID); void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); @@ -1187,7 +1188,8 @@ namespace OpenSim.Framework void SetAgentThrottleSilent(int throttle, int setting); int GetAgentThrottleSilent(int throttle); - void SendAvatarDataImmediate(ISceneEntity avatar); + void SendEntityFullUpdateImmediate(ISceneEntity entity); + void SendEntityTerseUpdateImmediate(ISceneEntity entity); /// /// Send a positional, velocity, etc. update to the viewer for a given entity. diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 55c327656a..a6b341f21c 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -47,6 +47,8 @@ namespace OpenSim.Framework.Monitoring // Subcommand used to list other stats. public const string ListSubCommand = "list"; + public static string StatsPassword { get; set; } + // All subcommands public static HashSet SubCommands = new HashSet { AllSubCommand, ListSubCommand }; @@ -302,6 +304,17 @@ namespace OpenSim.Framework.Monitoring int response_code = 200; string contenttype = "text/json"; + if (StatsPassword != String.Empty && (!request.ContainsKey("pass") || request["pass"].ToString() != StatsPassword)) + { + responsedata["int_response_code"] = response_code; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Access denied"; + responsedata["access_control_allow_origin"] = "*"; + + return responsedata; + } + string pCategoryName = StatsManager.AllSubCommand; string pContainerName = StatsManager.AllSubCommand; string pStatName = StatsManager.AllSubCommand; diff --git a/OpenSim/Framework/OutboundUrlFilter.cs b/OpenSim/Framework/OutboundUrlFilter.cs index ee4707fa8c..63ae361448 100644 --- a/OpenSim/Framework/OutboundUrlFilter.cs +++ b/OpenSim/Framework/OutboundUrlFilter.cs @@ -212,7 +212,17 @@ namespace OpenSim.Framework // Check that we are permitted to make calls to this endpoint. bool foundIpv4Address = false; - IPAddress[] addresses = Dns.GetHostAddresses(url.Host); + IPAddress[] addresses = null; + + try + { + addresses = Dns.GetHostAddresses(url.Host); + } + catch + { + // If there is a DNS error, we can't stop the script! + return true; + } foreach (IPAddress addr in addresses) { @@ -253,4 +263,4 @@ namespace OpenSim.Framework return allowed; } } -} \ No newline at end of file +} diff --git a/OpenSim/Framework/PhysicsInertia.cs b/OpenSim/Framework/PhysicsInertia.cs new file mode 100644 index 0000000000..af70634b7e --- /dev/null +++ b/OpenSim/Framework/PhysicsInertia.cs @@ -0,0 +1,262 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using System.Text; +using System.IO; +using System.Xml; + +namespace OpenSim.Framework +{ + public class PhysicsInertiaData + { + public float TotalMass; // the total mass of a linkset + public Vector3 CenterOfMass; // the center of mass position relative to root part position + public Vector3 Inertia; // (Ixx, Iyy, Izz) moment of inertia relative to center of mass and principal axis in local coords + public Vector4 InertiaRotation; // if principal axis don't match local axis, the principal axis rotation + // or the upper triangle of the inertia tensor + // Ixy (= Iyx), Ixz (= Izx), Iyz (= Izy)) + + public PhysicsInertiaData() + { + } + + public PhysicsInertiaData(PhysicsInertiaData source) + { + TotalMass = source.TotalMass; + CenterOfMass = source.CenterOfMass; + Inertia = source.Inertia; + InertiaRotation = source.InertiaRotation; + } + + private XmlTextWriter writer; + + private void XWint(string name, int i) + { + writer.WriteElementString(name, i.ToString()); + } + + private void XWfloat(string name, float f) + { + writer.WriteElementString(name, f.ToString(Utils.EnUsCulture)); + } + + private void XWVector(string name, Vector3 vec) + { + writer.WriteStartElement(name); + writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture)); + writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture)); + writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture)); + writer.WriteEndElement(); + } + + private void XWVector4(string name, Vector4 quat) + { + writer.WriteStartElement(name); + writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture)); + writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture)); + writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture)); + writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture)); + writer.WriteEndElement(); + } + + public void ToXml2(XmlTextWriter twriter) + { + writer = twriter; + writer.WriteStartElement("PhysicsInertia"); + + XWfloat("MASS", TotalMass); + XWVector("CM", CenterOfMass); + XWVector("INERTIA", Inertia); + XWVector4("IROT", InertiaRotation); + + writer.WriteEndElement(); + writer = null; + } + + XmlReader reader; + + private int XRint() + { + return reader.ReadElementContentAsInt(); + } + + private float XRfloat() + { + return reader.ReadElementContentAsFloat(); + } + + public Vector3 XRvector() + { + Vector3 vec; + reader.ReadStartElement(); + vec.X = reader.ReadElementContentAsFloat(); + vec.Y = reader.ReadElementContentAsFloat(); + vec.Z = reader.ReadElementContentAsFloat(); + reader.ReadEndElement(); + return vec; + } + + public Vector4 XRVector4() + { + Vector4 q; + reader.ReadStartElement(); + q.X = reader.ReadElementContentAsFloat(); + q.Y = reader.ReadElementContentAsFloat(); + q.Z = reader.ReadElementContentAsFloat(); + q.W = reader.ReadElementContentAsFloat(); + reader.ReadEndElement(); + return q; + } + + public static bool EReadProcessors( + Dictionary processors, + XmlReader xtr) + { + bool errors = false; + + string nodeName = string.Empty; + while (xtr.NodeType != XmlNodeType.EndElement) + { + nodeName = xtr.Name; + + Action p = null; + if (processors.TryGetValue(xtr.Name, out p)) + { + try + { + p(); + } + catch + { + errors = true; + if (xtr.NodeType == XmlNodeType.EndElement) + xtr.Read(); + } + } + else + { + xtr.ReadOuterXml(); // ignore + } + } + + return errors; + } + + public string ToXml2() + { + using (StringWriter sw = new StringWriter()) + { + using (XmlTextWriter xwriter = new XmlTextWriter(sw)) + { + ToXml2(xwriter); + } + + return sw.ToString(); + } + } + + public static PhysicsInertiaData FromXml2(string text) + { + if (text == String.Empty) + return null; + + UTF8Encoding enc = new UTF8Encoding(); + MemoryStream ms = new MemoryStream(enc.GetBytes(text)); + XmlTextReader xreader = new XmlTextReader(ms); + + PhysicsInertiaData v = new PhysicsInertiaData(); + bool error; + + v.FromXml2(xreader, out error); + + xreader.Close(); + + if (error) + return null; + + return v; + } + + public static PhysicsInertiaData FromXml2(XmlReader reader) + { + PhysicsInertiaData data = new PhysicsInertiaData(); + + bool errors = false; + + data.FromXml2(reader, out errors); + if (errors) + return null; + + return data; + } + + private void FromXml2(XmlReader _reader, out bool errors) + { + errors = false; + reader = _reader; + + Dictionary m_XmlProcessors = new Dictionary(); + + m_XmlProcessors.Add("MASS", ProcessXR_Mass); + m_XmlProcessors.Add("CM", ProcessXR_CM); + m_XmlProcessors.Add("INERTIA", ProcessXR_Inertia); + m_XmlProcessors.Add("IROT", ProcessXR_InertiaRotation); + + reader.ReadStartElement("PhysicsInertia", String.Empty); + + errors = EReadProcessors( + m_XmlProcessors, + reader); + + reader.ReadEndElement(); + reader = null; + } + + private void ProcessXR_Mass() + { + TotalMass = XRfloat(); + } + + private void ProcessXR_CM() + { + CenterOfMass = XRvector(); + } + + private void ProcessXR_Inertia() + { + Inertia = XRvector(); + } + + private void ProcessXR_InertiaRotation() + { + InertiaRotation = XRVector4(); + } + } +} diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 29985d2586..a830551793 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -328,6 +328,70 @@ namespace OpenSim.Framework return shape; } + public static PrimitiveBaseShape CreateMesh(int numberOfFaces, UUID meshAssetID) + { + PrimitiveBaseShape shape = new PrimitiveBaseShape(); + + shape._pathScaleX = 100; + shape._pathScaleY = 100; + + if(numberOfFaces <= 0) // oops ? + numberOfFaces = 1; + + switch(numberOfFaces) + { + case 1: // torus + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Curve1; + break; + + case 2: // torus with hollow (a sl viewer whould see 4 faces on a hollow sphere) + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Curve1; + shape.ProfileHollow = 1; + break; + + case 3: // cylinder + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 4: // cylinder with hollow + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileHollow = 1; + break; + + case 5: // prism + shape.ProfileCurve = (byte)ProfileShape.EquilateralTriangle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 6: // box + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 7: // box with hollow + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileHollow = 1; + break; + + default: // 8 faces box with cut + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileBegin = 1; + break; + } + + shape.SculptEntry = true; + shape.SculptType = (byte)OpenMetaverse.SculptType.Mesh; + shape.SculptTexture = meshAssetID; + + return shape; + } + public void SetScale(float side) { _scale = new Vector3(side, side, side); diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 99e97e8b51..7de8c526b2 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -130,7 +130,7 @@ namespace OpenSim.Framework private float m_physPrimMin = 0; private int m_physPrimMax = 0; private bool m_clampPrimSize = false; - private int m_objectCapacity = 0; + private int m_objectCapacity = 15000; private int m_maxPrimsPerUser = -1; private int m_linksetCapacity = 0; private string m_regionType = String.Empty; @@ -753,7 +753,7 @@ namespace OpenSim.Framework m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); allKeys.Remove("ClampPrimSize"); - m_objectCapacity = config.GetInt("MaxPrims", 15000); + m_objectCapacity = config.GetInt("MaxPrims", m_objectCapacity); allKeys.Remove("MaxPrims"); m_maxPrimsPerUser = config.GetInt("MaxPrimsPerUser", -1); diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index 8965e71a34..f627ae61ee 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -57,6 +57,7 @@ namespace OpenSim.Framework.Servers protected OpenSimAppender m_consoleAppender; protected FileAppender m_logFileAppender; + protected FileAppender m_statsLogFileAppender; protected DateTime m_startuptime; protected string m_startupDirectory = Environment.CurrentDirectory; @@ -156,6 +157,10 @@ namespace OpenSim.Framework.Servers { m_logFileAppender = (FileAppender)appender; } + else if (appender.Name == "StatsLogFileAppender") + { + m_statsLogFileAppender = (FileAppender)appender; + } } if (null == m_consoleAppender) @@ -185,6 +190,18 @@ namespace OpenSim.Framework.Servers m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File); } + + if (m_statsLogFileAppender != null && startupConfig != null) + { + string cfgStatsFileName = startupConfig.GetString("StatsLogFile", null); + if (cfgStatsFileName != null) + { + m_statsLogFileAppender.File = cfgStatsFileName; + m_statsLogFileAppender.ActivateOptions(); + } + + m_log.InfoFormat("[SERVER BASE]: Stats Logging started to file {0}", m_statsLogFileAppender.File); + } } /// diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 6d679f2c12..0ec24e60f4 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -63,22 +63,34 @@ namespace OpenSim.Framework None = 0, // folded perms - foldedTransfer = 1, - foldedModify = 1 << 1, - foldedCopy = 1 << 2, + FoldedTransfer = 1, + FoldedModify = 1 << 1, + FoldedCopy = 1 << 2, + FoldedExport = 1 << 3, - foldedMask = 0x07, + // DO NOT USE THIS FOR NEW WORK. IT IS DEPRECATED AND + // EXISTS ONLY TO REACT TO EXISTING OBJECTS HAVING IT. + // NEW CODE SHOULD NEVER SET THIS BIT! + // Use InventoryItemFlags.ObjectSlamPerm in the Flags field of + // this legacy slam bit. It comes from prior incomplete + // understanding of the code and the prohibition on + // reading viewer code that used to be in place. + Slam = (1 << 4), + + FoldedMask = 0x0f, // - Transfer = 1 << 13, - Modify = 1 << 14, - Copy = 1 << 15, - Export = 1 << 16, - Move = 1 << 19, - Damage = 1 << 20, + Transfer = 1 << 13, // 0x02000 + Modify = 1 << 14, // 0x04000 + Copy = 1 << 15, // 0x08000 + Export = 1 << 16, // 0x10000 + Move = 1 << 19, // 0x80000 + Damage = 1 << 20, // 0x100000 does not seem to be in use // All does not contain Export, which is special and must be // explicitly given - All = (1 << 13) | (1 << 14) | (1 << 15) | (1 << 19) + All = 0x8e000, + AllAndExport = 0x9e000, + AllEffective = 0x9e000 } /// @@ -1180,7 +1192,7 @@ namespace OpenSim.Framework { foreach (IAppender appender in LogManager.GetRepository().GetAppenders()) { - if (appender is FileAppender) + if (appender is FileAppender && appender.Name == "LogFileAppender") { return ((FileAppender)appender).File; } @@ -1189,6 +1201,19 @@ namespace OpenSim.Framework return "./OpenSim.log"; } + public static string statsLogFile() + { + foreach (IAppender appender in LogManager.GetRepository().GetAppenders()) + { + if (appender is FileAppender && appender.Name == "StatsLogFileAppender") + { + return ((FileAppender)appender).File; + } + } + + return "./OpenSimStats.log"; + } + public static string logDir() { return Path.GetDirectoryName(logFile()); diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs index ccaf69edfd..427e149f69 100644 --- a/OpenSim/Framework/WearableCacheItem.cs +++ b/OpenSim/Framework/WearableCacheItem.cs @@ -113,7 +113,8 @@ namespace OpenSim.Framework { if (dataCache.Check(item.TextureID.ToString())) { - AssetBase assetItem = dataCache.Get(item.TextureID.ToString()); + AssetBase assetItem; + dataCache.Get(item.TextureID.ToString(), out assetItem); if (assetItem != null) { itemmap.Add("assetdata", OSD.FromBinary(assetItem.Data)); diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 8022b1e587..58178bcf50 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -211,6 +211,7 @@ namespace OpenSim if (managedStatsURI != String.Empty) { string urlBase = String.Format("/{0}/", managedStatsURI); + StatsManager.StatsPassword = managedStatsPassword; MainServer.Instance.AddHTTPHandler(urlBase, StatsManager.HandleStatsRequest); m_log.InfoFormat("[OPENSIM] Enabling remote managed stats fetch. URL = {0}", urlBase); } diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 75dc741298..079d7336a7 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -88,6 +88,7 @@ namespace OpenSim public string userStatsURI = String.Empty; public string managedStatsURI = String.Empty; + public string managedStatsPassword = String.Empty; protected bool m_autoCreateClientStack = true; @@ -239,6 +240,7 @@ namespace OpenSim m_permsModules = new List(permissionModules.Split(',')); managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty); + managedStatsPassword = startupConfig.GetString("ManagedStatsRemoteFetchPassword", String.Empty); } // Load the simulation data service @@ -481,15 +483,14 @@ namespace OpenSim while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null) SetUpEstateOwner(scene); + scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID); + // Prims have to be loaded after module configuration since some modules may be invoked during the load scene.LoadPrimsFromStorage(regionInfo.originRegionID); // TODO : Try setting resource for region xstats here on scene MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo)); - scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID); - scene.EventManager.TriggerParcelPrimCountUpdate(); - if (scene.SnmpService != null) { scene.SnmpService.BootInfo("Grid Registration in progress", scene); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 58b7b00169..e1b9e08f29 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -946,17 +946,26 @@ namespace OpenSim.Region.ClientStack.Linden continue; } - PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); + OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; + + PrimitiveBaseShape pbs = null; + if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ... + { + int meshindx = inner_instance_list["mesh"].AsInteger(); + if (meshAssets.Count > meshindx) + pbs = PrimitiveBaseShape.CreateMesh(face_list.Count, meshAssets[meshindx]); + } + if(pbs == null) // fallback + pbs = PrimitiveBaseShape.CreateBox(); Primitive.TextureEntry textureEntry = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); - - OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; for (uint face = 0; face < face_list.Count; face++) { OSDMap faceMap = (OSDMap)face_list[(int)face]; - Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face); + + Primitive.TextureEntryFace f = textureEntry.CreateFace(face); //clone the default if (faceMap.ContainsKey("fullbright")) f.Fullbright = faceMap["fullbright"].AsBoolean(); if (faceMap.ContainsKey("diffuse_color")) @@ -986,51 +995,11 @@ namespace OpenSim.Region.ClientStack.Linden if (textures.Count > textureNum) f.TextureID = textures[textureNum]; - else - f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE; - + textureEntry.FaceTextures[face] = f; } - pbs.TextureEntry = textureEntry.GetBytes(); - if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ... - { - int meshindx = inner_instance_list["mesh"].AsInteger(); - if (meshAssets.Count > meshindx) - { - pbs.SculptEntry = true; - pbs.SculptType = (byte)SculptType.Mesh; - pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction - // data will be requested from asset on rez (i hope) - } - } - - // faces number to pbs shape - switch(face_list.Count) - { - case 1: - case 2: - pbs.ProfileCurve = (byte)ProfileCurve.Circle; - pbs.PathCurve = (byte)PathCurve.Circle; - break; - - case 3: - case 4: - pbs.ProfileCurve = (byte)ProfileCurve.Circle; - pbs.PathCurve = (byte)PathCurve.Line; - break; - case 5: - pbs.ProfileCurve = (byte)ProfileCurve.EqualTriangle; - pbs.PathCurve = (byte)PathCurve.Line; - break; - - default: - pbs.ProfileCurve = (byte)ProfileCurve.Square; - pbs.PathCurve = (byte)PathCurve.Line; - break; - } - Vector3 position = inner_instance_list["position"].AsVector3(); Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs index 189fa36376..69fcb7d107 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs @@ -121,6 +121,9 @@ namespace OpenSim.Region.ClientStack.Linden OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]); + if (r.Type != OSDType.Map) // not a proper req + return responsedata; + //UUID session_id = UUID.Zero; bool bypass_raycast = false; uint everyone_mask = 0; @@ -157,9 +160,6 @@ namespace OpenSim.Region.ClientStack.Linden int state = 0; int lastattach = 0; - if (r.Type != OSDType.Map) // not a proper req - return responsedata; - OSDMap rm = (OSDMap)r; if (rm.ContainsKey("ObjectData")) //v2 @@ -307,8 +307,6 @@ namespace OpenSim.Region.ClientStack.Linden } } - - Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false); PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); @@ -359,6 +357,8 @@ namespace OpenSim.Region.ClientStack.Linden rootpart.NextOwnerMask = next_owner_mask; rootpart.Material = (byte)material; + obj.AggregatePerms(); + m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); responsedata["int_response_code"] = 200; //501; //410; //404; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index 6874662c07..116c51f5b3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -335,6 +335,7 @@ namespace OpenSim.Region.ClientStack.Linden grp.AbsolutePosition = obj.Position; prim.RotationOffset = obj.Rotation; + // Required for linking grp.RootPart.ClearUpdateSchedule(); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index df3466815b..cf96a8bbc1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3950,24 +3950,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Send an ObjectUpdate packet with information about an avatar /// - public void SendAvatarDataImmediate(ISceneEntity avatar) + public void SendEntityFullUpdateImmediate(ISceneEntity ent) { // m_log.DebugFormat( // "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", // avatar.Name, avatar.UUID, Name, AgentId); - ScenePresence presence = avatar as ScenePresence; - if (presence == null) + if (ent == null) return; ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); objupdate.Header.Zerocoded = true; - objupdate.RegionData.RegionHandle = presence.RegionHandle; -// objupdate.RegionData.TimeDilation = ushort.MaxValue; objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); + + if(ent is ScenePresence) + { + ScenePresence presence = ent as ScenePresence; + objupdate.RegionData.RegionHandle = presence.RegionHandle; + objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); + } + else if(ent is SceneObjectPart) + { + SceneObjectPart part = ent as SceneObjectPart; + objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); + } + + OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); + + // We need to record the avatar local id since the root prim of an attachment points to this. +// m_attachmentsSent.Add(avatar.LocalId); + } + + public void SendEntityTerseUpdateImmediate(ISceneEntity ent) + { +// m_log.DebugFormat( +// "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", +// avatar.Name, avatar.UUID, Name, AgentId); + + if (ent == null) + return; + + ImprovedTerseObjectUpdatePacket objupdate = + (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); + objupdate.Header.Zerocoded = true; + + objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); + objupdate.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; + + if(ent is ScenePresence) + { + ScenePresence presence = ent as ScenePresence; + objupdate.RegionData.RegionHandle = presence.RegionHandle; + objupdate.ObjectData[0] = CreateImprovedTerseBlock(ent, false); + } + else if(ent is SceneObjectPart) + { + SceneObjectPart part = ent as SceneObjectPart; + objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + objupdate.ObjectData[0] = CreateImprovedTerseBlock(ent, false); + } OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); @@ -4021,7 +4065,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Primitive Packet/Data Sending Methods - /// /// Generate one of the object update packets based on PrimUpdateFlags /// and broadcast the packet to clients @@ -4044,10 +4087,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP */ if (entity is SceneObjectPart) { - SceneObjectPart e = (SceneObjectPart)entity; - SceneObjectGroup g = e.ParentGroup; + SceneObjectPart p = (SceneObjectPart)entity; + SceneObjectGroup g = p.ParentGroup; if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId) return; // Don't send updates for other people's HUDs + + if((updateFlags ^ PrimUpdateFlags.SendInTransit) == 0) + { + List partIDs = (new List {p.LocalId}); + lock (m_entityProps.SyncRoot) + m_entityProps.Remove(partIDs); + lock (m_entityUpdates.SyncRoot) + m_entityUpdates.Remove(partIDs); + return; + } } //double priority = m_prioritizer.GetUpdatePriority(this, entity); @@ -4126,14 +4179,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Vector3 mycamera = Vector3.Zero; Vector3 mypos = Vector3.Zero; ScenePresence mysp = (ScenePresence)SceneAgent; - if(mysp != null && !mysp.IsDeleted) + + // we should have a presence + if(mysp == null) + return; + + if(doCulling) { cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; // mycamera = mysp.CameraPosition; mypos = mysp.AbsolutePosition; } - else - doCulling = false; while (maxUpdatesBytes > 0) { @@ -4154,9 +4210,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP { SceneObjectPart part = (SceneObjectPart)update.Entity; SceneObjectGroup grp = part.ParentGroup; - if (grp.inTransit) + if (grp.inTransit && !update.Flags.HasFlag(PrimUpdateFlags.SendInTransit)) continue; +/* debug + if (update.Flags.HasFlag(PrimUpdateFlags.SendInTransit)) + { + + } +*/ if (grp.IsDeleted) { // Don't send updates for objects that have been marked deleted. @@ -4213,14 +4275,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { part.Shape.LightEntry = false; } - - if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) - { - // Ensure that mesh has at least 8 valid faces - part.Shape.ProfileBegin = 12500; - part.Shape.ProfileEnd = 0; - part.Shape.ProfileHollow = 27500; - } } if(doCulling && !grp.IsAttachment) @@ -4248,14 +4302,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP continue; } } - - if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) - { - // Ensure that mesh has at least 8 valid faces - part.Shape.ProfileBegin = 12500; - part.Shape.ProfileEnd = 0; - part.Shape.ProfileHollow = 27500; - } } else if (update.Entity is ScenePresence) { @@ -4330,7 +4376,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (update.Entity is ScenePresence) ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); else - ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId); + ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp); objectUpdateBlocks.Add(ablock); objectUpdates.Value.Add(update); maxUpdatesBytes -= ablock.Length; @@ -4462,6 +4508,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } // hack.. dont use +/* public void SendPartFullUpdate(ISceneEntity ent, uint? parentID) { if (ent is SceneObjectPart) @@ -4472,7 +4519,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP packet.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, this.m_agentId); + ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, mysp); if (parentID.HasValue) { blk.ParentID = parentID.Value; @@ -4488,7 +4535,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name); // } - +*/ public void ReprioritizeUpdates() { lock (m_entityUpdates.SyncRoot) @@ -5726,28 +5773,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP return update; } - protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) +// protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) + protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) { byte[] objectData = new byte[60]; - data.RelativePosition.ToBytes(objectData, 0); - data.Velocity.ToBytes(objectData, 12); - data.Acceleration.ToBytes(objectData, 24); + part.RelativePosition.ToBytes(objectData, 0); + part.Velocity.ToBytes(objectData, 12); + part.Acceleration.ToBytes(objectData, 24); - Quaternion rotation = data.RotationOffset; + Quaternion rotation = part.RotationOffset; rotation.Normalize(); rotation.ToBytes(objectData, 36); - data.AngularVelocity.ToBytes(objectData, 48); + part.AngularVelocity.ToBytes(objectData, 48); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); - update.ClickAction = (byte)data.ClickAction; + update.ClickAction = (byte)part.ClickAction; update.CRC = 0; - update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes; - update.FullID = data.UUID; - update.ID = data.LocalId; + update.ExtraParams = part.Shape.ExtraParams ?? Utils.EmptyBytes; + update.FullID = part.UUID; + update.ID = part.LocalId; //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated //update.JointPivot = Vector3.Zero; //update.JointType = 0; - update.Material = data.Material; + update.Material = part.Material; update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim /* if (data.ParentGroup.IsAttachment) @@ -5776,68 +5824,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP } */ - if (data.ParentGroup.IsAttachment) + if (part.ParentGroup.IsAttachment) { - if (data.IsRoot) + if (part.IsRoot) { - update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID); + update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID); } else update.NameValue = Utils.EmptyBytes; - int st = (int)data.ParentGroup.AttachmentPoint; + int st = (int)part.ParentGroup.AttachmentPoint; update.State = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ; } else { update.NameValue = Utils.EmptyBytes; - update.State = data.Shape.State; // not sure about this + update.State = part.Shape.State; // not sure about this } update.ObjectData = objectData; - update.ParentID = data.ParentID; - update.PathBegin = data.Shape.PathBegin; - update.PathCurve = data.Shape.PathCurve; - update.PathEnd = data.Shape.PathEnd; - update.PathRadiusOffset = data.Shape.PathRadiusOffset; - update.PathRevolutions = data.Shape.PathRevolutions; - update.PathScaleX = data.Shape.PathScaleX; - update.PathScaleY = data.Shape.PathScaleY; - update.PathShearX = data.Shape.PathShearX; - update.PathShearY = data.Shape.PathShearY; - update.PathSkew = data.Shape.PathSkew; - update.PathTaperX = data.Shape.PathTaperX; - update.PathTaperY = data.Shape.PathTaperY; - update.PathTwist = data.Shape.PathTwist; - update.PathTwistBegin = data.Shape.PathTwistBegin; - update.PCode = data.Shape.PCode; - update.ProfileBegin = data.Shape.ProfileBegin; - update.ProfileCurve = data.Shape.ProfileCurve; - update.ProfileEnd = data.Shape.ProfileEnd; - update.ProfileHollow = data.Shape.ProfileHollow; - update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes; - update.TextColor = data.GetTextColor().GetBytes(false); - update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes; - update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; - update.Scale = data.Shape.Scale; - update.Text = Util.StringToBytes256(data.Text); - update.MediaURL = Util.StringToBytes256(data.MediaUrl); + update.ParentID = part.ParentID; + update.PathBegin = part.Shape.PathBegin; + update.PathCurve = part.Shape.PathCurve; + update.PathEnd = part.Shape.PathEnd; + update.PathRadiusOffset = part.Shape.PathRadiusOffset; + update.PathRevolutions = part.Shape.PathRevolutions; + update.PathScaleX = part.Shape.PathScaleX; + update.PathScaleY = part.Shape.PathScaleY; + update.PathShearX = part.Shape.PathShearX; + update.PathShearY = part.Shape.PathShearY; + update.PathSkew = part.Shape.PathSkew; + update.PathTaperX = part.Shape.PathTaperX; + update.PathTaperY = part.Shape.PathTaperY; + update.PathTwist = part.Shape.PathTwist; + update.PathTwistBegin = part.Shape.PathTwistBegin; + update.PCode = part.Shape.PCode; + update.ProfileBegin = part.Shape.ProfileBegin; + update.ProfileCurve = part.Shape.ProfileCurve; + + if(part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack + update.ProfileCurve = (byte)(part.Shape.ProfileCurve & 0x0f); + else + update.ProfileCurve = part.Shape.ProfileCurve; + + update.ProfileEnd = part.Shape.ProfileEnd; + update.ProfileHollow = part.Shape.ProfileHollow; + update.PSBlock = part.ParticleSystem ?? Utils.EmptyBytes; + update.TextColor = part.GetTextColor().GetBytes(false); + update.TextureAnim = part.TextureAnimation ?? Utils.EmptyBytes; + update.TextureEntry = part.Shape.TextureEntry ?? Utils.EmptyBytes; + update.Scale = part.Shape.Scale; + update.Text = Util.StringToBytes256(part.Text); + update.MediaURL = Util.StringToBytes256(part.MediaUrl); #region PrimFlags - PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID); + PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp); // Don't send the CreateSelected flag to everyone flags &= ~PrimFlags.CreateSelected; - if (recipientID == data.OwnerID) + if (sp.UUID == part.OwnerID) { - if (data.CreateSelected) + if (part.CreateSelected) { // Only send this flag once, then unset it flags |= PrimFlags.CreateSelected; - data.CreateSelected = false; + part.CreateSelected = false; } } @@ -5849,21 +5903,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion PrimFlags - if (data.Sound != UUID.Zero) + if (part.Sound != UUID.Zero) { - update.Sound = data.Sound; - update.OwnerID = data.OwnerID; - update.Gain = (float)data.SoundGain; - update.Radius = (float)data.SoundRadius; - update.Flags = data.SoundFlags; + update.Sound = part.Sound; + update.OwnerID = part.OwnerID; + update.Gain = (float)part.SoundGain; + update.Radius = (float)part.SoundRadius; + update.Flags = part.SoundFlags; } - switch ((PCode)data.Shape.PCode) + switch ((PCode)part.Shape.PCode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: - update.Data = new byte[] { data.Shape.State }; + update.Data = new byte[] { part.Shape.State }; break; default: update.Data = Utils.EmptyBytes; @@ -7753,10 +7807,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectDuplicate handlerObjectDuplicate = null; - for (int i = 0; i < dupe.ObjectData.Length; i++) + handlerObjectDuplicate = OnObjectDuplicate; + if (handlerObjectDuplicate != null) { - handlerObjectDuplicate = OnObjectDuplicate; - if (handlerObjectDuplicate != null) + for (int i = 0; i < dupe.ObjectData.Length; i++) { UUID rezGroupID = dupe.AgentData.GroupID; if(!IsGroupMember(rezGroupID)) diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 2242e421c4..6e4a710bf9 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs @@ -369,7 +369,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender else if (Cache != null) { string assetName = "j2kCache_" + AssetId.ToString(); - AssetBase layerDecodeAsset = Cache.Get(assetName); + AssetBase layerDecodeAsset; + Cache.Get(assetName, out layerDecodeAsset); if (layerDecodeAsset != null) { diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs index 23c1f035b8..403236c170 100644 --- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs @@ -260,10 +260,9 @@ namespace OpenSim.Region.CoreModules.Asset /// Cache doesn't guarantee in any situation that asset is stored to it. /// /// - public AssetBase Get(string id) + public bool Get(string id, out AssetBase assetBase) { m_getCount++; - AssetBase assetBase; if (m_cache.TryGetValue(id, out assetBase)) m_hitCount++; @@ -284,7 +283,7 @@ namespace OpenSim.Region.CoreModules.Asset // if (null == assetBase) // m_log.DebugFormat("[CENOME ASSET CACHE]: Asset {0} not in cache", id); - return assetBase; + return true; } #endregion diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs index 51fc3d1d7b..10c0e85175 100644 --- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs @@ -115,7 +115,10 @@ namespace OpenSim.Region.CoreModules.Asset public bool Check(string id) { // XXX This is probably not an efficient implementation. - return Get(id) != null; + AssetBase asset; + if (!Get(id, out asset)) + return false; + return asset != null; } public void Cache(AssetBase asset) @@ -129,9 +132,10 @@ namespace OpenSim.Region.CoreModules.Asset // We don't do negative caching } - public AssetBase Get(string id) + public bool Get(string id, out AssetBase asset) { - return (AssetBase)m_Cache.Get(id); + asset = (AssetBase)m_Cache.Get(id); + return true; } public void Expire(string id) diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 187f090ec5..610e279a24 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -474,6 +474,8 @@ namespace OpenSim.Region.CoreModules.Asset { using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { + if (stream.Length == 0) // Empty file will trigger exception below + return null; BinaryFormatter bformatter = new BinaryFormatter(); asset = (AssetBase)bformatter.Deserialize(stream); @@ -531,15 +533,26 @@ namespace OpenSim.Region.CoreModules.Asset return found; } + // For IAssetService public AssetBase Get(string id) { + AssetBase asset; + Get(id, out asset); + return asset; + } + + public bool Get(string id, out AssetBase asset) + { + asset = null; + m_Requests++; object dummy; if (m_negativeCache.TryGetValue(id, out dummy)) - return null; + { + return false; + } - AssetBase asset = null; asset = GetFromWeakReference(id); if (asset != null && m_updateFileTimeOnCacheHit) { @@ -578,13 +591,7 @@ namespace OpenSim.Region.CoreModules.Asset GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l)); } - if(asset == null) - { - - - } - - return asset; + return true; } public bool Check(string id) @@ -599,7 +606,9 @@ namespace OpenSim.Region.CoreModules.Asset public AssetBase GetCached(string id) { - return Get(id); + AssetBase asset; + Get(id, out asset); + return asset; } public void Expire(string id) @@ -797,6 +806,9 @@ namespace OpenSim.Region.CoreModules.Asset return; } + catch (UnauthorizedAccessException e) + { + } finally { if (stream != null) @@ -1227,19 +1239,23 @@ namespace OpenSim.Region.CoreModules.Asset public AssetMetadata GetMetadata(string id) { - AssetBase asset = Get(id); + AssetBase asset; + Get(id, out asset); return asset.Metadata; } public byte[] GetData(string id) { - AssetBase asset = Get(id); + AssetBase asset; + Get(id, out asset); return asset.Data; } public bool Get(string id, object sender, AssetRetrieved handler) { - AssetBase asset = Get(id); + AssetBase asset; + if (!Get(id, out asset)) + return false; handler(id, sender, asset); return true; } @@ -1270,7 +1286,9 @@ namespace OpenSim.Region.CoreModules.Asset public bool UpdateContent(string id, byte[] data) { - AssetBase asset = Get(id); + AssetBase asset; + if (!Get(id, out asset)) + return false; asset.Data = data; Cache(asset); return true; diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs index 208963d1f4..abe9b23770 100644 --- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs @@ -131,14 +131,15 @@ namespace OpenSim.Region.CoreModules.Asset // We don't do negative caching } - public AssetBase Get(string id) + public bool Get(string id, out AssetBase asset) { - Object asset = null; - m_Cache.TryGet(id, out asset); + Object a = null; + m_Cache.TryGet(id, out a); - Debug(asset); + Debug(a); - return (AssetBase)asset; + asset = (AssetBase)a; + return true; } public void Expire(string id) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 8b8ac20c4d..cf188aacd3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -481,14 +481,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", // group.Name, group.LocalId, sp.Name, attachmentPt, silent); - if (sp.GetAttachments().Contains(group)) - { -// m_log.WarnFormat( -// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", -// group.Name, group.LocalId, sp.Name, AttachmentPt); - - return false; - } if (group.GetSittingAvatarsCount() != 0) { @@ -500,6 +492,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return false; } + List attachments = sp.GetAttachments(attachmentPt); + if (attachments.Contains(group)) + { +// if (DebugLevel > 0) +// m_log.WarnFormat( +// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", +// group.Name, group.LocalId, sp.Name, attachmentPt); + + return false; + } + Vector3 attachPos = group.AbsolutePosition; // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should @@ -533,7 +536,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint; attachPos = group.RootPart.AttachedPos; - group.HasGroupChanged = true; } // if we still didn't find a suitable attachment point....... @@ -544,18 +546,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments attachPos = Vector3.Zero; } - List attachments = sp.GetAttachments(attachmentPt); - - if (attachments.Contains(group)) - { - if (DebugLevel > 0) - m_log.WarnFormat( - "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", - group.Name, group.LocalId, sp.Name, attachmentPt); - - return false; - } - // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones while (attachments.Count >= 5) { @@ -579,7 +569,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments lock (sp.AttachmentsSyncLock) { group.AttachmentPoint = attachmentPt; - group.AbsolutePosition = attachPos; + group.RootPart.AttachedPos = attachPos; if (addToInventory && sp.PresenceType != PresenceType.Npc) UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); @@ -956,7 +946,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.DeleteFromStorage(so.UUID); m_scene.EventManager.TriggerParcelPrimCountTainted(); - so.AttachedAvatar = sp.UUID; foreach (SceneObjectPart part in so.Parts) { @@ -969,11 +958,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - so.AbsolutePosition = attachOffset; - so.RootPart.AttachedPos = attachOffset; - so.IsAttachment = true; so.RootPart.SetParentLocalId(sp.LocalId); + so.AttachedAvatar = sp.UUID; so.AttachmentPoint = attachmentpoint; + so.RootPart.AttachedPos = attachOffset; + so.AbsolutePosition = attachOffset; + so.IsAttachment = true; sp.AddAttachment(so); @@ -1322,7 +1312,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (part == null) return; - if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) + SceneObjectGroup group = part.ParentGroup; + + if (!m_scene.Permissions.CanTakeObject(group, sp)) { remoteClient.SendAgentAlertMessage( "You don't have sufficient permissions to attach this object", false); @@ -1334,7 +1326,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments AttachmentPt &= 0x7f; // Calls attach with a Zero position - SceneObjectGroup group = part.ParentGroup; if (AttachObject(sp, group , AttachmentPt, false, true, append)) { if (DebugLevel > 0) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index fb408a402d..535d946710 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -299,7 +299,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (bakedTextureFace == null) continue; - AssetBase asset = cache.Get(bakedTextureFace.TextureID.ToString()); + AssetBase asset; + cache.Get(bakedTextureFace.TextureID.ToString(), out asset); if (asset != null && asset.Local) { diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index d1f6054106..315ce1b072 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private bool enabled = true; + private bool m_UseNewAvnCode = false; private List m_SceneList = new List(); private string m_RestURL = String.Empty; IMessageTransferModule m_TransferModule = null; @@ -82,6 +83,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages); + m_UseNewAvnCode = cnf.GetBoolean("UseNewAvnCode", m_UseNewAvnCode); } public void AddRegion(Scene scene) @@ -244,68 +246,73 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage return; } - Scene scene = FindScene(new UUID(im.fromAgentID)); - if (scene == null) - scene = m_SceneList[0]; - -// Avination new code -// SendReply reply = SynchronousRestObjectRequester.MakeRequest( -// "POST", m_RestURL+"/SaveMessage/?scope=" + -// scene.RegionInfo.ScopeID.ToString(), im); - -// current opensim and osgrid compatible - bool success = SynchronousRestObjectRequester.MakeRequest( - "POST", m_RestURL+"/SaveMessage/", im, 10000); -// current opensim and osgrid compatible end - - if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) + if(m_UseNewAvnCode) { - IClientAPI client = FindClient(new UUID(im.fromAgentID)); - if (client == null) - return; -/* Avination new code - if (reply.Message == String.Empty) - reply.Message = "User is not logged in. " + (reply.Success ? "Message saved." : "Message not saved"); + Scene scene = FindScene(new UUID(im.fromAgentID)); + if (scene == null) + scene = m_SceneList[0]; - bool sendReply = true; + UUID scopeID = scene.RegionInfo.ScopeID; + SendReply reply = SynchronousRestObjectRequester.MakeRequest( + "POST", m_RestURL+"/SaveMessage/?scope=" + scopeID.ToString(), im, 20000); - switch (reply.Disposition) + if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) { - case 0: // Normal - break; - case 1: // Only once per user - if (m_repliesSent.ContainsKey(client) && m_repliesSent[client].Contains(new UUID(im.toAgentID))) + IClientAPI client = FindClient(new UUID(im.fromAgentID)); + if (client == null) + return; + + if (string.IsNullOrEmpty(reply.Message)) + reply.Message = "User is not logged in. " + (reply.Success ? "Message saved." : "Message not saved"); + + bool sendReply = true; + + switch (reply.Disposition) { - sendReply = false; + case 0: // Normal + break; + case 1: // Only once per user + if (m_repliesSent.ContainsKey(client) && m_repliesSent[client].Contains(new UUID(im.toAgentID))) + sendReply = false; + else + { + if (!m_repliesSent.ContainsKey(client)) + m_repliesSent[client] = new List(); + m_repliesSent[client].Add(new UUID(im.toAgentID)); + } + break; } - else + + if (sendReply) { - if (!m_repliesSent.ContainsKey(client)) - m_repliesSent[client] = new List(); - m_repliesSent[client].Add(new UUID(im.toAgentID)); + client.SendInstantMessage(new GridInstantMessage( + null, new UUID(im.toAgentID), + "System", new UUID(im.fromAgentID), + (byte)InstantMessageDialog.MessageFromAgent, + reply.Message, + false, new Vector3())); } - break; } + } + else + { + bool success = SynchronousRestObjectRequester.MakeRequest( + "POST", m_RestURL+"/SaveMessage/", im, 20000); - if (sendReply) + if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) { + IClientAPI client = FindClient(new UUID(im.fromAgentID)); + if (client == null) + return; + client.SendInstantMessage(new GridInstantMessage( - null, new UUID(im.toAgentID), - "System", new UUID(im.fromAgentID), - (byte)InstantMessageDialog.MessageFromAgent, - reply.Message, - false, new Vector3())); - } -*/ -// current opensim and osgrid compatible - client.SendInstantMessage(new GridInstantMessage( null, new UUID(im.toAgentID), "System", new UUID(im.fromAgentID), (byte)InstantMessageDialog.MessageFromAgent, "User is not logged in. "+ (success ? "Message saved." : "Message not saved"), false, new Vector3())); -// current opensim and osgrid compatible end + } } } } diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index bc8aeca002..89e30206f1 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles if (profileConfig == null) { - m_log.Debug("[PROFILES]: UserProfiles disabled, no configuration"); + //m_log.Debug("[PROFILES]: UserProfiles disabled, no configuration"); Enabled = false; return; } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 6dc982be3c..87b76dc30b 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1703,11 +1703,81 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return agent; } + public bool CrossAgentCreateFarChild(ScenePresence agent, GridRegion neighbourRegion, Vector3 pos, EntityTransferContext ctx) + { + ulong regionhandler = neighbourRegion.RegionHandle; + + if(agent.knowsNeighbourRegion(regionhandler)) + return true; + + string reason; + ulong currentRegionHandler = agent.Scene.RegionInfo.RegionHandle; + GridRegion source = new GridRegion(agent.Scene.RegionInfo); + + AgentCircuitData currentAgentCircuit = + agent.Scene.AuthenticateHandler.GetAgentCircuitData(agent.ControllingClient.CircuitCode); + AgentCircuitData agentCircuit = agent.ControllingClient.RequestClientInfo(); + agentCircuit.startpos = pos; + agentCircuit.child = true; + + agentCircuit.Appearance = new AvatarAppearance(); + agentCircuit.Appearance.AvatarHeight = agent.Appearance.AvatarHeight; + + if (currentAgentCircuit != null) + { + agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; + agentCircuit.IPAddress = currentAgentCircuit.IPAddress; + agentCircuit.Viewer = currentAgentCircuit.Viewer; + agentCircuit.Channel = currentAgentCircuit.Channel; + agentCircuit.Mac = currentAgentCircuit.Mac; + agentCircuit.Id0 = currentAgentCircuit.Id0; + } + + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + agent.AddNeighbourRegion(neighbourRegion, agentCircuit.CapsPath); + + IPEndPoint endPoint = neighbourRegion.ExternalEndPoint; + if (Scene.SimulationService.CreateAgent(source, neighbourRegion, agentCircuit, (int)TeleportFlags.Default, ctx, out reason)) + { + string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + int newSizeX = neighbourRegion.RegionSizeX; + int newSizeY = neighbourRegion.RegionSizeY; + + if (m_eqModule != null) + { + #region IP Translation for NAT + IClientIPEndpoint ipepClient; + if (agent.ClientView.TryGet(out ipepClient)) + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + + m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + + "and EstablishAgentCommunication with seed cap {8}", LogHeader, + source.RegionName, agent.Name, + neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, newSizeX, newSizeY , capsPath); + + m_eqModule.EnableSimulator(regionhandler, + endPoint, agent.UUID, newSizeX, newSizeY); + m_eqModule.EstablishAgentCommunication(agent.UUID, endPoint, capsPath, + regionhandler, newSizeX, newSizeY); + } + else + { + agent.ControllingClient.InformClientOfNeighbour(regionhandler, endPoint); + } + return true; + } + agent.RemoveNeighbourRegion(regionhandler); + return false; + } + public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx) { int ts = Util.EnvironmentTickCount(); + bool sucess = true; + string reason = String.Empty; try { + AgentData cAgent = new AgentData(); agent.CopyTo(cAgent,true); @@ -1725,18 +1795,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Beyond this point, extra cleanup is needed beyond removing transit state m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); - if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx)) + if (sucess && !agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx)) + { + sucess = false; + reason = "agent update failed"; + } + + if(!sucess) { // region doesn't take it m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.", - neighbourRegion.RegionName, agent.Name); + "[ENTITY TRANSFER MODULE]: agent {0} crossing to {1} failed: {2}", + agent.Name, neighbourRegion.RegionName, reason); ReInstantiateScripts(agent); if(agent.ParentID == 0 && agent.ParentUUID == UUID.Zero) + { agent.AddToPhysicalScene(isFlying); + } return false; } @@ -1777,7 +1855,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); - Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); + Vector3 vel2 = Vector3.Zero; + if((agent.crossingFlags & 2) != 0) + vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); if (m_eqModule != null) { @@ -1804,7 +1884,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // this may need the attachments - agent.HasMovedAway(true); + agent.HasMovedAway((agent.crossingFlags & 8) == 0); agent.MakeChildAgent(neighbourRegion.RegionHandle); @@ -2135,7 +2215,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY, 0f); } - + #endregion #region NotFoundLocationCache class // A collection of not found locations to make future lookups 'not found' lookups quick. @@ -2620,7 +2700,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { // FIXME: It would be better to never add the scene object at all rather than add it and then delete // it - if (!Scene.Permissions.CanObjectEntry(so.UUID, true, so.AbsolutePosition)) + if (!Scene.Permissions.CanObjectEntry(so, true, so.AbsolutePosition)) { // Deny non attachments based on parcel settings // diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 95e7456d3f..ba3a7c9062 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -541,16 +541,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess #region Permissions - private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene) + private bool CanTakeObject(SceneObjectGroup sog, ScenePresence sp) { if (m_bypassPermissions) return true; - if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer)) - { - SceneObjectGroup sog = null; - if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer) - return true; + if(sp == null || sog == null) + return false; + if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(sp.UUID)) + { + if (sog.OwnerID == sp.UUID) + return true; return false; } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 010482374c..67c847b21d 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -427,20 +427,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess originalRotations[objectGroup.UUID] = inventoryStoredRotation; // Restore attachment data after trip through the sim - if (objectGroup.RootPart.AttachPoint > 0) + if (objectGroup.AttachmentPoint > 0) { inventoryStoredPosition = objectGroup.RootPart.AttachedPos; inventoryStoredRotation = objectGroup.RootPart.AttachRotation; - } + if (objectGroup.RootPart.Shape.PCode != (byte) PCode.Tree && + objectGroup.RootPart.Shape.PCode != (byte) PCode.NewTree) + objectGroup.RootPart.Shape.LastAttachPoint = (byte)objectGroup.AttachmentPoint; - // Trees could be attached and it's been done, but it makes - // no sense. State must be preserved because it's the tree type - if (objectGroup.RootPart.Shape.PCode != (byte) PCode.Tree && - objectGroup.RootPart.Shape.PCode != (byte) PCode.NewTree) - { - objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; - if (objectGroup.RootPart.AttachPoint > 0) - objectGroup.RootPart.Shape.LastAttachPoint = objectGroup.RootPart.AttachPoint; } objectGroup.AbsolutePosition = inventoryStoredPosition; @@ -605,15 +599,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess perms &= ~(uint)PermissionMask.Transfer; if ((nextPerms & (uint)PermissionMask.Modify) == 0) perms &= ~(uint)PermissionMask.Modify; - - item.BasePermissions = perms & so.RootPart.NextOwnerMask; + +// item.BasePermissions = perms & so.RootPart.NextOwnerMask; + + uint nextp = so.RootPart.NextOwnerMask | (uint)PermissionMask.FoldedMask; + item.BasePermissions = perms & nextp; item.CurrentPermissions = item.BasePermissions; item.NextPermissions = perms & so.RootPart.NextOwnerMask; item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; // apply next owner perms on rez - item.CurrentPermissions |= SceneObjectGroup.SLAM; + item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; } else { @@ -1124,7 +1121,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // rootPart.OwnerID, item.Owner, item.CurrentPermissions); if ((rootPart.OwnerID != item.Owner) || - (item.CurrentPermissions & 16) != 0 || + (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) { //Need to kill the for sale here @@ -1136,32 +1133,48 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess foreach (SceneObjectPart part in so.Parts) { part.GroupMask = 0; // DO NOT propagate here - - part.LastOwnerID = part.OwnerID; + if( part.OwnerID != part.GroupID) + part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.RezzerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); - // This applies the base mask from the item as the next - // permissions for the object. This is correct because the - // giver's base mask was masked by the giver's next owner - // mask, so the base mask equals the original next owner mask. - part.NextOwnerMask = item.BasePermissions; + // Reconstruct the original item's base permissions. They + // can be found in the lower (folded) bits. + if ((item.BasePermissions & (uint)PermissionMask.FoldedMask) != 0) + { + // We have permissions stored there so use them + part.NextOwnerMask = ((item.BasePermissions & 7) << 13); + if ((item.BasePermissions & (uint)PermissionMask.FoldedExport) != 0) + part.NextOwnerMask |= (uint)PermissionMask.Export; + part.NextOwnerMask |= (uint)PermissionMask.Move; + } + else + { + // This is a legacy object and we can't avoid the issues that + // caused perms loss or escalation before, treat it the legacy + // way. + part.NextOwnerMask = item.NextPermissions; + } } so.ApplyNextOwnerPermissions(); // In case the user has changed flags on a received item // we have to apply those changes after the slam. Else we - // get a net loss of permissions + // get a net loss of permissions. + // On legacy objects, this opts for a loss of permissions rather + // than the previous handling that allowed escalation. foreach (SceneObjectPart part in so.Parts) { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { + part.GroupMask = item.GroupPermissions & part.BaseMask; part.EveryoneMask = item.EveryOnePermissions & part.BaseMask; part.NextOwnerMask = item.NextPermissions & part.BaseMask; } } + } } else @@ -1180,6 +1193,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } rootPart.TrimPermissions(); + so.AggregateDeepPerms(); if (isAttachment) so.FromItemID = item.ID; diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 51f973a4c0..32cb5a383a 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -957,9 +957,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public virtual bool IsLocalGridUser(UUID uuid) { - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid); - if (account == null || (account != null && !account.LocalToGrid)) - return false; + lock (m_Scenes) + { + if (m_Scenes.Count == 0) + return true; + UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid); + if (account == null || (account != null && !account.LocalToGrid)) + return false; + } return true; } diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 3f332fae29..290daa9b20 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -83,17 +83,17 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); - private Dictionary m_RequestMap = + protected Dictionary m_RequestMap = new Dictionary(); - private Dictionary m_UrlMap = + protected Dictionary m_UrlMap = new Dictionary(); - private uint m_HttpsPort = 0; - private IHttpServer m_HttpServer = null; - private IHttpServer m_HttpsServer = null; + protected uint m_HttpsPort = 0; + protected IHttpServer m_HttpServer = null; + protected IHttpServer m_HttpsServer = null; - public string ExternalHostNameForLSL { get; private set; } + public string ExternalHostNameForLSL { get; protected set; } /// /// The default maximum number of urls @@ -107,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public Type ReplaceableInterface { - get { return null; } + get { return typeof(IUrlModule); } } public string Name @@ -453,7 +453,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } - private void RemoveUrl(UrlData data) + protected void RemoveUrl(UrlData data) { if (data.isSsl) m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/"); @@ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/"); } - private Hashtable NoEvents(UUID requestID, UUID sessionID) + protected Hashtable NoEvents(UUID requestID, UUID sessionID) { Hashtable response = new Hashtable(); UrlData url; @@ -499,7 +499,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp return response; } - private bool HasEvents(UUID requestID, UUID sessionID) + protected bool HasEvents(UUID requestID, UUID sessionID) { UrlData url=null; @@ -531,7 +531,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } } - private void Drop(UUID requestID, UUID sessionID) + protected void Drop(UUID requestID, UUID sessionID) { UrlData url = null; lock (m_RequestMap) @@ -552,7 +552,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } } - private Hashtable GetEvents(UUID requestID, UUID sessionID) + protected Hashtable GetEvents(UUID requestID, UUID sessionID) { UrlData url = null; RequestData requestData = null; @@ -757,7 +757,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } } - private void OnScriptReset(uint localID, UUID itemID) + protected void OnScriptReset(uint localID, UUID itemID) { ScriptRemoved(itemID); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs index 9e75ee2259..2e6f472399 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs @@ -85,12 +85,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile public LocalUserProfilesServicesConnector() { - m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector no params"); + //m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector no params"); } public LocalUserProfilesServicesConnector(IConfigSource source) { - m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector instantiated directly."); + //m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector instantiated directly."); InitialiseService(source); } @@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile IConfig config = source.Configs[ConfigName]; if (config == null) { - m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: UserProfilesService missing from OpenSim.ini"); + //m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: UserProfilesService missing from OpenSim.ini"); return; } @@ -225,4 +225,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile } #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index f5aa9716d9..92ae36fbb6 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs @@ -209,7 +209,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset if (m_Cache != null) { - asset = m_Cache.Get(id); + if (!m_Cache.Get(id, out asset)) + return null; if (asset != null) return asset; @@ -238,10 +239,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset public AssetBase GetCached(string id) { + AssetBase asset = null; if (m_Cache != null) - return m_Cache.Get(id); + m_Cache.Get(id, out asset); - return null; + return asset; } public AssetMetadata GetMetadata(string id) @@ -250,8 +252,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset if (m_Cache != null) { - if (m_Cache != null) - m_Cache.Get(id); + if (!m_Cache.Get(id, out asset)) + return null; if (asset != null) return asset.Metadata; @@ -273,8 +275,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset if (m_Cache != null) { - if (m_Cache != null) - m_Cache.Get(id); + if (!m_Cache.Get(id, out asset)) + return null; if (asset != null) return asset.Data; @@ -292,7 +294,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset AssetBase asset = null; if (m_Cache != null) - asset = m_Cache.Get(id); + { + if (!m_Cache.Get(id, out asset)) + return false; + } if (asset != null) { @@ -382,7 +387,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset AssetBase asset = null; if (m_Cache != null) - asset = m_Cache.Get(id); + m_Cache.Get(id, out asset); if (asset != null) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs index 7190aa09ed..37a48bb752 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs @@ -158,7 +158,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset AssetBase asset = null; if (m_Cache != null) - asset = m_Cache.Get(id); + { + if (!m_Cache.Get(id, out asset)) + return null; + } if (asset == null) { @@ -177,17 +180,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset { // m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Cache request for {0}", id); + AssetBase asset = null; if (m_Cache != null) - return m_Cache.Get(id); + m_Cache.Get(id, out asset); - return null; + return asset; } public AssetMetadata GetMetadata(string id) { AssetBase asset = null; if (m_Cache != null) - asset = m_Cache.Get(id); + { + if (!m_Cache.Get(id, out asset)) + return null; + } if (asset != null) return asset.Metadata; @@ -210,7 +217,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset AssetBase asset = null; if (m_Cache != null) - asset = m_Cache.Get(id); + { + if (!m_Cache.Get(id, out asset)) + return null; + } if (asset != null) return asset.Data; @@ -232,7 +242,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset if (m_Cache != null) { - AssetBase asset = m_Cache.Get(id); + AssetBase asset; + if (!m_Cache.Get(id, out asset)) + return false; if (asset != null) { @@ -287,7 +299,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset { AssetBase asset = null; if (m_Cache != null) - m_Cache.Get(id); + m_Cache.Get(id, out asset); if (asset != null) { asset.Data = data; diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 5d12f8b31a..53b9796f63 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -149,9 +149,11 @@ namespace OpenSim.Region.CoreModules.World.Land parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0); + m_scene.EventManager.OnObjectAddedToScene += EventManagerOnParcelPrimCountAdd; m_scene.EventManager.OnParcelPrimCountAdd += EventManagerOnParcelPrimCountAdd; - m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate; + m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene; + m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate; m_scene.EventManager.OnRequestParcelPrimCountUpdate += EventManagerOnRequestParcelPrimCountUpdate; m_scene.EventManager.OnAvatarEnteringNewParcel += EventManagerOnAvatarEnteringNewParcel; @@ -287,8 +289,10 @@ namespace OpenSim.Region.CoreModules.World.Land fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY)); - fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; - fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); + LandData ldata = fullSimParcel.LandData; + ldata.SimwideArea = ldata.Area; + ldata.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; + ldata.ClaimDate = Util.UnixTimeSinceEpoch(); return AddLandObject(fullSimParcel); } @@ -813,6 +817,9 @@ namespace OpenSim.Region.CoreModules.World.Land throw new Exception("Error: Parcel not found at point " + x + ", " + y); } + if(m_landList.Count == 0 || m_landIDList == null) + return null; + lock (m_landIDList) { try @@ -824,8 +831,6 @@ namespace OpenSim.Region.CoreModules.World.Land return null; } } - - return m_landList[m_landIDList[x / 4, y / 4]]; } // Create a 'parcel is here' bitmap for the parcel identified by the passed landID @@ -1576,6 +1581,7 @@ namespace OpenSim.Region.CoreModules.World.Land } } } + FinalizeLandPrimCountUpdate(); // update simarea information } } @@ -1640,9 +1646,9 @@ namespace OpenSim.Region.CoreModules.World.Land foreach (HashSet objs in returns.Values) { List objs2 = new List(objs); - if (m_scene.Permissions.CanReturnObjects(null, remoteClient.AgentId, objs2)) + if (m_scene.Permissions.CanReturnObjects(null, remoteClient, objs2)) { - m_scene.returnObjects(objs2.ToArray(), remoteClient.AgentId); + m_scene.returnObjects(objs2.ToArray(), remoteClient); } else { @@ -2035,7 +2041,7 @@ namespace OpenSim.Region.CoreModules.World.Land { SceneObjectGroup[] objs = new SceneObjectGroup[1]; objs[0] = obj; - ((Scene)client.Scene).returnObjects(objs, client.AgentId); + ((Scene)client.Scene).returnObjects(objs, client); } Dictionary Timers = new Dictionary(); diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 73b4cb57a0..2b5cb31eeb 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -356,6 +356,7 @@ namespace OpenSim.Region.CoreModules.World.Land } } + // the total prims a parcel owner can have on a region public int GetSimulatorMaxPrimCount() { if (overrideSimulatorMaxPrimCount != null) @@ -370,7 +371,7 @@ namespace OpenSim.Region.CoreModules.World.Land * (double)m_scene.RegionInfo.RegionSettings.ObjectBonus / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) +0.5 ); - + // sanity check if(simMax > m_scene.RegionInfo.ObjectCapacity) simMax = m_scene.RegionInfo.ObjectCapacity; //m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}, SimWidePrims {3}", @@ -1043,7 +1044,8 @@ namespace OpenSim.Region.CoreModules.World.Land else LandData.AABBMax = new Vector3(tx, ty, (float)m_scene.Heightmap[tx - 1, ty - 1]); - LandData.Area = tempArea * landUnit * landUnit; + tempArea *= landUnit * landUnit; + LandData.Area = tempArea; } #endregion @@ -1647,8 +1649,7 @@ namespace OpenSim.Region.CoreModules.World.Land { foreach (SceneObjectGroup obj in primsOverMe) { - if (obj.OwnerID == previousOwner && obj.GroupID == UUID.Zero && - (obj.GetEffectivePermissions() & (uint)(OpenSim.Framework.PermissionMask.Transfer)) != 0) + if(m_scene.Permissions.CanSellObject(previousOwner,obj, (byte)SaleType.Original)) m_BuySellModule.BuyObject(sp.ControllingClient, UUID.Zero, obj.LocalId, 1, 0); } } @@ -1662,7 +1663,7 @@ namespace OpenSim.Region.CoreModules.World.Land { SceneObjectGroup[] objs = new SceneObjectGroup[1]; objs[0] = obj; - m_scene.returnObjects(objs, obj.OwnerID); + m_scene.returnObjects(objs, null); } public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) @@ -1693,6 +1694,8 @@ namespace OpenSim.Region.CoreModules.World.Land { if (obj.GroupID == LandData.GroupID) { + if (obj.OwnerID == LandData.OwnerID) + continue; if (!returns.ContainsKey(obj.OwnerID)) returns[obj.OwnerID] = new List(); @@ -1734,8 +1737,8 @@ namespace OpenSim.Region.CoreModules.World.Land foreach (List ol in returns.Values) { - if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) - m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); + if (m_scene.Permissions.CanReturnObjects(this, remote_client, ol)) + m_scene.returnObjects(ol.ToArray(), remote_client); } } diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index 857f919a06..2a720db660 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs @@ -92,10 +92,8 @@ namespace OpenSim.Region.CoreModules.World.Land m_Scene.RegisterModuleInterface(this); m_Scene.EventManager.OnObjectAddedToScene += OnParcelPrimCountAdd; - m_Scene.EventManager.OnObjectBeingRemovedFromScene += - OnObjectBeingRemovedFromScene; - m_Scene.EventManager.OnParcelPrimCountTainted += - OnParcelPrimCountTainted; + m_Scene.EventManager.OnObjectBeingRemovedFromScene += OnObjectBeingRemovedFromScene; + m_Scene.EventManager.OnParcelPrimCountTainted += OnParcelPrimCountTainted; m_Scene.EventManager.OnLandObjectAdded += delegate(ILandObject lo) { OnParcelPrimCountTainted(); }; } @@ -215,29 +213,15 @@ namespace OpenSim.Region.CoreModules.World.Land else parcelCounts.Users[obj.OwnerID] = partCount; - if (obj.IsSelected) - { + if (obj.IsSelected || obj.GetSittingAvatarsCount() > 0) parcelCounts.Selected += partCount; - } + + if (obj.OwnerID == landData.OwnerID) + parcelCounts.Owner += partCount; + else if (landData.GroupID != UUID.Zero && obj.GroupID == landData.GroupID) + parcelCounts.Group += partCount; else - { - if (landData.IsGroupOwned) - { - if (obj.OwnerID == landData.GroupID) - parcelCounts.Owner += partCount; - else if (landData.GroupID != UUID.Zero && obj.GroupID == landData.GroupID) - parcelCounts.Group += partCount; - else - parcelCounts.Others += partCount; - } - else - { - if (obj.OwnerID == landData.OwnerID) - parcelCounts.Owner += partCount; - else - parcelCounts.Others += partCount; - } - } + parcelCounts.Others += partCount; } } @@ -393,7 +377,6 @@ namespace OpenSim.Region.CoreModules.World.Land count = counts.Owner; count += counts.Group; count += counts.Others; - count += counts.Selected; } } diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index 0d8ece7cdf..a349aa1be5 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs @@ -151,7 +151,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01); m_scene.AddNewSceneObject(sog, false); - m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, 0, m_userId, UUID.Zero, Quaternion.Identity); + m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, m_userId, UUID.Zero, Quaternion.Identity, false); Assert.That(pc.Owner, Is.EqualTo(6)); Assert.That(pc.Group, Is.EqualTo(0)); diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index 283735889f..90d65c7101 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs @@ -89,28 +89,23 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell if (part == null) return; - if (part.ParentGroup.IsDeleted) + SceneObjectGroup sog = part.ParentGroup; + if (sog == null || sog.IsDeleted) return; - if (part.OwnerID != part.GroupID && part.OwnerID != client.AgentId && (!m_scene.Permissions.IsGod(client.AgentId))) - return; - - if (part.OwnerID == part.GroupID) // Group owned + // Does the user have the power to put the object on sale? + if (!m_scene.Permissions.CanSellObject(client, sog, saleType)) { - // Does the user have the power to put the object on sale? - if (!m_scene.Permissions.CanSellGroupObject(client.AgentId, part.GroupID, m_scene)) - { - client.SendAgentAlertMessage("You don't have permission to set group-owned objects on sale", false); - return; - } + client.SendAgentAlertMessage("You don't have permission to set object on sale", false); + return; } - part = part.ParentGroup.RootPart; + part = sog.RootPart; part.ObjectSaleType = saleType; part.SalePrice = salePrice; - part.ParentGroup.HasGroupChanged = true; + sog.HasGroupChanged = true; part.SendPropertiesToClient(client); } @@ -127,7 +122,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell switch (saleType) { case 1: // Sell as original (in-place sale) - uint effectivePerms = group.GetEffectivePermissions(); + uint effectivePerms = group.EffectiveOwnerPerms; if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) { @@ -136,8 +131,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell return false; } - group.SetOwnerId(remoteClient.AgentId); - group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); + group.SetOwner(remoteClient.AgentId, remoteClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { @@ -147,6 +141,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } + group.AggregatePerms(); } part.ObjectSaleType = 0; @@ -174,7 +169,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); group.AbsolutePosition = originalPosition; - uint perms = group.GetEffectivePermissions(); + uint perms = group.EffectiveOwnerPerms; if ((perms & (uint)PermissionMask.Transfer) == 0) { diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 75d90f363f..8eee8640ab 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -49,6 +49,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; + protected ScenePermissions scenePermissions; protected bool m_Enabled; private InventoryFolderImpl m_libraryRootFolder; @@ -69,15 +70,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions } #region Constants - // These are here for testing. They will be taken out - - //private uint PERM_ALL = (uint)2147483647; - private uint PERM_COPY = (uint)32768; - //private uint PERM_MODIFY = (uint)16384; - private uint PERM_MOVE = (uint)524288; - private uint PERM_TRANS = (uint)8192; - private uint PERM_LOCKED = (uint)540672; - /// /// Different user set names that come in from the configuration file. /// @@ -96,14 +88,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions private bool m_bypassPermissionsValue = true; private bool m_propagatePermissions = false; private bool m_debugPermissions = false; - private bool m_allowGridGods = false; - private bool m_RegionOwnerIsGod = false; - private bool m_RegionManagerIsGod = false; - private bool m_forceGridGodsOnly; - private bool m_forceGodModeAlwaysOn; - private bool m_allowGodActionsWithoutGodMode; - - private bool m_SimpleBuildPermissions = false; + private bool m_allowGridAdmins = false; + private bool m_RegionOwnerIsAdmin = false; + private bool m_RegionManagerIsAdmin = false; + private bool m_forceGridAdminsOnly; + private bool m_forceAdminModeAlwaysOn; + private bool m_allowAdminActionsWithoutGodMode; /// /// The set of users that are allowed to create scripts. This is only active if permissions are not being @@ -172,25 +162,23 @@ namespace OpenSim.Region.CoreModules.World.Permissions string[] sections = new string[] { "Startup", "Permissions" }; - m_allowGridGods = Util.GetConfigVarFromSections(config, "allow_grid_gods", sections, false); + m_allowGridAdmins = Util.GetConfigVarFromSections(config, "allow_grid_gods", sections, false); m_bypassPermissions = !Util.GetConfigVarFromSections(config, "serverside_object_permissions", sections, true); m_propagatePermissions = Util.GetConfigVarFromSections(config, "propagate_permissions", sections, true); - m_forceGridGodsOnly = Util.GetConfigVarFromSections(config, "force_grid_gods_only", sections, false); - if(!m_forceGridGodsOnly) + m_forceGridAdminsOnly = Util.GetConfigVarFromSections(config, "force_grid_gods_only", sections, false); + if(!m_forceGridAdminsOnly) { - m_RegionOwnerIsGod = Util.GetConfigVarFromSections(config, "region_owner_is_god",sections, true); - m_RegionManagerIsGod = Util.GetConfigVarFromSections(config, "region_manager_is_god",sections, false); + m_RegionOwnerIsAdmin = Util.GetConfigVarFromSections(config, "region_owner_is_god",sections, true); + m_RegionManagerIsAdmin = Util.GetConfigVarFromSections(config, "region_manager_is_god",sections, false); } else - m_allowGridGods = true; + m_allowGridAdmins = true; - m_forceGodModeAlwaysOn = Util.GetConfigVarFromSections(config, "automatic_gods", sections, false); - m_allowGodActionsWithoutGodMode = Util.GetConfigVarFromSections(config, "implicit_gods", sections, false); - if(m_allowGodActionsWithoutGodMode) - m_forceGodModeAlwaysOn = false; - - m_SimpleBuildPermissions = Util.GetConfigVarFromSections(config, "simple_build_permissions",sections, false); + m_forceAdminModeAlwaysOn = Util.GetConfigVarFromSections(config, "automatic_gods", sections, false); + m_allowAdminActionsWithoutGodMode = Util.GetConfigVarFromSections(config, "implicit_gods", sections, false); + if(m_allowAdminActionsWithoutGodMode) + m_forceAdminModeAlwaysOn = false; m_allowedScriptCreators = ParseUserSetConfigSetting(config, "allowed_script_creators", m_allowedScriptCreators); @@ -266,63 +254,78 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene = scene; scene.RegisterModuleInterface(this); + scenePermissions = m_scene.Permissions; //Register functions with Scene External Checks! - m_scene.Permissions.OnBypassPermissions += BypassPermissions; - m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; - m_scene.Permissions.OnPropagatePermissions += PropagatePermissions; - m_scene.Permissions.OnGenerateClientFlags += GenerateClientFlags; - m_scene.Permissions.OnAbandonParcel += CanAbandonParcel; - m_scene.Permissions.OnReclaimParcel += CanReclaimParcel; - m_scene.Permissions.OnDeedParcel += CanDeedParcel; - m_scene.Permissions.OnDeedObject += CanDeedObject; - m_scene.Permissions.OnIsGod += IsGod; - m_scene.Permissions.OnIsGridGod += IsGridGod; - m_scene.Permissions.OnIsAdministrator += IsAdministrator; - m_scene.Permissions.OnIsEstateManager += IsEstateManager; - m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; - m_scene.Permissions.OnDeleteObject += CanDeleteObject; - m_scene.Permissions.OnEditObject += CanEditObject; - m_scene.Permissions.OnEditParcelProperties += CanEditParcelProperties; - m_scene.Permissions.OnInstantMessage += CanInstantMessage; - m_scene.Permissions.OnInventoryTransfer += CanInventoryTransfer; - m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand; - m_scene.Permissions.OnMoveObject += CanMoveObject; - m_scene.Permissions.OnObjectEntry += CanObjectEntry; - m_scene.Permissions.OnReturnObjects += CanReturnObjects; - m_scene.Permissions.OnRezObject += CanRezObject; - m_scene.Permissions.OnRunConsoleCommand += CanRunConsoleCommand; - m_scene.Permissions.OnRunScript += CanRunScript; - m_scene.Permissions.OnCompileScript += CanCompileScript; - m_scene.Permissions.OnSellParcel += CanSellParcel; - m_scene.Permissions.OnTakeObject += CanTakeObject; - m_scene.Permissions.OnSellGroupObject += CanSellGroupObject; - m_scene.Permissions.OnTakeCopyObject += CanTakeCopyObject; - m_scene.Permissions.OnTerraformLand += CanTerraformLand; - m_scene.Permissions.OnLinkObject += CanLinkObject; - m_scene.Permissions.OnDelinkObject += CanDelinkObject; - m_scene.Permissions.OnBuyLand += CanBuyLand; + scenePermissions.OnBypassPermissions += BypassPermissions; + scenePermissions.OnSetBypassPermissions += SetBypassPermissions; + scenePermissions.OnPropagatePermissions += PropagatePermissions; - m_scene.Permissions.OnViewNotecard += CanViewNotecard; - m_scene.Permissions.OnViewScript += CanViewScript; - m_scene.Permissions.OnEditNotecard += CanEditNotecard; - m_scene.Permissions.OnEditScript += CanEditScript; + scenePermissions.OnIsGridGod += IsGridAdministrator; + scenePermissions.OnIsAdministrator += IsAdministrator; + scenePermissions.OnIsEstateManager += IsEstateManager; - m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory; - m_scene.Permissions.OnEditObjectInventory += CanEditObjectInventory; - m_scene.Permissions.OnCopyObjectInventory += CanCopyObjectInventory; - m_scene.Permissions.OnDeleteObjectInventory += CanDeleteObjectInventory; - m_scene.Permissions.OnResetScript += CanResetScript; + scenePermissions.OnGenerateClientFlags += GenerateClientFlags; - m_scene.Permissions.OnCreateUserInventory += CanCreateUserInventory; - m_scene.Permissions.OnCopyUserInventory += CanCopyUserInventory; - m_scene.Permissions.OnEditUserInventory += CanEditUserInventory; - m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; + scenePermissions.OnIssueEstateCommand += CanIssueEstateCommand; + scenePermissions.OnRunConsoleCommand += CanRunConsoleCommand; - m_scene.Permissions.OnTeleport += CanTeleport; + scenePermissions.OnTeleport += CanTeleport; - m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia; - m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia; + scenePermissions.OnInstantMessage += CanInstantMessage; + + scenePermissions.OnAbandonParcel += CanAbandonParcel; + scenePermissions.OnReclaimParcel += CanReclaimParcel; + scenePermissions.OnDeedParcel += CanDeedParcel; + scenePermissions.OnSellParcel += CanSellParcel; + scenePermissions.OnEditParcelProperties += CanEditParcelProperties; + scenePermissions.OnTerraformLand += CanTerraformLand; + scenePermissions.OnBuyLand += CanBuyLand; + + scenePermissions.OnReturnObjects += CanReturnObjects; + + scenePermissions.OnRezObject += CanRezObject; + scenePermissions.OnObjectEntry += CanObjectEntry; + scenePermissions.OnObjectEnterWithScripts += OnObjectEnterWithScripts; + + scenePermissions.OnDuplicateObject += CanDuplicateObject; + scenePermissions.OnDeleteObjectByIDs += CanDeleteObjectByIDs; + scenePermissions.OnDeleteObject += CanDeleteObject; + scenePermissions.OnEditObjectByIDs += CanEditObjectByIDs; + scenePermissions.OnEditObject += CanEditObject; + scenePermissions.OnInventoryTransfer += CanInventoryTransfer; + scenePermissions.OnMoveObject += CanMoveObject; + scenePermissions.OnTakeObject += CanTakeObject; + scenePermissions.OnTakeCopyObject += CanTakeCopyObject; + scenePermissions.OnLinkObject += CanLinkObject; + scenePermissions.OnDelinkObject += CanDelinkObject; + scenePermissions.OnDeedObject += CanDeedObject; + scenePermissions.OnSellGroupObject += CanSellGroupObject; + scenePermissions.OnSellObjectByUserID += CanSellObjectByUserID; + scenePermissions.OnSellObject += CanSellObject; + + scenePermissions.OnCreateObjectInventory += CanCreateObjectInventory; + scenePermissions.OnEditObjectInventory += CanEditObjectInventory; + scenePermissions.OnCopyObjectInventory += CanCopyObjectInventory; + scenePermissions.OnDeleteObjectInventory += CanDeleteObjectInventory; + scenePermissions.OnDoObjectInvToObjectInv += CanDoObjectInvToObjectInv; + scenePermissions.OnDropInObjectInv += CanDropInObjectInv; + + scenePermissions.OnViewNotecard += CanViewNotecard; + scenePermissions.OnViewScript += CanViewScript; + scenePermissions.OnEditNotecard += CanEditNotecard; + scenePermissions.OnEditScript += CanEditScript; + scenePermissions.OnResetScript += CanResetScript; + scenePermissions.OnRunScript += CanRunScript; + scenePermissions.OnCompileScript += CanCompileScript; + + scenePermissions.OnCreateUserInventory += CanCreateUserInventory; + scenePermissions.OnCopyUserInventory += CanCopyUserInventory; + scenePermissions.OnEditUserInventory += CanEditUserInventory; + scenePermissions.OnDeleteUserInventory += CanDeleteUserInventory; + + scenePermissions.OnControlPrimMedia += CanControlPrimMedia; + scenePermissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia; m_scene.AddCommand("Users", this, "bypass permissions", "bypass permissions ", @@ -351,6 +354,78 @@ namespace OpenSim.Region.CoreModules.World.Permissions return; m_scene.UnregisterModuleInterface(this); + + scenePermissions.OnBypassPermissions -= BypassPermissions; + scenePermissions.OnSetBypassPermissions -= SetBypassPermissions; + scenePermissions.OnPropagatePermissions -= PropagatePermissions; + + scenePermissions.OnIsGridGod -= IsGridAdministrator; + scenePermissions.OnIsAdministrator -= IsAdministrator; + scenePermissions.OnIsEstateManager -= IsEstateManager; + + scenePermissions.OnGenerateClientFlags -= GenerateClientFlags; + + scenePermissions.OnIssueEstateCommand -= CanIssueEstateCommand; + scenePermissions.OnRunConsoleCommand -= CanRunConsoleCommand; + + scenePermissions.OnTeleport -= CanTeleport; + + scenePermissions.OnInstantMessage -= CanInstantMessage; + + scenePermissions.OnAbandonParcel -= CanAbandonParcel; + scenePermissions.OnReclaimParcel -= CanReclaimParcel; + scenePermissions.OnDeedParcel -= CanDeedParcel; + scenePermissions.OnSellParcel -= CanSellParcel; + scenePermissions.OnEditParcelProperties -= CanEditParcelProperties; + scenePermissions.OnTerraformLand -= CanTerraformLand; + scenePermissions.OnBuyLand -= CanBuyLand; + + scenePermissions.OnRezObject -= CanRezObject; + scenePermissions.OnObjectEntry -= CanObjectEntry; + scenePermissions.OnObjectEnterWithScripts -= OnObjectEnterWithScripts; + + scenePermissions.OnReturnObjects -= CanReturnObjects; + + scenePermissions.OnDuplicateObject -= CanDuplicateObject; + scenePermissions.OnDeleteObjectByIDs -= CanDeleteObjectByIDs; + scenePermissions.OnDeleteObject -= CanDeleteObject; + scenePermissions.OnEditObjectByIDs -= CanEditObjectByIDs; + scenePermissions.OnEditObject -= CanEditObject; + scenePermissions.OnInventoryTransfer -= CanInventoryTransfer; + scenePermissions.OnMoveObject -= CanMoveObject; + scenePermissions.OnTakeObject -= CanTakeObject; + scenePermissions.OnTakeCopyObject -= CanTakeCopyObject; + scenePermissions.OnLinkObject -= CanLinkObject; + scenePermissions.OnDelinkObject -= CanDelinkObject; + scenePermissions.OnDeedObject -= CanDeedObject; + + scenePermissions.OnSellGroupObject -= CanSellGroupObject; + scenePermissions.OnSellObjectByUserID -= CanSellObjectByUserID; + scenePermissions.OnSellObject -= CanSellObject; + + scenePermissions.OnCreateObjectInventory -= CanCreateObjectInventory; + scenePermissions.OnEditObjectInventory -= CanEditObjectInventory; + scenePermissions.OnCopyObjectInventory -= CanCopyObjectInventory; + scenePermissions.OnDeleteObjectInventory -= CanDeleteObjectInventory; + scenePermissions.OnDoObjectInvToObjectInv -= CanDoObjectInvToObjectInv; + scenePermissions.OnDropInObjectInv -= CanDropInObjectInv; + + scenePermissions.OnViewNotecard -= CanViewNotecard; + scenePermissions.OnViewScript -= CanViewScript; + scenePermissions.OnEditNotecard -= CanEditNotecard; + scenePermissions.OnEditScript -= CanEditScript; + scenePermissions.OnResetScript -= CanResetScript; + scenePermissions.OnRunScript -= CanRunScript; + scenePermissions.OnCompileScript -= CanCompileScript; + + scenePermissions.OnCreateUserInventory -= CanCreateUserInventory; + scenePermissions.OnCopyUserInventory -= CanCopyUserInventory; + scenePermissions.OnEditUserInventory -= CanEditUserInventory; + scenePermissions.OnDeleteUserInventory -= CanDeleteUserInventory; + + scenePermissions.OnControlPrimMedia -= CanControlPrimMedia; + scenePermissions.OnInteractWithPrimMedia -= CanInteractWithPrimMedia; + } public void Close() @@ -480,6 +555,36 @@ namespace OpenSim.Region.CoreModules.World.Permissions return false; } + protected bool GroupMemberPowers(UUID groupID, UUID userID, ref ulong powers) + { + powers = 0; + if (null == GroupsModule) + return false; + + GroupMembershipData gmd = GroupsModule.GetMembershipData(groupID, userID); + + if (gmd != null) + { + powers = gmd.GroupPowers; + return true; + } + return false; + } + + protected bool GroupMemberPowers(UUID groupID, ScenePresence sp, ref ulong powers) + { + powers = 0; + IClientAPI client = sp.ControllingClient; + if (client == null) + return false; + + if(!client.IsGroupMember(groupID)) + return false; + + powers = client.GetGroupPowers(groupID); + return true; + } + /// /// Parse a user set configuration setting /// @@ -526,13 +631,13 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (user == UUID.Zero) return false; - if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod) + if (m_RegionOwnerIsAdmin && m_scene.RegionInfo.EstateSettings.EstateOwner == user) return true; - if (IsEstateManager(user) && m_RegionManagerIsGod) + if (m_RegionManagerIsAdmin && IsEstateManager(user)) return true; - if (IsGridGod(user, null)) + if (IsGridAdministrator(user)) return true; return false; @@ -544,14 +649,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions /// The user /// Unused, can be null /// - protected bool IsGridGod(UUID user, Scene scene) + protected bool IsGridAdministrator(UUID user) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - if (user == UUID.Zero) return false; + if (user == UUID.Zero) + return false; - if (m_allowGridGods) + if (m_allowGridAdmins) { ScenePresence sp = m_scene.GetScenePresence(user); if (sp != null) @@ -567,10 +673,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions protected bool IsFriendWithPerms(UUID user, UUID objectOwner) { - if (user == UUID.Zero) + if (FriendsModule == null) return false; - if (FriendsModule == null) + if (user == UUID.Zero) return false; int friendPerms = FriendsModule.GetRightsGrantedByFriend(user, objectOwner); @@ -606,75 +712,178 @@ namespace OpenSim.Region.CoreModules.World.Permissions #region Object Permissions - public uint GenerateClientFlags(UUID user, UUID objID) + const uint DEFAULT_FLAGS = (uint)( + PrimFlags.ObjectCopy | // Tells client you can copy the object + PrimFlags.ObjectModify | // tells client you can modify the object + PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) + PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it + PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object + PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object + PrimFlags.ObjectOwnerModify // Tells client that you're the owner of the object + ); + + const uint NOT_DEFAULT_FLAGS = (uint)~( + PrimFlags.ObjectCopy | // Tells client you can copy the object + PrimFlags.ObjectModify | // tells client you can modify the object + PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) + PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it + PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object + PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object + PrimFlags.ObjectOwnerModify // Tells client that you're the owner of the object + ); + + const uint EXTRAOWNERMASK = (uint)( + PrimFlags.ObjectYouOwner | + PrimFlags.ObjectAnyOwner + ); + + const uint EXTRAGODMASK = (uint)( + PrimFlags.ObjectYouOwner | + PrimFlags.ObjectAnyOwner | + PrimFlags.ObjectOwnerModify | + PrimFlags.ObjectModify | + PrimFlags.ObjectMove + ); + + const uint GOD_FLAGS = (uint)( + PrimFlags.ObjectCopy | // Tells client you can copy the object + PrimFlags.ObjectModify | // tells client you can modify the object + PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) + PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it + PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object + PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object + PrimFlags.ObjectOwnerModify // Tells client that you're the owner of the object + ); + + const uint LOCKED_GOD_FLAGS = (uint)( + PrimFlags.ObjectCopy | // Tells client you can copy the object + PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it + PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object + PrimFlags.ObjectAnyOwner // Tells client that someone owns the object + ); + + const uint SHAREDMASK = (uint)( + PermissionMask.Move | + PermissionMask.Modify | + PermissionMask.Copy + ); + + public uint GenerateClientFlags(SceneObjectPart task, ScenePresence sp, uint curEffectivePerms) { - // Here's the way this works, - // ObjectFlags and Permission flags are two different enumerations - // ObjectFlags, however, tells the client to change what it will allow the user to do. - // So, that means that all of the permissions type ObjectFlags are /temporary/ and only - // supposed to be set when customizing the objectflags for the client. - - // These temporary objectflags get computed and added in this function based on the - // Permission mask that's appropriate! - // Outside of this method, they should never be added to objectflags! - // -teravus - - SceneObjectPart task = m_scene.GetSceneObjectPart(objID); - - // this shouldn't ever happen.. return no permissions/objectflags. - if (task == null) - return (uint)0; - - uint objflags = task.GetEffectiveObjectFlags(); - UUID objectOwner = task.OwnerID; - + if(sp == null || task == null || curEffectivePerms == 0) + return 0; // Remove any of the objectFlags that are temporary. These will get added back if appropriate - // in the next bit of code + uint objflags = curEffectivePerms & NOT_DEFAULT_FLAGS ; - // libomv will moan about PrimFlags.ObjectYouOfficer being - // deprecated -#pragma warning disable 0612 - objflags &= (uint) - ~(PrimFlags.ObjectCopy | // Tells client you can copy the object - PrimFlags.ObjectModify | // tells client you can modify the object - PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) - PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it - PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object - PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object - PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object - PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set - ); -#pragma warning restore 0612 + uint returnMask; - // Creating the three ObjectFlags options for this method to choose from. - // Customize the OwnerMask - uint objectOwnerMask = ApplyObjectModifyMasks(task.OwnerMask, objflags); - objectOwnerMask |= (uint)PrimFlags.ObjectYouOwner | (uint)PrimFlags.ObjectAnyOwner | (uint)PrimFlags.ObjectOwnerModify; + SceneObjectGroup grp = task.ParentGroup; + if(grp == null) + return 0; - // Customize the GroupMask - uint objectGroupMask = ApplyObjectModifyMasks(task.GroupMask, objflags); + UUID taskOwnerID = task.OwnerID; + UUID spID = sp.UUID; - // Customize the EveryoneMask - uint objectEveryoneMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags); - if (objectOwner != UUID.Zero) - objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; + bool unlocked = (grp.RootPart.OwnerMask & (uint)PermissionMask.Move) != 0; - PermissionClass permissionClass = GetPermissionClass(user, task); - - switch (permissionClass) + if(sp.IsGod) { - case PermissionClass.Owner: - return objectOwnerMask; - case PermissionClass.Group: - return objectGroupMask | objectEveryoneMask; - case PermissionClass.Everyone: - default: - return objectEveryoneMask; + // do locked on objects owned by admin + if(!unlocked && spID == taskOwnerID) + return objflags | LOCKED_GOD_FLAGS; + else + return objflags | GOD_FLAGS; } + + //bypass option == owner rights + if (m_bypassPermissions) + { + returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags, true); //?? + returnMask |= EXTRAOWNERMASK; + if((returnMask & (uint)PrimFlags.ObjectModify) != 0) + returnMask |= (uint)PrimFlags.ObjectOwnerModify; + return returnMask; + } + + // owner + if (spID == taskOwnerID) + { + returnMask = ApplyObjectModifyMasks(grp.EffectiveOwnerPerms, objflags, unlocked); + returnMask |= EXTRAOWNERMASK; + if((returnMask & (uint)PrimFlags.ObjectModify) != 0) + returnMask |= (uint)PrimFlags.ObjectOwnerModify; + return returnMask; + } + + // if not god or owner, do attachments as everyone + if(task.ParentGroup.IsAttachment) + { + returnMask = ApplyObjectModifyMasks(grp.EffectiveEveryOnePerms, objflags, unlocked); + if (taskOwnerID != UUID.Zero) + returnMask |= (uint)PrimFlags.ObjectAnyOwner; + return returnMask; + } + + UUID taskGroupID = task.GroupID; + bool notGroupdOwned = taskOwnerID != taskGroupID; + + // if friends with rights then owner + if (notGroupdOwned && IsFriendWithPerms(spID, taskOwnerID)) + { + returnMask = ApplyObjectModifyMasks(grp.EffectiveOwnerPerms, objflags, unlocked); + returnMask |= EXTRAOWNERMASK; + if((returnMask & (uint)PrimFlags.ObjectModify) != 0) + returnMask |= (uint)PrimFlags.ObjectOwnerModify; + return returnMask; + } + + // group owned or shared ? + IClientAPI client = sp.ControllingClient; + ulong powers = 0; + if(taskGroupID != UUID.Zero && GroupMemberPowers(taskGroupID, sp, ref powers)) + { + if(notGroupdOwned) + { + // group sharing or everyone + returnMask = ApplyObjectModifyMasks(grp.EffectiveGroupOrEveryOnePerms, objflags, unlocked); + if (taskOwnerID != UUID.Zero) + returnMask |= (uint)PrimFlags.ObjectAnyOwner; + return returnMask; + } + + // object is owned by group, check role powers + if((powers & (ulong)GroupPowers.ObjectManipulate) == 0) + { + // group sharing or everyone + returnMask = ApplyObjectModifyMasks(grp.EffectiveGroupOrEveryOnePerms, objflags, unlocked); + returnMask |= + (uint)PrimFlags.ObjectGroupOwned | + (uint)PrimFlags.ObjectAnyOwner; + return returnMask; + } + + // we may have copy without transfer + uint grpEffectiveOwnerPerms = grp.EffectiveOwnerPerms; + if((grpEffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + grpEffectiveOwnerPerms &= ~(uint)PermissionMask.Copy; + returnMask = ApplyObjectModifyMasks(grpEffectiveOwnerPerms, objflags, unlocked); + returnMask |= + (uint)PrimFlags.ObjectGroupOwned | + (uint)PrimFlags.ObjectYouOwner; + if((returnMask & (uint)PrimFlags.ObjectModify) != 0) + returnMask |= (uint)PrimFlags.ObjectOwnerModify; + return returnMask; + } + + // fallback is everyone rights + returnMask = ApplyObjectModifyMasks(grp.EffectiveEveryOnePerms, objflags, unlocked); + if (taskOwnerID != UUID.Zero) + returnMask |= (uint)PrimFlags.ObjectAnyOwner; + return returnMask; } - private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) + private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask, bool unlocked) { // We are adding the temporary objectflags to the object's objectflags based on the // permission flag given. These change the F flags on the client. @@ -684,14 +893,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions objectFlagsMask |= (uint)PrimFlags.ObjectCopy; } - if ((setPermissionMask & (uint)PermissionMask.Move) != 0) + if (unlocked) { - objectFlagsMask |= (uint)PrimFlags.ObjectMove; - } + if ((setPermissionMask & (uint)PermissionMask.Move) != 0) + { + objectFlagsMask |= (uint)PrimFlags.ObjectMove; + } - if ((setPermissionMask & (uint)PermissionMask.Modify) != 0) - { - objectFlagsMask |= (uint)PrimFlags.ObjectModify; + if ((setPermissionMask & (uint)PermissionMask.Modify) != 0) + { + objectFlagsMask |= (uint)PrimFlags.ObjectModify; + } } if ((setPermissionMask & (uint)PermissionMask.Transfer) != 0) @@ -702,6 +914,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions return objectFlagsMask; } + // OARs still need this method that handles offline users public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj) { if (obj == null) @@ -715,136 +928,199 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (user == objectOwner) return PermissionClass.Owner; - if (IsFriendWithPerms(user, objectOwner) && !obj.ParentGroup.IsAttachment) - 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; -/* to review later - // 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) + if(!obj.ParentGroup.IsAttachment) { - // Admin objects should not be editable by the above - if (!IsAdministrator(objectOwner)) + if (IsFriendWithPerms(user, objectOwner) ) return PermissionClass.Owner; + + // Group permissions + if (obj.GroupID != UUID.Zero && IsGroupMember(obj.GroupID, user, 0)) + return PermissionClass.Group; } -*/ - // Group permissions - if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0)) - return PermissionClass.Group; return PermissionClass.Everyone; } - /// - /// General permissions checks for any operation involving an object. These supplement more specific checks - /// implemented by callers. - /// - /// - /// This is a scene object group UUID - /// - /// - protected bool GenericObjectPermission(UUID currentUser, UUID objId, bool denyOnLocked) + // get effective object permissions using user UUID. User rights will be fixed + protected uint GetObjectPermissions(UUID currentUser, SceneObjectGroup group, bool denyOnLocked) { - // Default: deny - bool permission = false; - bool locked = false; + if (group == null) + return 0; - SceneObjectPart part = m_scene.GetSceneObjectPart(objId); - - if (part == null) - return false; - - SceneObjectGroup group = part.ParentGroup; + SceneObjectPart root = group.RootPart; + if (root == null) + return 0; UUID objectOwner = group.OwnerID; - locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0); + bool locked = denyOnLocked && ((root.OwnerMask & (uint)PermissionMask.Move) == 0); - // People shouldn't be able to do anything with locked objects, except the Administrator - // The 'set permissions' runs through a different permission check, so when an object owner - // sets an object locked, the only thing that they can do is unlock it. - // - // Nobody but the object owner can set permissions on an object - // - if (locked && (!IsAdministrator(currentUser)) && denyOnLocked) - { - return false; - } - - // Object owners should be able to edit their own content - if (currentUser == objectOwner) - { - // there is no way that later code can change this back to false - // so just return true immediately and short circuit the more - // expensive group checks - return true; - - //permission = true; - } - else if (group.IsAttachment) - { - permission = false; - } - -// m_log.DebugFormat( -// "[PERMISSIONS]: group.GroupID = {0}, part.GroupMask = {1}, isGroupMember = {2} for {3}", -// group.GroupID, -// m_scene.GetSceneObjectPart(objId).GroupMask, -// IsGroupMember(group.GroupID, currentUser, 0), -// currentUser); - - // Group members should be able to edit group objects - if ((group.GroupID != UUID.Zero) - && ((m_scene.GetSceneObjectPart(objId).GroupMask & (uint)PermissionMask.Modify) != 0) - && IsGroupMember(group.GroupID, currentUser, 0)) - { - // Return immediately, so that the administrator can shares group objects - return true; - } - - // Friends with benefits should be able to edit the objects too - if (IsFriendWithPerms(currentUser, objectOwner)) - { - // Return immediately, so that the administrator can share objects with friends - return true; - } - - // Users should be able to edit what is over their land. - ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); - if ((parcel != null) && (parcel.LandData.OwnerID == currentUser)) - { - permission = true; - } - - // Estate users should be able to edit anything in the sim - if (IsEstateManager(currentUser)) - { - permission = true; - } - - // Admin objects should not be editable by the above - if (IsAdministrator(objectOwner)) - { - permission = false; - } - - // Admin should be able to edit anything in the sim (including admin objects) if (IsAdministrator(currentUser)) { - permission = true; + // do lock on admin owned objects + if(locked && currentUser == objectOwner) + return (uint)(PermissionMask.AllEffective & ~(PermissionMask.Modify | PermissionMask.Move)); + return (uint)PermissionMask.AllEffective; } - return permission; + uint lockmask = (uint)PermissionMask.AllEffective; + if(locked) + lockmask &= ~(uint)(PermissionMask.Modify | PermissionMask.Move); + + if (currentUser == objectOwner) + return group.EffectiveOwnerPerms & lockmask; + + if (group.IsAttachment) + return 0; + + UUID sogGroupID = group.GroupID; + bool notgroudOwned = sogGroupID != objectOwner; + + if (notgroudOwned && IsFriendWithPerms(currentUser, objectOwner)) + return group.EffectiveOwnerPerms & lockmask; + + ulong powers = 0; + if (sogGroupID != UUID.Zero && GroupMemberPowers(sogGroupID, currentUser, ref powers)) + { + if(notgroudOwned) + return group.EffectiveGroupOrEveryOnePerms & lockmask; + + if((powers & (ulong)GroupPowers.ObjectManipulate) == 0) + return group.EffectiveGroupOrEveryOnePerms & lockmask; + + uint grpEffectiveOwnerPerms = group.EffectiveOwnerPerms & lockmask; + if((grpEffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + grpEffectiveOwnerPerms &= ~(uint)PermissionMask.Copy; + return grpEffectiveOwnerPerms; + } + + return group.EffectiveEveryOnePerms & lockmask; } + // get effective object permissions using present presence. So some may depend on requested rights (ie God) + protected uint GetObjectPermissions(ScenePresence sp, SceneObjectGroup group, bool denyOnLocked) + { + if (sp == null || sp.IsDeleted || group == null || group.IsDeleted) + return 0; + + SceneObjectPart root = group.RootPart; + if (root == null) + return 0; + + UUID spID = sp.UUID; + UUID objectOwner = group.OwnerID; + + bool locked = denyOnLocked && ((root.OwnerMask & (uint)PermissionMask.Move) == 0); + + if (sp.IsGod) + { + if(locked && spID == objectOwner) + return (uint)(PermissionMask.AllEffective & ~(PermissionMask.Modify | PermissionMask.Move)); + return (uint)PermissionMask.AllEffective; + } + + uint lockmask = (uint)PermissionMask.AllEffective; + if(locked) + lockmask &= ~(uint)(PermissionMask.Modify | PermissionMask.Move); + + if (spID == objectOwner) + return group.EffectiveOwnerPerms & lockmask; + + if (group.IsAttachment) + return 0; + + UUID sogGroupID = group.GroupID; + bool notgroudOwned = sogGroupID != objectOwner; + + if (notgroudOwned && IsFriendWithPerms(spID, objectOwner)) + return group.EffectiveOwnerPerms & lockmask; + + ulong powers = 0; + if (sogGroupID != UUID.Zero && GroupMemberPowers(sogGroupID, sp, ref powers)) + { + if(notgroudOwned) + return group.EffectiveGroupOrEveryOnePerms & lockmask; + + if((powers & (ulong)GroupPowers.ObjectManipulate) == 0) + return group.EffectiveGroupOrEveryOnePerms & lockmask; + + uint grpEffectiveOwnerPerms = group.EffectiveOwnerPerms & lockmask; + if((grpEffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + grpEffectiveOwnerPerms &= ~(uint)PermissionMask.Copy; + return grpEffectiveOwnerPerms; + } + + return group.EffectiveEveryOnePerms & lockmask; + } + + private uint GetObjectItemPermissions(UUID userID, TaskInventoryItem ti) + { + UUID tiOwnerID = ti.OwnerID; + if(tiOwnerID == userID) + return ti.CurrentPermissions; + + if(IsAdministrator(userID)) + return (uint)PermissionMask.AllEffective; + // ?? + if (IsFriendWithPerms(userID, tiOwnerID)) + return ti.CurrentPermissions; + + UUID tiGroupID = ti.GroupID; + if(tiGroupID != UUID.Zero) + { + ulong powers = 0; + if(GroupMemberPowers(tiGroupID, userID, ref powers)) + { + if(tiGroupID == ti.OwnerID) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return ti.CurrentPermissions; + } + return ti.GroupPermissions; + } + } + + return 0; + } + + private uint GetObjectItemPermissions(ScenePresence sp, TaskInventoryItem ti, bool notEveryone) + { + UUID tiOwnerID = ti.OwnerID; + UUID spID = sp.UUID; + + if(tiOwnerID == spID) + return ti.CurrentPermissions; + + // ?? + if (IsFriendWithPerms(spID, tiOwnerID)) + return ti.CurrentPermissions; + + UUID tiGroupID = ti.GroupID; + if(tiGroupID != UUID.Zero) + { + ulong powers = 0; + if(GroupMemberPowers(tiGroupID, spID, ref powers)) + { + if(tiGroupID == ti.OwnerID) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return ti.CurrentPermissions; + } + uint p = ti.GroupPermissions; + if(!notEveryone) + p |= ti.EveryonePermissions; + return p; + } + } + + if(notEveryone) + return 0; + + return ti.EveryonePermissions; + } #endregion #region Generic Permissions @@ -869,89 +1145,37 @@ namespace OpenSim.Region.CoreModules.World.Permissions public bool GenericEstatePermission(UUID user) { - // Default: deny - bool permission = false; - // Estate admins should be able to use estate tools if (IsEstateManager(user)) - permission = true; + return true; // Administrators always have permission if (IsAdministrator(user)) - permission = true; + return true; - return permission; - } - - protected bool GenericParcelPermission(UUID user, ILandObject parcel, ulong groupPowers) - { - bool permission = false; - - if (parcel.LandData.OwnerID == user) - { - permission = true; - } - - if ((parcel.LandData.GroupID != UUID.Zero) && IsGroupMember(parcel.LandData.GroupID, user, groupPowers)) - { - permission = true; - } - - if (IsEstateManager(user)) - { - permission = true; - } - - if (IsAdministrator(user)) - { - permission = true; - } - - if (m_SimpleBuildPermissions && - (parcel.LandData.Flags & (uint)ParcelFlags.UseAccessList) == 0 && parcel.IsInLandAccessList(user)) - permission = true; - - return permission; + return false; } protected bool GenericParcelOwnerPermission(UUID user, ILandObject parcel, ulong groupPowers, bool allowEstateManager) { if (parcel.LandData.OwnerID == user) - { - // Returning immediately so that group deeded objects on group deeded land don't trigger a NRE on - // the subsequent redundant checks when using lParcelMediaCommandList() - // See http://opensimulator.org/mantis/view.php?id=3999 for more details return true; - } if (parcel.LandData.IsGroupOwned && IsGroupMember(parcel.LandData.GroupID, user, groupPowers)) - { return true; - } if (allowEstateManager && IsEstateManager(user)) - { return true; - } if (IsAdministrator(user)) - { return true; - } return false; } - - protected bool GenericParcelPermission(UUID user, Vector3 pos, ulong groupPowers) - { - ILandObject parcel = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); - if (parcel == null) return false; - return GenericParcelPermission(user, parcel, groupPowers); - } #endregion #region Permission Checks - private bool CanAbandonParcel(UUID user, ILandObject parcel, Scene scene) + private bool CanAbandonParcel(UUID user, ILandObject parcel) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -959,7 +1183,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions return GenericParcelOwnerPermission(user, parcel, (ulong)GroupPowers.LandRelease, false); } - private bool CanReclaimParcel(UUID user, ILandObject parcel, Scene scene) + private bool CanReclaimParcel(UUID user, ILandObject parcel) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -967,108 +1191,223 @@ namespace OpenSim.Region.CoreModules.World.Permissions return GenericParcelOwnerPermission(user, parcel, 0,true); } - private bool CanDeedParcel(UUID user, ILandObject parcel, Scene scene) + private bool CanDeedParcel(UUID user, ILandObject parcel) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; + if(parcel.LandData.GroupID == UUID.Zero) + return false; + + if (IsAdministrator(user)) + return true; + if (parcel.LandData.OwnerID != user) // Only the owner can deed! return false; - ScenePresence sp = scene.GetScenePresence(user); - IClientAPI client = sp.ControllingClient; - - if ((client.GetGroupPowers(parcel.LandData.GroupID) & (ulong)GroupPowers.LandDeed) == 0) + ScenePresence sp = m_scene.GetScenePresence(user); + if(sp == null) return false; - return GenericParcelOwnerPermission(user, parcel, (ulong)GroupPowers.LandDeed, false); - } - - private bool CanDeedObject(UUID user, UUID group, Scene scene) - { - DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); - if (m_bypassPermissions) return m_bypassPermissionsValue; - - ScenePresence sp = scene.GetScenePresence(user); IClientAPI client = sp.ControllingClient; - - if ((client.GetGroupPowers(group) & (ulong)GroupPowers.DeedObject) == 0) + if ((client.GetGroupPowers(parcel.LandData.GroupID) & (ulong)GroupPowers.LandDeed) == 0) return false; return true; } - private bool IsGod(UUID user, Scene scene) + private bool CanDeedObject(ScenePresence sp, SceneObjectGroup sog, UUID targetGroupID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return IsAdministrator(user); + if(sog == null || sog.IsDeleted || sp == null || sp.IsDeleted || targetGroupID == UUID.Zero) + return false; + + // object has group already? + if(sog.GroupID != targetGroupID) + return false; + + // is effectivelly shared? + if(sog.EffectiveGroupPerms == 0) + return false; + + if(sp.IsGod) + return true; + + // owned by requester? + if(sog.OwnerID != sp.UUID) + return false; + + // owner can transfer? + if((sog.EffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + return false; + + // group member ? + ulong powers = 0; + if(!GroupMemberPowers(targetGroupID, sp, ref powers)) + return false; + + // has group rights? + if ((powers & (ulong)GroupPowers.DeedObject) == 0) + return false; + + return true; } - private bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition) + private bool CanDuplicateObject(SceneObjectGroup sog, ScenePresence sp) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - if (!GenericObjectPermission(owner, objectID, true)) - { - //They can't even edit the object - return false; - } - - SceneObjectPart part = scene.GetSceneObjectPart(objectID); - if (part == null) + if (sog == null || sog.IsDeleted || sp == null || sp.IsDeleted) return false; - if (part.OwnerID == owner) - { - if ((part.OwnerMask & PERM_COPY) == 0) - return false; - } - else if (part.GroupID != UUID.Zero) - { - if ((part.OwnerID == part.GroupID) && ((owner != part.LastOwnerID) || ((part.GroupMask & PERM_TRANS) == 0))) - return false; + uint perms = GetObjectPermissions(sp, sog, false); + if((perms & (uint)PermissionMask.Copy) == 0) + return false; - if ((part.GroupMask & PERM_COPY) == 0) - return false; - } + if(sog.OwnerID != sp.UUID && (perms & (uint)PermissionMask.Transfer) == 0) + return false; //If they can rez, they can duplicate - return CanRezObject(objectCount, owner, objectPosition, scene); + return CanRezObject(0, sp.UUID, sog.AbsolutePosition); } - private bool CanDeleteObject(UUID objectID, UUID deleter, Scene scene) + private bool CanDeleteObject(SceneObjectGroup sog, ScenePresence sp) + { + // ignoring locked. viewers should warn and ask for confirmation + + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + if (sog == null || sog.IsDeleted || sp == null || sp.IsDeleted) + return false; + + if(sog.IsAttachment) + return false; + + UUID sogOwnerID = sog.OwnerID; + UUID spID = sp.UUID; + + if(sogOwnerID == spID) + return true; + + if (sp.IsGod) + return true; + + if (IsFriendWithPerms(sog.UUID, sogOwnerID)) + return true; + + UUID sogGroupID = sog.GroupID; + if (sogGroupID != UUID.Zero) + { + ulong powers = 0; + if(GroupMemberPowers(sogGroupID, sp, ref powers)) + { + if(sogGroupID == sogOwnerID) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return true; + } + return (sog.EffectiveGroupPerms & (uint)PermissionMask.Modify) != 0; + } + } + return false; + } + + private bool CanDeleteObjectByIDs(UUID objectID, UUID userID) + { + // ignoring locked. viewers should warn and ask for confirmation + + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + SceneObjectGroup sog = m_scene.GetGroupByPrim(objectID); + if (sog == null) + return false; + + if(sog.IsAttachment) + return false; + + UUID sogOwnerID = sog.OwnerID; + + if(sogOwnerID == userID) + return true; + + if (IsAdministrator(userID)) + return true; + + if (IsFriendWithPerms(objectID, sogOwnerID)) + return true; + + UUID sogGroupID = sog.GroupID; + if (sogGroupID != UUID.Zero) + { + ulong powers = 0; + if(GroupMemberPowers(sogGroupID, userID, ref powers)) + { + if(sogGroupID == sogOwnerID) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return true; + } + return (sog.EffectiveGroupPerms & (uint)PermissionMask.Modify) != 0; + } + } + return false; + } + + private bool CanEditObjectByIDs(UUID objectID, UUID userID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(deleter, objectID, false); + SceneObjectGroup sog = m_scene.GetGroupByPrim(objectID); + if (sog == null) + return false; + + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + return true; } - private bool CanEditObject(UUID objectID, UUID editorID, Scene scene) + private bool CanEditObject(SceneObjectGroup sog, ScenePresence sp) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + if(sog == null || sog.IsDeleted || sp == null || sp.IsDeleted) + return false; + + uint perms = GetObjectPermissions(sp, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + return true; } - private bool CanEditObjectInventory(UUID objectID, UUID editorID, Scene scene) + private bool CanEditObjectInventory(UUID objectID, UUID userID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + SceneObjectGroup sog = m_scene.GetGroupByPrim(objectID); + if (sog == null) + return false; + + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + return true; } - private bool CanEditParcelProperties(UUID user, ILandObject parcel, GroupPowers p, Scene scene, bool allowManager) + private bool CanEditParcelProperties(UUID userID, ILandObject parcel, GroupPowers p, bool allowManager) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericParcelOwnerPermission(user, parcel, (ulong)p, false); + return GenericParcelOwnerPermission(userID, parcel, (ulong)p, false); } /// @@ -1079,18 +1418,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions /// /// /// - private bool CanEditScript(UUID script, UUID objectID, UUID user, Scene scene) + private bool CanEditScript(UUID script, UUID objectID, UUID userID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - if (m_allowedScriptEditors == UserSet.Administrators && !IsAdministrator(user)) + if (m_allowedScriptEditors == UserSet.Administrators && !IsAdministrator(userID)) return false; // Ordinarily, if you can view it, you can edit it // There is no viewing a no mod script // - return CanViewScript(script, objectID, user, scene); + return CanViewScript(script, objectID, userID); } /// @@ -1101,7 +1440,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions /// /// /// - private bool CanEditNotecard(UUID notecard, UUID objectID, UUID user, Scene scene) + private bool CanEditNotecard(UUID notecard, UUID objectID, UUID user) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1132,69 +1471,68 @@ namespace OpenSim.Region.CoreModules.World.Permissions } else // Prim inventory { - SceneObjectPart part = scene.GetSceneObjectPart(objectID); - + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); if (part == null) return false; - if (part.OwnerID != user) - { - if (part.GroupID == UUID.Zero) - return false; - - if (!IsGroupMember(part.GroupID, user, 0)) - return false; - - if ((part.GroupMask & (uint)PermissionMask.Modify) == 0) - return false; - } - else - { - if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) + SceneObjectGroup sog = part.ParentGroup; + if (sog == null) + return false; + + // check object mod right + uint perms = GetObjectPermissions(user, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) return false; - } TaskInventoryItem ti = part.Inventory.GetInventoryItem(notecard); - if (ti == null) return false; - + if (ti.OwnerID != user) { - if (ti.GroupID == UUID.Zero) + UUID tiGroupID = ti.GroupID; + if (tiGroupID == UUID.Zero) return false; - if (!IsGroupMember(ti.GroupID, user, 0)) + ulong powers = 0; + if(!GroupMemberPowers(tiGroupID, user, ref powers)) return false; + + if(tiGroupID == ti.OwnerID && (powers & (ulong)GroupPowers.ObjectManipulate) != 0) + { + if ((ti.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy)) == + ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy)) + return true; + } + if ((ti.GroupPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy)) == + ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy)) + return true; + return false; } // Require full perms - if ((ti.CurrentPermissions & - ((uint)PermissionMask.Modify | - (uint)PermissionMask.Copy)) != - ((uint)PermissionMask.Modify | - (uint)PermissionMask.Copy)) + if ((ti.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy)) != + ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy)) return false; } - return true; } - private bool CanInstantMessage(UUID user, UUID target, Scene startScene) + private bool CanInstantMessage(UUID user, UUID target) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; // If the sender is an object, check owner instead // - SceneObjectPart part = startScene.GetSceneObjectPart(user); + SceneObjectPart part = m_scene.GetSceneObjectPart(user); if (part != null) user = part.OwnerID; return GenericCommunicationPermission(user, target); } - private bool CanInventoryTransfer(UUID user, UUID target, Scene startScene) + private bool CanInventoryTransfer(UUID user, UUID target) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1202,7 +1540,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions return GenericCommunicationPermission(user, target); } - private bool CanIssueEstateCommand(UUID user, Scene requestFromScene, bool ownerCommand) + private bool CanIssueEstateCommand(UUID user, bool ownerCommand) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1210,178 +1548,162 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (IsAdministrator(user)) return true; - if (m_scene.RegionInfo.EstateSettings.IsEstateOwner(user)) - return true; - if (ownerCommand) - return false; + return m_scene.RegionInfo.EstateSettings.IsEstateOwner(user); - return GenericEstatePermission(user); + return IsEstateManager(user); } - private bool CanMoveObject(UUID objectID, UUID moverID, Scene scene) + private bool CanMoveObject(SceneObjectGroup sog, ScenePresence sp) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + + if(sog == null || sog.IsDeleted || sp == null || sp.IsDeleted) + return false; + if (m_bypassPermissions) { - SceneObjectPart part = scene.GetSceneObjectPart(objectID); - if (part.OwnerID != moverID) - { - if (!part.ParentGroup.IsDeleted) - { - if (part.ParentGroup.IsAttachment) - return false; - } - } + if (sog.OwnerID != sp.UUID && sog.IsAttachment) + return false; return m_bypassPermissionsValue; } - bool permission = GenericObjectPermission(moverID, objectID, true); - if (!permission) - { - if (!m_scene.Entities.ContainsKey(objectID)) - { - return false; - } - - // The client - // may request to edit linked parts, and therefore, it needs - // to also check for SceneObjectPart - - // If it's not an object, we cant edit it. - if ((!(m_scene.Entities[objectID] is SceneObjectGroup))) - { - return false; - } - - - SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objectID]; - - - // UUID taskOwner = null; - // Added this because at this point in time it wouldn't be wise for - // the administrator object permissions to take effect. - // UUID objectOwner = task.OwnerID; - - // Anyone can move - if ((task.RootPart.EveryoneMask & PERM_MOVE) != 0) - permission = true; - - // Locked - if ((task.RootPart.OwnerMask & PERM_LOCKED) == 0) - permission = false; - } - else - { - bool locked = false; - if (!m_scene.Entities.ContainsKey(objectID)) - { - return false; - } - - // If it's not an object, we cant edit it. - if ((!(m_scene.Entities[objectID] is SceneObjectGroup))) - { - return false; - } - - SceneObjectGroup group = (SceneObjectGroup)m_scene.Entities[objectID]; - - UUID objectOwner = group.OwnerID; - locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0); - - // This is an exception to the generic object permission. - // Administrators who lock their objects should not be able to move them, - // however generic object permission should return true. - // This keeps locked objects from being affected by random click + drag actions by accident - // and allows the administrator to grab or delete a locked object. - - // Administrators and estate managers are still able to click+grab locked objects not - // owned by them in the scene - // This is by design. - - if (locked && (moverID == objectOwner)) - return false; - } - return permission; + uint perms = GetObjectPermissions(sp, sog, true); + if((perms & (uint)PermissionMask.Move) == 0) + return false; + return true; } - private bool CanObjectEntry(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene) + private bool CanObjectEntry(SceneObjectGroup sog, bool enteringRegion, Vector3 newPoint) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); - if (m_bypassPermissions) return m_bypassPermissionsValue; + float newX = newPoint.X; + float newY = newPoint.Y; - // allow outide region?? - if (newPoint.X < -1f || newPoint.Y < -1f) + // allow outside region this is needed for crossings + if (newX < -1f || newX > (m_scene.RegionInfo.RegionSizeX + 1.0f) || + newY < -1f || newY > (m_scene.RegionInfo.RegionSizeY + 1.0f) ) return true; - if (newPoint.X > scene.RegionInfo.RegionSizeX + 1.0f || newPoint.Y > scene.RegionInfo.RegionSizeY + 1.0f) - { + + if(sog == null || sog.IsDeleted) + return false; + + if (m_bypassPermissions) + return m_bypassPermissionsValue; + + ILandObject parcel = m_scene.LandChannel.GetLandObject(newX, newY); + if (parcel == null) + return false; + + if ((parcel.LandData.Flags & ((int)ParcelFlags.AllowAPrimitiveEntry)) != 0) return true; - } - - SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objectID]; - - ILandObject land = m_scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); if (!enteringRegion) { - ILandObject fromland = m_scene.LandChannel.GetLandObject(task.AbsolutePosition.X, task.AbsolutePosition.Y); - - if (fromland == land) // Not entering + Vector3 oldPoint = sog.AbsolutePosition; + ILandObject fromparcel = m_scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); + if (fromparcel != null && fromparcel.Equals(parcel)) // it already entered parcel ???? return true; } - if (land == null) - { - return false; - } + UUID userID = sog.OwnerID; + LandData landdata = parcel.LandData; - if ((land.LandData.Flags & ((int)ParcelFlags.AllowAPrimitiveEntry)) != 0) - { + if (landdata.OwnerID == userID) return true; - } - if (!m_scene.Entities.ContainsKey(objectID)) - { - return false; - } - - // If it's not an object, we cant edit it. - if (!(m_scene.Entities[objectID] is SceneObjectGroup)) - { - return false; - } - - - if (GenericParcelPermission(task.OwnerID, newPoint, 0)) - { + if (IsAdministrator(userID)) return true; + + UUID landGroupID = landdata.GroupID; + if (landGroupID != UUID.Zero) + { + if ((parcel.LandData.Flags & ((int)ParcelFlags.AllowGroupObjectEntry)) != 0) + return IsGroupMember(landGroupID, userID, 0); + + if (landdata.IsGroupOwned && IsGroupMember(landGroupID, userID, (ulong)GroupPowers.AllowRez)) + return true; } //Otherwise, false! return false; } - private bool CanReturnObjects(ILandObject land, UUID user, List objects, Scene scene) + private bool OnObjectEnterWithScripts(SceneObjectGroup sog, ILandObject parcel) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + + if(sog == null || sog.IsDeleted) + return false; + + if (m_bypassPermissions) + return m_bypassPermissionsValue; + + if (parcel == null) + return true; + + int checkflags = ((int)ParcelFlags.AllowAPrimitiveEntry); + bool scripts = (sog.ScriptCount() > 0); + if(scripts) + checkflags |= ((int)ParcelFlags.AllowOtherScripts); + + if ((parcel.LandData.Flags & checkflags) == checkflags) + return true; + + UUID userID = sog.OwnerID; + LandData landdata = parcel.LandData; + + if (landdata.OwnerID == userID) + return true; + + if (IsAdministrator(userID)) + return true; + + UUID landGroupID = landdata.GroupID; + if (landGroupID != UUID.Zero) + { + checkflags = (int)ParcelFlags.AllowGroupObjectEntry; + if(scripts) + checkflags |= ((int)ParcelFlags.AllowGroupScripts); + + if ((parcel.LandData.Flags & checkflags) == checkflags) + return IsGroupMember(landGroupID, userID, 0); + + if (landdata.IsGroupOwned && IsGroupMember(landGroupID, userID, (ulong)GroupPowers.AllowRez)) + return true; + } + + //Otherwise, false! + return false; + } + + + private bool CanReturnObjects(ILandObject land, ScenePresence sp, List objects) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - GroupPowers powers; - ILandObject l; + if(sp == null) + return true; // assuming that in this case rights are as owner - ScenePresence sp = scene.GetScenePresence(user); - if (sp == null) - return false; + UUID userID = sp.UUID; + bool isPrivUser = sp.IsGod || IsEstateManager(userID); IClientAPI client = sp.ControllingClient; + ulong powers = 0; + ILandObject l; + foreach (SceneObjectGroup g in new List(objects)) { - // Any user can return their own objects at any time - // - if (GenericObjectPermission(user, g.UUID, false)) + if(g.IsAttachment) + { + objects.Remove(g); + continue; + } + + if (isPrivUser || g.OwnerID == userID) continue; // This is a short cut for efficiency. If land is non-null, @@ -1395,39 +1717,40 @@ namespace OpenSim.Region.CoreModules.World.Permissions else { Vector3 pos = g.AbsolutePosition; - - l = scene.LandChannel.GetLandObject(pos.X, pos.Y); + l = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); } // If it's not over any land, then we can't do a thing - if (l == null) + if (l == null || l.LandData == null) { objects.Remove(g); continue; } + LandData ldata = l.LandData; // If we own the land outright, then allow // - if (l.LandData.OwnerID == user) + if (ldata.OwnerID == userID) continue; // Group voodoo // - if (l.LandData.IsGroupOwned) + if (ldata.IsGroupOwned) { - powers = (GroupPowers)client.GetGroupPowers(l.LandData.GroupID); + UUID lGroupID = ldata.GroupID; // Not a group member, or no rights at all // - if (powers == (GroupPowers)0) + powers = client.GetGroupPowers(lGroupID); + if(powers == 0) { objects.Remove(g); continue; } - + // Group deeded object? // - if (g.OwnerID == l.LandData.GroupID && - (powers & GroupPowers.ReturnGroupOwned) == (GroupPowers)0) + if (g.OwnerID == lGroupID && + (powers & (ulong)GroupPowers.ReturnGroupOwned) == 0) { objects.Remove(g); continue; @@ -1435,14 +1758,14 @@ namespace OpenSim.Region.CoreModules.World.Permissions // Group set object? // - if (g.GroupID == l.LandData.GroupID && - (powers & GroupPowers.ReturnGroupSet) == (GroupPowers)0) + if (g.GroupID == lGroupID && + (powers & (ulong)GroupPowers.ReturnGroupSet) == 0) { objects.Remove(g); continue; } - if ((powers & GroupPowers.ReturnNonGroup) == (GroupPowers)0) + if ((powers & (ulong)GroupPowers.ReturnNonGroup) == 0) { objects.Remove(g); continue; @@ -1465,41 +1788,41 @@ namespace OpenSim.Region.CoreModules.World.Permissions return true; } - private bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition, Scene scene) + private bool CanRezObject(int objectCount, UUID userID, Vector3 objectPosition) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); - if (m_bypassPermissions) return m_bypassPermissionsValue; + if (m_bypassPermissions) + return m_bypassPermissionsValue; // m_log.DebugFormat("[PERMISSIONS MODULE]: Checking rez object at {0} in {1}", objectPosition, m_scene.Name); ILandObject parcel = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); - if (parcel == null) + if (parcel == null || parcel.LandData == null) return false; - if ((parcel.LandData.Flags & (uint)ParcelFlags.CreateObjects) != 0) - { + LandData landdata = parcel.LandData; + if ((userID == landdata.OwnerID)) return true; - } - else if ((owner == parcel.LandData.OwnerID) || IsAdministrator(owner)) - { + + if ((landdata.Flags & (uint)ParcelFlags.CreateObjects) != 0) return true; - } - else if (((parcel.LandData.Flags & (uint)ParcelFlags.CreateGroupObjects) != 0) - && (parcel.LandData.GroupID != UUID.Zero) && IsGroupMember(parcel.LandData.GroupID, owner, 0)) - { + + if(IsAdministrator(userID)) return true; - } - else if (parcel.LandData.GroupID != UUID.Zero && IsGroupMember(parcel.LandData.GroupID, owner, (ulong)GroupPowers.AllowRez)) + + if(landdata.GroupID != UUID.Zero) { - return true; - } - else - { - return false; + if ((landdata.Flags & (uint)ParcelFlags.CreateGroupObjects) != 0) + return IsGroupMember(landdata.GroupID, userID, 0); + + if (landdata.IsGroupOwned && IsGroupMember(landdata.GroupID, userID, (ulong)GroupPowers.AllowRez)) + return true; } + + return false; } - private bool CanRunConsoleCommand(UUID user, Scene requestFromScene) + private bool CanRunConsoleCommand(UUID user) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1508,15 +1831,43 @@ namespace OpenSim.Region.CoreModules.World.Permissions return IsAdministrator(user); } - private bool CanRunScript(UUID script, UUID objectID, UUID user, Scene scene) + private bool CanRunScript(TaskInventoryItem scriptitem, SceneObjectPart part) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return true; + if(scriptitem == null || part == null) + return false; + + SceneObjectGroup sog = part.ParentGroup; + if(sog == null) + return false; + + Vector3 pos = sog.AbsolutePosition; + ILandObject parcel = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (parcel == null) + return false; + + LandData ldata = parcel.LandData; + if(ldata == null) + return false; + + uint lflags = ldata.Flags; + + if ((lflags & (uint)ParcelFlags.AllowOtherScripts) != 0) + return true; + + if ((part.OwnerID == ldata.OwnerID)) + return true; + + if (((lflags & (uint)ParcelFlags.AllowGroupScripts) != 0) + && (ldata.GroupID != UUID.Zero) && (ldata.GroupID == part.GroupID)) + return true; + + return GenericEstatePermission(part.OwnerID); } - private bool CanSellParcel(UUID user, ILandObject parcel, Scene scene) + private bool CanSellParcel(UUID user, ILandObject parcel) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1524,7 +1875,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions return GenericParcelOwnerPermission(user, parcel, (ulong)GroupPowers.LandSetSale, true); } - private bool CanSellGroupObject(UUID userID, UUID groupID, Scene scene) + private bool CanSellGroupObject(UUID userID, UUID groupID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1532,66 +1883,159 @@ namespace OpenSim.Region.CoreModules.World.Permissions return IsGroupMember(groupID, userID, (ulong)GroupPowers.ObjectSetForSale); } - private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene) + private bool CanSellObjectByUserID(SceneObjectGroup sog, UUID userID, byte saleType) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(stealer,objectID, false); + if (sog == null || sog.IsDeleted || userID == UUID.Zero) + return false; + + // sell is not a attachment op + if(sog.IsAttachment) + return false; + + if(IsAdministrator(userID)) + return true; + + uint sogEffectiveOwnerPerms = sog.EffectiveOwnerPerms; + if((sogEffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + return false; + + if(saleType == (byte)SaleType.Copy && + (sogEffectiveOwnerPerms & (uint)PermissionMask.Copy) == 0) + return false; + + UUID sogOwnerID = sog.OwnerID; + + if(sogOwnerID == userID) + return true; + + // else only group owned can be sold by members with powers + UUID sogGroupID = sog.GroupID; + if(sog.OwnerID != sogGroupID || sogGroupID == UUID.Zero) + return false; + + return IsGroupMember(sogGroupID, userID, (ulong)GroupPowers.ObjectSetForSale); } - private bool CanTakeCopyObject(UUID objectID, UUID userID, Scene inScene) + private bool CanSellObject(SceneObjectGroup sog, ScenePresence sp, byte saleType) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - bool permission = GenericObjectPermission(userID, objectID, false); + if (sog == null || sog.IsDeleted || sp == null || sp.IsDeleted) + return false; - SceneObjectGroup so = (SceneObjectGroup)m_scene.Entities[objectID]; + // sell is not a attachment op + if(sog.IsAttachment) + return false; - if (!permission) - { - if (!m_scene.Entities.ContainsKey(objectID)) - { - return false; - } + if(sp.IsGod) + return true; - // If it's not an object, we cant edit it. - if (!(m_scene.Entities[objectID] is SceneObjectGroup)) - { - return false; - } + uint sogEffectiveOwnerPerms = sog.EffectiveOwnerPerms; + if((sogEffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + return false; - // UUID taskOwner = null; - // Added this because at this point in time it wouldn't be wise for - // the administrator object permissions to take effect. - // UUID objectOwner = task.OwnerID; + if(saleType == (byte)SaleType.Copy && + (sogEffectiveOwnerPerms & (uint)PermissionMask.Copy) == 0) + return false; - if ((so.RootPart.EveryoneMask & PERM_COPY) != 0) - permission = true; - } + UUID userID = sp.UUID; + UUID sogOwnerID = sog.OwnerID; - if (so.OwnerID != userID) - { - if ((so.GetEffectivePermissions() & (PERM_COPY | PERM_TRANS)) != (PERM_COPY | PERM_TRANS)) - permission = false; - } - else - { - if ((so.GetEffectivePermissions() & PERM_COPY) != PERM_COPY) - permission = false; - } + if(sogOwnerID == userID) + return true; - return permission; + // else only group owned can be sold by members with powers + UUID sogGroupID = sog.GroupID; + if(sog.OwnerID != sogGroupID || sogGroupID == UUID.Zero) + return false; + + ulong powers = 0; + if(!GroupMemberPowers(sogGroupID, sp, ref powers)) + return false; + + if((powers & (ulong)GroupPowers.ObjectSetForSale) == 0) + return false; + + return true; } - private bool CanTerraformLand(UUID user, Vector3 position, Scene requestFromScene) + private bool CanTakeObject(SceneObjectGroup sog, ScenePresence sp) + { + // ignore locked, viewers shell ask for confirmation + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + if (sog == null || sog.IsDeleted || sp == null || sp.IsDeleted) + return false; + + // take is not a attachment op + if(sog.IsAttachment) + return false; + + UUID sogOwnerID = sog.OwnerID; + UUID spID = sp.UUID; + + if(sogOwnerID == spID) + return true; + + if (sp.IsGod) + return true; + + if((sog.EffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + return false; + + if (IsFriendWithPerms(sog.UUID, sogOwnerID)) + return true; + + UUID sogGroupID = sog.GroupID; + if (sogGroupID != UUID.Zero) + { + ulong powers = 0; + if(GroupMemberPowers(sogGroupID, sp, ref powers)) + { + if(sogGroupID == sogOwnerID) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return true; + } + return (sog.EffectiveGroupPerms & (uint)PermissionMask.Modify) != 0; + } + } + return false; + } + + private bool CanTakeCopyObject(SceneObjectGroup sog, ScenePresence sp) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + if (sog == null || sog.IsDeleted || sp == null || sp.IsDeleted) + return false; + + // refuse on attachments + if(sog.IsAttachment && !sp.IsGod) + return false; + + uint perms = GetObjectPermissions(sp, sog, true); + if((perms & (uint)PermissionMask.Copy) == 0) + return false; + + if(sog.OwnerID != sp.UUID && (perms & (uint)PermissionMask.Transfer) == 0) + return false; + return true; + } + + private bool CanTerraformLand(UUID userID, Vector3 position) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; // Estate override - if (GenericEstatePermission(user)) + if (GenericEstatePermission(userID)) return true; float X = position.X; @@ -1609,13 +2053,19 @@ namespace OpenSim.Region.CoreModules.World.Permissions ILandObject parcel = m_scene.LandChannel.GetLandObject(X, Y); if (parcel == null) return false; - - // Others allowed to terraform? - if ((parcel.LandData.Flags & ((int)ParcelFlags.AllowTerraform)) != 0) + + LandData landdata = parcel.LandData; + if (landdata == null) + return false; + + if ((landdata.Flags & ((int)ParcelFlags.AllowTerraform)) != 0) return true; - // Land owner can terraform too - if (parcel != null && GenericParcelPermission(user, parcel, (ulong)GroupPowers.AllowEditLand)) + if(landdata.OwnerID == userID) + return true; + + if (landdata.IsGroupOwned && parcel.LandData.GroupID != UUID.Zero && + IsGroupMember(landdata.GroupID, userID, (ulong)GroupPowers.AllowEditLand)) return true; return false; @@ -1629,15 +2079,19 @@ namespace OpenSim.Region.CoreModules.World.Permissions /// /// /// - private bool CanViewScript(UUID script, UUID objectID, UUID user, Scene scene) + private bool CanViewScript(UUID script, UUID objectID, UUID userID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; + // A god is a god is a god + if (IsAdministrator(userID)) + return true; + if (objectID == UUID.Zero) // User inventory { IInventoryService invService = m_scene.InventoryService; - InventoryItemBase assetRequestItem = invService.GetItem(user, script); + InventoryItemBase assetRequestItem = invService.GetItem(userID, script); if (assetRequestItem == null && LibraryRootFolder != null) // Library item { assetRequestItem = LibraryRootFolder.FindItem(script); @@ -1657,60 +2111,53 @@ namespace OpenSim.Region.CoreModules.World.Permissions // readable only if it's really full perms // if ((assetRequestItem.CurrentPermissions & +/* ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) +*/ + (uint)(PermissionMask.Modify | PermissionMask.Copy)) != + (uint)(PermissionMask.Modify | PermissionMask.Copy)) return false; } else // Prim inventory { - SceneObjectPart part = scene.GetSceneObjectPart(objectID); - + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); if (part == null) return false; - if (part.OwnerID != user) - { - if (part.GroupID == UUID.Zero) - return false; + SceneObjectGroup sog = part.ParentGroup; + if (sog == null) + return false; - if (!IsGroupMember(part.GroupID, user, 0)) - return false; - - if ((part.GroupMask & (uint)PermissionMask.Modify) == 0) - return false; - } - else - { - if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) - return false; - } + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; TaskInventoryItem ti = part.Inventory.GetInventoryItem(script); - if (ti == null) +// if (ti == null || ti.InvType != (int)InventoryType.LSL) + if (ti == null) // legacy may not have type return false; - if (ti.OwnerID != user) - { - if (ti.GroupID == UUID.Zero) - return false; - - if (!IsGroupMember(ti.GroupID, user, 0)) - return false; - } + uint itperms = GetObjectItemPermissions(userID, ti); // Require full perms - if ((ti.CurrentPermissions & - ((uint)PermissionMask.Modify | + + if ((itperms & +/* + ((uint)(PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) +*/ + (uint)(PermissionMask.Modify | PermissionMask.Copy)) != + (uint)(PermissionMask.Modify | PermissionMask.Copy)) return false; } @@ -1725,15 +2172,19 @@ namespace OpenSim.Region.CoreModules.World.Permissions /// /// /// - private bool CanViewNotecard(UUID notecard, UUID objectID, UUID user, Scene scene) + private bool CanViewNotecard(UUID notecard, UUID objectID, UUID userID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; + // A god is a god is a god + if (IsAdministrator(userID)) + return true; + if (objectID == UUID.Zero) // User inventory { IInventoryService invService = m_scene.InventoryService; - InventoryItemBase assetRequestItem = invService.GetItem(user, notecard); + InventoryItemBase assetRequestItem = invService.GetItem(userID, notecard); if (assetRequestItem == null && LibraryRootFolder != null) // Library item { assetRequestItem = LibraryRootFolder.FindItem(notecard); @@ -1751,40 +2202,29 @@ namespace OpenSim.Region.CoreModules.World.Permissions } else // Prim inventory { - SceneObjectPart part = scene.GetSceneObjectPart(objectID); - + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); if (part == null) return false; - if (part.OwnerID != user) - { - if (part.GroupID == UUID.Zero) - return false; + SceneObjectGroup sog = part.ParentGroup; + if (sog == null) + return false; - if (!IsGroupMember(part.GroupID, user, 0)) - return false; - } - - if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) return false; TaskInventoryItem ti = part.Inventory.GetInventoryItem(notecard); +// if (ti == null || ti.InvType != (int)InventoryType.Notecard) if (ti == null) return false; - if (ti.OwnerID != user) - { - if (ti.GroupID == UUID.Zero) - return false; - - if (!IsGroupMember(ti.GroupID, user, 0)) - return false; - } + uint itperms = GetObjectItemPermissions(userID, ti); // Notecards are always readable unless no copy // - if ((ti.CurrentPermissions & + if ((itperms & (uint)PermissionMask.Copy) != (uint)PermissionMask.Copy) return false; @@ -1800,7 +2240,14 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(userID, objectID, false); + SceneObjectGroup sog = m_scene.GetGroupByPrim(objectID); + if (sog == null) + return false; + + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + return true; } private bool CanDelinkObject(UUID userID, UUID objectID) @@ -1808,10 +2255,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(userID, objectID, false); + SceneObjectGroup sog = m_scene.GetGroupByPrim(objectID); + if (sog == null) + return false; + + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + return true; } - private bool CanBuyLand(UUID userID, ILandObject parcel, Scene scene) + private bool CanBuyLand(UUID userID, ILandObject parcel) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1824,6 +2278,130 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); + if (part == null) + return false; + + SceneObjectGroup sog = part.ParentGroup; + if (sog == null) + return false; + + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + + TaskInventoryItem ti = part.Inventory.GetInventoryItem(itemID); + if(ti == null) + return false; + + uint itperms = GetObjectItemPermissions(userID, ti); + + if((itperms & (uint)PermissionMask.Copy) == 0) + return false; + + if(sog.OwnerID != userID && (itperms & (uint)PermissionMask.Transfer) == 0) + return false; + + return true; + } + + // object inventory to object inventory item drag and drop + private bool CanDoObjectInvToObjectInv(TaskInventoryItem item, SceneObjectPart sourcePart, SceneObjectPart destPart) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + + if (sourcePart == null || destPart == null || item == null) + return false; + + if (m_bypassPermissions) + return m_bypassPermissionsValue; + + SceneObjectGroup srcsog = sourcePart.ParentGroup; + SceneObjectGroup destsog = destPart.ParentGroup; + if (srcsog == null || destsog == null) + return false; + + // dest is locked + if((destsog.EffectiveOwnerPerms & (uint)PermissionMask.Move) == 0) + return false; + + uint itperms = item.CurrentPermissions; + + // if item is no copy the source is modifed + if((itperms & (uint)PermissionMask.Copy) == 0 && (srcsog.EffectiveOwnerPerms & (uint)PermissionMask.Modify) == 0) + return false; + + UUID srcOwner = srcsog.OwnerID; + UUID destOwner = destsog.OwnerID; + bool notSameOwner = srcOwner != destOwner; + + if(notSameOwner) + { + if((itperms & (uint)PermissionMask.Transfer) == 0) + return false; + + // scripts can't be droped + if(item.InvType == (int)InventoryType.LSL) + return false; + + if((destsog.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0) + return false; + } + else + { + if((destsog.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0 && + (destsog.EffectiveOwnerPerms & (uint)PermissionMask.Modify) == 0) + return false; + } + + return true; + } + + private bool CanDropInObjectInv(InventoryItemBase item, ScenePresence sp, SceneObjectPart destPart) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + + if (sp == null || sp.IsDeleted || destPart == null || item == null) + return false; + + SceneObjectGroup destsog = destPart.ParentGroup; + if (destsog == null || destsog.IsDeleted) + return false; + + if (m_bypassPermissions) + return m_bypassPermissionsValue; + + if(sp.IsGod) + return true; + + // dest is locked + if((destsog.EffectiveOwnerPerms & (uint)PermissionMask.Move) == 0) + return false; + + UUID destOwner = destsog.OwnerID; + UUID spID = sp.UUID; + bool spNotOwner = spID != destOwner; + + // scripts can't be droped + if(spNotOwner && item.InvType == (int)InventoryType.LSL) + return false; + + if(spNotOwner || item.Owner != destOwner) + { + // no copy item will be moved if it has transfer + uint itperms = item.CurrentPermissions; + if((itperms & (uint)PermissionMask.Transfer) == 0) + return false; + } + + // allowdrop is a root part thing and does bypass modify rights + if((destsog.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0) + return true; + + uint perms = GetObjectPermissions(spID, destsog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + return true; } @@ -1832,6 +2410,23 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); + if (part == null) + return false; + + SceneObjectGroup sog = part.ParentGroup; + if (sog == null) + return false; + + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + + TaskInventoryItem ti = part.Inventory.GetInventoryItem(itemID); + if(ti == null) + return false; + + //TODO item perm ? return true; } @@ -1848,26 +2443,23 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); ScenePresence p = m_scene.GetScenePresence(userID); - if (part == null || p == null) + if (p == null) return false; - if (!IsAdministrator(userID)) + SceneObjectGroup sog = m_scene.GetGroupByPrim(objectID); + if (sog == null) + return false; + + uint perms = GetObjectPermissions(userID, sog, true); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + + if ((int)InventoryType.LSL == invType) { - if (part.OwnerID != userID) - { - // Group permissions - if ((part.GroupID == UUID.Zero) || (p.ControllingClient.GetGroupPowers(part.GroupID) == 0) || ((part.GroupMask & (uint)PermissionMask.Modify) == 0)) - return false; - } else { - if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) - return false; - } - if ((int)InventoryType.LSL == invType) - if (m_allowedScriptCreators == UserSet.Administrators) - return false; + if (m_allowedScriptCreators == UserSet.Administrators) + return false; } return true; @@ -1941,22 +2533,22 @@ namespace OpenSim.Region.CoreModules.World.Permissions return true; } - private bool CanResetScript(UUID prim, UUID script, UUID agentID, Scene scene) + private bool CanResetScript(UUID primID, UUID script, UUID agentID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - SceneObjectPart part = m_scene.GetSceneObjectPart(prim); + SceneObjectGroup sog = m_scene.GetGroupByPrim(primID); + if (sog == null) + return false; - // If we selected a sub-prim to reset, prim won't represent the object, but only a part. - // We have to check the permissions of the object, though. - if (part.ParentID != 0) prim = part.ParentUUID; - - // You can reset the scripts in any object you can edit - return GenericObjectPermission(agentID, prim, false); + uint perms = GetObjectPermissions(agentID, sog, false); + if((perms & (uint)PermissionMask.Modify) == 0) // ?? + return false; + return true; } - private bool CanCompileScript(UUID ownerUUID, int scriptType, Scene scene) + private bool CanCompileScript(UUID ownerUUID, int scriptType) { //m_log.DebugFormat("check if {0} is allowed to compile {1}", ownerUUID, scriptType); switch (scriptType) { @@ -2014,7 +2606,14 @@ namespace OpenSim.Region.CoreModules.World.Permissions // "[PERMISSIONS]: Checking CanControlPrimMedia for {0} on {1} face {2} with control permissions {3}", // agentID, primID, face, me.ControlPermissions); - return GenericObjectPermission(agentID, part.ParentGroup.UUID, true); + SceneObjectGroup sog = part.ParentGroup; + if (sog == null) + return false; + + uint perms = GetObjectPermissions(agentID, sog, false); + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + return true; } private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int face) diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs index 8bac9e6623..bb3b8605b5 100644 --- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs +++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs @@ -61,6 +61,8 @@ namespace OpenSim.Region.CoreModules.World.Region protected IDialogModule m_DialogModule = null; protected string m_MarkerPath = String.Empty; private int[] m_CurrentAlerts = null; + protected bool m_shortCircuitDelays = false; + protected bool m_rebootAll = false; public void Initialise(IConfigSource config) { @@ -69,6 +71,9 @@ namespace OpenSim.Region.CoreModules.World.Region { m_MarkerPath = restartConfig.GetString("MarkerPath", String.Empty); } + IConfig startupConfig = config.Configs["Startup"]; + m_shortCircuitDelays = startupConfig.GetBoolean("SkipDelayOnEmptyRegion", false); + m_rebootAll = startupConfig.GetBoolean("InworldRestartShutsDown", false); } public void AddRegion(Scene scene) @@ -250,6 +255,14 @@ namespace OpenSim.Region.CoreModules.World.Region private void OnTimer(object source, ElapsedEventArgs e) { int nextInterval = DoOneNotice(true); + if (m_shortCircuitDelays) + { + if (CountAgents() == 0) + { + m_Scene.RestartNow(); + return; + } + } SetTimer(nextInterval); } @@ -349,5 +362,35 @@ namespace OpenSim.Region.CoreModules.World.Region { } } + + int CountAgents() + { + m_log.Info("[RESTART MODULE]: Counting affected avatars"); + int agents = 0; + + if (m_rebootAll) + { + foreach (Scene s in SceneManager.Instance.Scenes) + { + foreach (ScenePresence sp in s.GetScenePresences()) + { + if (!sp.IsChildAgent && !sp.IsNPC) + agents++; + } + } + } + else + { + foreach (ScenePresence sp in m_Scene.GetScenePresences()) + { + if (!sp.IsChildAgent && !sp.IsNPC) + agents++; + } + } + + m_log.InfoFormat("[RESTART MODULE]: Avatars in region: {0}", agents); + + return agents; + } } } diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs index 04b6f00a39..167f6b50d2 100644 --- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs +++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs @@ -105,8 +105,9 @@ namespace OpenSim.Region.CoreModules.World.Vegetation if (rootPart.Shape.PCode != (byte)PCode.Grass) AdaptTree(ref shape); - m_scene.AddNewSceneObject(sceneObject, true); sceneObject.SetGroup(groupID, null); + m_scene.AddNewSceneObject(sceneObject, true); + sceneObject.AggregatePerms(); return sceneObject; } diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 0c4017eb88..e7c2428708 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -278,6 +278,8 @@ namespace OpenSim.Region.Framework.Interfaces /// void ProcessInventoryBackup(ISimulationDataService datastore); + void AggregateInnerPerms(ref uint owner, ref uint group, ref uint everyone); + uint MaskEffectivePermissions(); void ApplyNextOwnerPermissions(); diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 9585082719..1b690bad3f 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -102,6 +102,8 @@ namespace OpenSim.Region.Framework.Interfaces ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx); + bool CrossAgentCreateFarChild(ScenePresence agent, GridRegion neighbourRegion, Vector3 pos, EntityTransferContext ctx); + bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition); } diff --git a/OpenSim/Region/Framework/Interfaces/IEtcdModule.cs b/OpenSim/Region/Framework/Interfaces/IEtcdModule.cs new file mode 100644 index 0000000000..123cb67308 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IEtcdModule.cs @@ -0,0 +1,37 @@ +/* + * 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; + +public interface IEtcdModule +{ + bool Store(string k, string v); + bool Store(string k, string v, int ttl); + string Get(string k); + void Watch(string k, Action callback); + void Delete(string k); +} diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 1e9711d0b4..827f91ee56 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -3161,7 +3161,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (Action d in handler.GetInvocationList()) { - m_log.InfoFormat("[EVENT MANAGER]: TriggerSceneShuttingDown invoque {0}", d.Method.Name.ToString()); + m_log.InfoFormat("[EVENT MANAGER]: TriggerSceneShuttingDown invoke {0}", d.Method.Name.ToString()); try { d(s); diff --git a/OpenSim/Region/Framework/Scenes/GodController.cs b/OpenSim/Region/Framework/Scenes/GodController.cs index 7ed80f6051..937236664f 100644 --- a/OpenSim/Region/Framework/Scenes/GodController.cs +++ b/OpenSim/Region/Framework/Scenes/GodController.cs @@ -246,17 +246,14 @@ namespace OpenSim.Region.Framework.Scenes { bool newstate = false; if(m_forceGodModeAlwaysOn) - newstate = true; - else + newstate = m_viewergodlevel >= 200; + if(state != null) { - if(state != null) - { - OSDMap s = (OSDMap)state; + OSDMap s = (OSDMap)state; - if (s.ContainsKey("ViewerUiIsGod")) - newstate = s["ViewerUiIsGod"].AsBoolean(); - m_lastLevelToViewer = m_viewergodlevel; // we are not changing viewer level by default - } + if (s.ContainsKey("ViewerUiIsGod")) + newstate = s["ViewerUiIsGod"].AsBoolean(); + m_lastLevelToViewer = m_viewergodlevel; // we are not changing viewer level by default } UpdateGodLevels(newstate); } @@ -264,6 +261,11 @@ namespace OpenSim.Region.Framework.Scenes public void HasMovedAway() { m_lastLevelToViewer = 0; + if(m_forceGodModeAlwaysOn) + { + m_viewergodlevel = m_rightsGodLevel; + m_godlevel = m_rightsGodLevel; + } } public int UserLevel diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index e4aa196497..d81d8a269a 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -495,6 +495,7 @@ namespace OpenSim.Region.Framework.Scenes m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero; + m_skippedUpdates = 1000; m_group.SendGroupRootTerseUpdate(); // m_group.RootPart.ScheduleTerseUpdate(); } @@ -517,6 +518,7 @@ namespace OpenSim.Region.Framework.Scenes return; if (m_running && !m_waitingCrossing) StartTimer(); + m_skippedUpdates = 1000; } } @@ -643,10 +645,15 @@ namespace OpenSim.Region.Framework.Scenes m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero; m_group.SendGroupRootTerseUpdate(); - // m_group.RootPart.ScheduleTerseUpdate(); + m_frames.Clear(); } + Vector3 m_lastPosUpdate; + Quaternion m_lastRotationUpdate; + Vector3 m_currentVel; + int m_skippedUpdates; + private void DoOnTimer(double tickDuration) { if (m_skipLoops > 0) @@ -665,6 +672,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_group.RootPart.Velocity != Vector3.Zero) { m_group.RootPart.Velocity = Vector3.Zero; + m_skippedUpdates = 1000; m_group.SendGroupRootTerseUpdate(); } return; @@ -677,7 +685,9 @@ namespace OpenSim.Region.Framework.Scenes // retry to set the position that evtually caused the outbound // if still outside region this will call startCrossing below m_isCrossing = false; + m_skippedUpdates = 1000; m_group.AbsolutePosition = m_nextPosition; + if (!m_isCrossing) { StopTimer(); @@ -700,10 +710,12 @@ namespace OpenSim.Region.Framework.Scenes } m_currentFrame = m_frames[0]; - m_currentFrame.TimeMS += (int)tickDuration; } - //force a update on a keyframe transition m_nextPosition = m_group.AbsolutePosition; + m_currentVel = (Vector3)m_currentFrame.Position - m_nextPosition; + m_currentVel /= (m_currentFrame.TimeMS * 0.001f); + + m_currentFrame.TimeMS += (int)tickDuration; update = true; } @@ -712,7 +724,7 @@ namespace OpenSim.Region.Framework.Scenes // Do the frame processing double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration; - if (remainingSteps <= 0.0) + if (remainingSteps <= 1.0) { m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero; @@ -720,92 +732,71 @@ namespace OpenSim.Region.Framework.Scenes m_nextPosition = (Vector3)m_currentFrame.Position; m_group.AbsolutePosition = m_nextPosition; - // we are sending imediate updates, no doing force a extra terseUpdate - // m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); - m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation; lock (m_frames) { m_frames.RemoveAt(0); if (m_frames.Count > 0) + { m_currentFrame = m_frames[0]; + m_currentVel = (Vector3)m_currentFrame.Position - m_nextPosition; + m_currentVel /= (m_currentFrame.TimeMS * 0.001f); + m_group.RootPart.Velocity = m_currentVel; + m_currentFrame.TimeMS += (int)tickDuration; + } + else + m_group.RootPart.Velocity = Vector3.Zero; } - update = true; } else { - float completed = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; - bool lastStep = m_currentFrame.TimeMS <= tickDuration; + bool lastSteps = remainingSteps < 4; + Vector3 currentPosition = m_group.AbsolutePosition; + Vector3 motionThisFrame = (Vector3)m_currentFrame.Position - currentPosition; + motionThisFrame /= (float)remainingSteps; + + m_nextPosition = currentPosition + motionThisFrame; - Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; - Vector3 motionThisFrame = v / (float)remainingSteps; - v = v * 1000 / m_currentFrame.TimeMS; - - m_nextPosition = m_group.AbsolutePosition + motionThisFrame; - - if (Vector3.Mag(motionThisFrame) >= 0.05f) - update = true; - - //int totalSteps = m_currentFrame.TimeTotal / (int)tickDuration; - //m_log.DebugFormat("KeyframeMotion.OnTimer: step {0}/{1}, curPosition={2}, finalPosition={3}, motionThisStep={4} (scene {5})", - // totalSteps - remainingSteps + 1, totalSteps, m_group.AbsolutePosition, m_currentFrame.Position, motionThisStep, m_scene.RegionInfo.RegionName); - - if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation) + Quaternion currentRotation = m_group.GroupRotation; + if ((Quaternion)m_currentFrame.Rotation != currentRotation) { - Quaternion current = m_group.GroupRotation; - + float completed = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed); step.Normalize(); - /* use simpler change detection - * float angle = 0; - - float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; - float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; - float aa_bb = aa * bb; - - if (aa_bb == 0) - { - angle = 0; - } - else - { - float ab = current.X * step.X + - current.Y * step.Y + - current.Z * step.Z + - current.W * step.W; - float q = (ab * ab) / aa_bb; - - if (q > 1.0f) - { - angle = 0; - } - else - { - angle = (float)Math.Acos(2 * q - 1); - } - } - - if (angle > 0.01f) - */ - if (Math.Abs(step.X - current.X) > 0.001f - || Math.Abs(step.Y - current.Y) > 0.001f - || Math.Abs(step.Z - current.Z) > 0.001f) - // assuming w is a dependente var - { -// m_group.UpdateGroupRotationR(step); - m_group.RootPart.RotationOffset = step; - - //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); + m_group.RootPart.RotationOffset = step; + if (Math.Abs(step.X - m_lastRotationUpdate.X) > 0.001f + || Math.Abs(step.Y - m_lastRotationUpdate.Y) > 0.001f + || Math.Abs(step.Z - m_lastRotationUpdate.Z) > 0.001f) update = true; - } } - } - if (update) - { m_group.AbsolutePosition = m_nextPosition; + if(lastSteps) + m_group.RootPart.Velocity = Vector3.Zero; + else + m_group.RootPart.Velocity = m_currentVel; + + if(!update && ( + lastSteps || + m_skippedUpdates * tickDuration > 0.5 || + Math.Abs(m_nextPosition.X - currentPosition.X) > 5f || + Math.Abs(m_nextPosition.Y - currentPosition.Y) > 5f || + Math.Abs(m_nextPosition.Z - currentPosition.Z) > 5f + )) + { + update = true; + } + else + m_skippedUpdates++; + + } + if(update) + { + m_lastPosUpdate = m_nextPosition; + m_lastRotationUpdate = m_group.GroupRotation; + m_skippedUpdates = 0; m_group.SendGroupRootTerseUpdate(); } } @@ -850,6 +841,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_group.RootPart.Velocity != Vector3.Zero) { m_group.RootPart.Velocity = Vector3.Zero; + m_skippedUpdates = 1000; m_group.SendGroupRootTerseUpdate(); // m_group.RootPart.ScheduleTerseUpdate(); } @@ -862,6 +854,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_group != null) { m_group.RootPart.Velocity = Vector3.Zero; + m_skippedUpdates = 1000; m_group.SendGroupRootTerseUpdate(); // m_group.RootPart.ScheduleTerseUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index cbf40c80c5..53ca849fb1 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -172,14 +172,22 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { + SceneObjectGroup sog = ((SceneObjectPart)entity).ParentGroup; // Attachments are high priority, - if (((SceneObjectPart)entity).ParentGroup.IsAttachment) + if (sog.IsAttachment) return 2; + + + if(presence.ParentPart != null) + { + if(presence.ParentPart.ParentGroup == sog) + return 2; + } pqueue = ComputeDistancePriority(client, entity, false); // Non physical prims are lower priority than physical prims - PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; + PhysicsActor physActor = sog.RootPart.PhysActor; if (physActor == null || !physActor.IsPhysical) pqueue++; } @@ -302,6 +310,17 @@ namespace OpenSim.Region.Framework.Scenes else { SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; + if(presence.ParentPart != null) + { + if(presence.ParentPart.ParentGroup == group) + return pqueue; + } + if(group.IsAttachment) + { + if(group.RootPart.LocalId == presence.LocalId) + return pqueue; + } + float bradius = group.GetBoundsRadius(); Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter(); distance = Vector3.Distance(presencePos, grppos); diff --git a/OpenSim/Region/Framework/Scenes/SOPMaterial.cs b/OpenSim/Region/Framework/Scenes/SOPMaterial.cs index 651c52eee5..d38ef615ef 100644 --- a/OpenSim/Region/Framework/Scenes/SOPMaterial.cs +++ b/OpenSim/Region/Framework/Scenes/SOPMaterial.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Framework; namespace OpenSim.Region.Framework.Scenes @@ -90,6 +91,87 @@ namespace OpenSim.Region.Framework.Scenes else return 0; } + } + public class FaceMaterial + { + public UUID ID; + public UUID NormalMapID = UUID.Zero; + public float NormalOffsetX = 0.0f; + public float NormalOffsetY = 0.0f; + public float NormalRepeatX = 1.0f; + public float NormalRepeatY = 1.0f; + public float NormalRotation = 0.0f; + + public UUID SpecularMapID = UUID.Zero; + public float SpecularOffsetX = 0.0f; + public float SpecularOffsetY = 0.0f; + public float SpecularRepeatX = 1.0f; + public float SpecularRepeatY = 1.0f; + public float SpecularRotation = 0.0f; + + public Color4 SpecularLightColor = new Color4(255,255,255,255); + public Byte SpecularLightExponent = 51; + public Byte EnvironmentIntensity = 0; + public Byte DiffuseAlphaMode = 1; + public Byte AlphaMaskCutoff = 0; + + public FaceMaterial() + { } + + public FaceMaterial(UUID pID, OSDMap mat) + { + ID = pID; + if(mat == null) + return; + float scale = 0.0001f; + NormalMapID = mat["NormMap"].AsUUID(); + NormalOffsetX = scale * (float)mat["NormOffsetX"].AsReal(); + NormalOffsetY = scale * (float)mat["NormOffsetY"].AsReal(); + NormalRepeatX = scale * (float)mat["NormRepeatX"].AsReal(); + NormalRepeatY = scale * (float)mat["NormRepeatY"].AsReal(); + NormalRotation = scale * (float)mat["NormRotation"].AsReal(); + + SpecularMapID = mat["SpecMap"].AsUUID(); + SpecularOffsetX = scale * (float)mat["SpecOffsetX"].AsReal(); + SpecularOffsetY = scale * (float)mat["SpecOffsetY"].AsReal(); + SpecularRepeatX = scale * (float)mat["SpecRepeatX"].AsReal(); + SpecularRepeatY = scale * (float)mat["SpecRepeatY"].AsReal(); + SpecularRotation = scale * (float)mat["SpecRotation"].AsReal(); + + SpecularLightColor = mat["SpecColor"].AsColor4(); + SpecularLightExponent = (Byte)mat["SpecExp"].AsUInteger(); + EnvironmentIntensity = (Byte)mat["EnvIntensity"].AsUInteger(); + DiffuseAlphaMode = (Byte)mat["DiffuseAlphaMode"].AsUInteger(); + AlphaMaskCutoff = (Byte)mat["AlphaMaskCutoff"].AsUInteger(); + } + + public OSDMap toOSD() + { + OSDMap mat = new OSDMap(); + float scale = 10000f; + + mat["NormMap"] = NormalMapID; + mat["NormOffsetX"] = (int) (scale * NormalOffsetX); + mat["NormOffsetY"] = (int) (scale * NormalOffsetY); + mat["NormRepeatX"] = (int) (scale * NormalRepeatX); + mat["NormRepeatY"] = (int) (scale * NormalRepeatY); + mat["NormRotation"] = (int) (scale * NormalRotation); + + mat["SpecMap"] = SpecularMapID; + mat["SpecOffsetX"] = (int) (scale * SpecularOffsetX); + mat["SpecOffsetY"] = (int) (scale * SpecularOffsetY); + mat["SpecRepeatX"] = (int) (scale * SpecularRepeatX); + mat["SpecRepeatY"] = (int) (scale * SpecularRepeatY); + mat["SpecRotation"] = (int) (scale * SpecularRotation); + + mat["SpecColor"] = SpecularLightColor; + mat["SpecExp"] = SpecularLightExponent; + mat["EnvIntensity"] = EnvironmentIntensity; + mat["DiffuseAlphaMode"] = DiffuseAlphaMode; + mat["AlphaMaskCutoff"] = AlphaMaskCutoff; + + return mat; + } } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index cb06540de5..2f016fa276 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -338,6 +338,7 @@ namespace OpenSim.Region.Framework.Scenes // Update item with new asset item.AssetID = asset.FullID; group.UpdateInventoryItem(item); + group.AggregatePerms(); part.SendPropertiesToClient(remoteClient); @@ -647,7 +648,8 @@ namespace OpenSim.Region.Framework.Scenes // Modify uint permsMask = ~ ((uint)PermissionMask.Copy | (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify); + (uint)PermissionMask.Modify | + (uint)PermissionMask.Export); // Now, reduce the next perms to the mask bits // relevant to the operation @@ -677,6 +679,23 @@ namespace OpenSim.Region.Framework.Scenes (uint)PermissionMask.Move; uint ownerPerms = item.CurrentPermissions; + // These will be applied to the root prim at next rez. + // The legacy slam bit (bit 3) and folded permission (bits 0-2) + // are preserved due to the above mangling + ownerPerms &= nextPerms; + + // Mask the base permissions. This is a conservative + // approach altering only the three main perms + basePerms &= nextPerms; + + // Mask out the folded portion of the base mask. + // While the owner mask carries the actual folded + // permissions, the base mask carries the original + // base mask, before masking with the folded perms. + // We need this later for rezzing. + basePerms &= ~(uint)PermissionMask.FoldedMask; + basePerms |= ((basePerms >> 13) & 7) | (((basePerms & (uint)PermissionMask.Export) != 0) ? (uint)PermissionMask.FoldedExport : 0); + // If this is an object, root prim perms may be more // permissive than folded perms. Use folded perms as // a mask @@ -684,6 +703,9 @@ namespace OpenSim.Region.Framework.Scenes { // Create a safe mask for the current perms uint foldedPerms = (item.CurrentPermissions & 7) << 13; + if ((item.CurrentPermissions & (uint)PermissionMask.FoldedExport) != 0) + foldedPerms |= (uint)PermissionMask.Export; + foldedPerms |= permsMask; bool isRootMod = (item.CurrentPermissions & @@ -691,6 +713,8 @@ namespace OpenSim.Region.Framework.Scenes true : false; // Mask the owner perms to the folded perms + // Note that this is only to satisfy the viewer. + // The effect of this will be reversed on rez. ownerPerms &= foldedPerms; basePerms &= foldedPerms; @@ -705,15 +729,6 @@ namespace OpenSim.Region.Framework.Scenes } } - // These will be applied to the root prim at next rez. - // The slam bit (bit 3) and folded permission (bits 0-2) - // are preserved due to the above mangling - ownerPerms &= nextPerms; - - // Mask the base permissions. This is a conservative - // approach altering only the three main perms - basePerms &= nextPerms; - // Assign to the actual item. Make sure the slam bit is // set, if it wasn't set before. itemCopy.BasePermissions = basePerms; @@ -1200,6 +1215,7 @@ namespace OpenSim.Region.Framework.Scenes } group.RemoveInventoryItem(localID, itemID); + group.AggregatePerms(); } part.SendPropertiesToClient(remoteClient); @@ -1244,6 +1260,10 @@ namespace OpenSim.Region.Framework.Scenes agentItem.InvType = taskItem.InvType; agentItem.Flags = taskItem.Flags; + // The code below isn't OK. It doesn't account for flags being changed + // in the object inventory, so it will break when you do it. That + // is the previous behaviour, so no matter at this moment. However, there is a lot + // TODO: Fix this after the inventory fixer exists and has beenr run if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions()) { agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); @@ -1252,7 +1272,7 @@ namespace OpenSim.Region.Framework.Scenes else agentItem.CurrentPermissions = agentItem.BasePermissions & taskItem.CurrentPermissions; - agentItem.CurrentPermissions = agentItem.BasePermissions; + agentItem.BasePermissions = agentItem.CurrentPermissions; agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; agentItem.Flags &= ~(uint)(InventoryItemFlags.ObjectOverwriteBase | InventoryItemFlags.ObjectOverwriteOwner | InventoryItemFlags.ObjectOverwriteGroup | InventoryItemFlags.ObjectOverwriteEveryone | InventoryItemFlags.ObjectOverwriteNextOwner); @@ -1360,18 +1380,10 @@ namespace OpenSim.Region.Framework.Scenes return; } - if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + if (!Permissions.CanCopyObjectInventory(itemId, part.UUID, remoteClient.AgentId)) { - // If the item to be moved is no copy, we need to be able to - // edit the prim. - if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) - return; - } - else - { - // If the item is copiable, then we just need to have perms - // on it. The delete check is a pure rights check - if (!Permissions.CanDeleteObject(part.UUID, remoteClient.AgentId)) + // check also if we can delete the no copy item + if(!Permissions.CanEditObject(part.UUID, remoteClient.AgentId)) return; } @@ -1449,29 +1461,9 @@ namespace OpenSim.Region.Framework.Scenes return; } - // Can't transfer this - // - if (part.OwnerID != destPart.OwnerID && (srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) + if(!Permissions.CanDoObjectInvToObjectInv(srcTaskItem, part, destPart)) return; - bool overrideNoMod = false; - if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0) - overrideNoMod = true; - - if (part.OwnerID != destPart.OwnerID && (destPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0) - { - // object cannot copy items to an object owned by a different owner - // unless llAllowInventoryDrop has been called - - return; - } - - // must have both move and modify permission to put an item in an object - if (((part.OwnerMask & (uint)PermissionMask.Modify) == 0) && (!overrideNoMod)) - { - return; - } - TaskInventoryItem destTaskItem = new TaskInventoryItem(); destTaskItem.ItemID = UUID.Random(); @@ -1512,9 +1504,10 @@ namespace OpenSim.Region.Framework.Scenes destTaskItem.Type = srcTaskItem.Type; destPart.Inventory.AddInventoryItem(destTaskItem, part.OwnerID != destPart.OwnerID); - if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + { part.Inventory.RemoveInventoryItem(itemId); + } ScenePresence avatar; @@ -1652,76 +1645,79 @@ namespace OpenSim.Region.Framework.Scenes uint primLocalID) { UUID itemID = itemInfo.ItemID; + if (itemID == UUID.Zero) + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: UpdateTaskInventory called with item ID Zero on update for {1}!", + remoteClient.Name); + return; + } // Find the prim we're dealing with SceneObjectPart part = GetSceneObjectPart(primLocalID); - - if (part != null) + if(part == null) { - TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID); - bool allowInventoryDrop = (part.GetEffectiveObjectFlags() - & (uint)PrimFlags.AllowInventoryDrop) != 0; + m_log.WarnFormat( + "[PRIM INVENTORY]: " + + "Update with item {0} requested of prim {1} for {2} but this prim does not exist", + itemID, primLocalID, remoteClient.Name); + return; + } - // Explicity allow anyone to add to the inventory if the - // AllowInventoryDrop flag has been set. Don't however let - // them update an item unless they pass the external checks - // - if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId) - && (currentItem != null || !allowInventoryDrop)) + TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID); + + if (currentItem == null) + { + InventoryItemBase item = InventoryService.GetItem(remoteClient.AgentId, itemID); + + // if not found Try library + if (item == null && LibraryService != null && LibraryService.LibraryRootFolder != null) + item = LibraryService.LibraryRootFolder.FindItem(itemID); + + if(item == null) + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!", + itemID, remoteClient.Name); + return; + } + + if (!Permissions.CanDropInObjectInv(item, remoteClient, part)) return; - if (currentItem == null) + UUID copyID = UUID.Random(); + bool modrights = Permissions.CanEditObject(part.ParentGroup, remoteClient); + part.ParentGroup.AddInventoryItem(remoteClient.AgentId, primLocalID, item, copyID, modrights); + m_log.InfoFormat( + "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", + item.Name, primLocalID, remoteClient.Name); + part.SendPropertiesToClient(remoteClient); + if (!Permissions.BypassPermissions()) { - UUID copyID = UUID.Random(); - if (itemID != UUID.Zero) + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { - InventoryItemBase item = InventoryService.GetItem(remoteClient.AgentId, itemID); - - // Try library - if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null) - { - item = LibraryService.LibraryRootFolder.FindItem(itemID); - } - - // If we've found the item in the user's inventory or in the library - if (item != null) - { - part.ParentGroup.AddInventoryItem(remoteClient.AgentId, primLocalID, item, copyID); - m_log.InfoFormat( - "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", - item.Name, primLocalID, remoteClient.Name); - part.SendPropertiesToClient(remoteClient); - if (!Permissions.BypassPermissions()) - { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) - { - List uuids = new List(); - uuids.Add(itemID); - RemoveInventoryItem(remoteClient, uuids); - } - } - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!", - itemID, remoteClient.Name); - } + List uuids = new List(); + uuids.Add(itemID); + RemoveInventoryItem(remoteClient, uuids); } } - else // Updating existing item with new perms etc - { + } + else // Updating existing item with new perms etc + { // m_log.DebugFormat( // "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()", // currentItem.Name, part.Name); - // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the - // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update) - // will not pass in a transaction ID in the update message. - if (transactionID != UUID.Zero && AgentTransactionsModule != null) - { - AgentTransactionsModule.HandleTaskItemUpdateFromTransaction( - remoteClient, part, transactionID, currentItem); + if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) + return; + + // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the + // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update) + // will not pass in a transaction ID in the update message. + if (transactionID != UUID.Zero && AgentTransactionsModule != null) + { + AgentTransactionsModule.HandleTaskItemUpdateFromTransaction( + remoteClient, part, transactionID, currentItem); // if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) // remoteClient.SendAgentAlertMessage("Notecard saved", false); @@ -1729,49 +1725,30 @@ namespace OpenSim.Region.Framework.Scenes // remoteClient.SendAgentAlertMessage("Script saved", false); // else // remoteClient.SendAgentAlertMessage("Item saved", false); - } + } - // Base ALWAYS has move - currentItem.BasePermissions |= (uint)PermissionMask.Move; + // Base ALWAYS has move + currentItem.BasePermissions |= (uint)PermissionMask.Move; - itemInfo.Flags = currentItem.Flags; + itemInfo.Flags = currentItem.Flags; - // Check if we're allowed to mess with permissions - if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god + // Check if we're allowed to mess with permissions + if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god + { + if (remoteClient.AgentId != part.OwnerID) // Not owner { - if (remoteClient.AgentId != part.OwnerID) // Not owner - { - // Friends and group members can't change any perms - itemInfo.BasePermissions = currentItem.BasePermissions; - itemInfo.EveryonePermissions = currentItem.EveryonePermissions; - itemInfo.GroupPermissions = currentItem.GroupPermissions; - itemInfo.NextPermissions = currentItem.NextPermissions; - itemInfo.CurrentPermissions = currentItem.CurrentPermissions; - } - else - { - // Owner can't change base, and can change other - // only up to base - itemInfo.BasePermissions = currentItem.BasePermissions; - if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions) - itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; - if (itemInfo.GroupPermissions != currentItem.GroupPermissions) - itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup; - if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions) - itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner; - if (itemInfo.NextPermissions != currentItem.NextPermissions) - itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; - itemInfo.EveryonePermissions &= currentItem.BasePermissions; - itemInfo.GroupPermissions &= currentItem.BasePermissions; - itemInfo.CurrentPermissions &= currentItem.BasePermissions; - itemInfo.NextPermissions &= currentItem.BasePermissions; - } - + // Friends and group members can't change any perms + itemInfo.BasePermissions = currentItem.BasePermissions; + itemInfo.EveryonePermissions = currentItem.EveryonePermissions; + itemInfo.GroupPermissions = currentItem.GroupPermissions; + itemInfo.NextPermissions = currentItem.NextPermissions; + itemInfo.CurrentPermissions = currentItem.CurrentPermissions; } else { - if (itemInfo.BasePermissions != currentItem.BasePermissions) - itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteBase; + // Owner can't change base, and can change other + // only up to base + itemInfo.BasePermissions = currentItem.BasePermissions; if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; if (itemInfo.GroupPermissions != currentItem.GroupPermissions) @@ -1780,23 +1757,34 @@ namespace OpenSim.Region.Framework.Scenes itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner; if (itemInfo.NextPermissions != currentItem.NextPermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; + itemInfo.EveryonePermissions &= currentItem.BasePermissions; + itemInfo.GroupPermissions &= currentItem.BasePermissions; + itemInfo.CurrentPermissions &= currentItem.BasePermissions; + itemInfo.NextPermissions &= currentItem.BasePermissions; } - // Next ALWAYS has move - itemInfo.NextPermissions |= (uint)PermissionMask.Move; - - if (part.Inventory.UpdateInventoryItem(itemInfo)) - { - part.SendPropertiesToClient(remoteClient); - } } - } - else - { - m_log.WarnFormat( - "[PRIM INVENTORY]: " + - "Update with item {0} requested of prim {1} for {2} but this prim does not exist", - itemID, primLocalID, remoteClient.Name); + else + { + if (itemInfo.BasePermissions != currentItem.BasePermissions) + itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteBase; + if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions) + itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; + if (itemInfo.GroupPermissions != currentItem.GroupPermissions) + itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup; + if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions) + itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner; + if (itemInfo.NextPermissions != currentItem.NextPermissions) + itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; + } + + // Next ALWAYS has move + itemInfo.NextPermissions |= (uint)PermissionMask.Move; + + if (part.Inventory.UpdateInventoryItem(itemInfo)) + { + part.SendPropertiesToClient(remoteClient); + } } } @@ -1960,6 +1948,8 @@ namespace OpenSim.Region.Framework.Scenes part.Inventory.AddInventoryItem(taskItem, false); part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); + part.ParentGroup.AggregatePerms(); + // tell anyone managing scripts that a new script exists EventManager.TriggerNewScript(agentID, part, taskItem.ItemID); @@ -2095,13 +2085,20 @@ namespace OpenSim.Region.Framework.Scenes /// DeRezAction /// User folder ID to place derezzed object public virtual void DeRezObjects( - IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID) + IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID, bool AddToReturns = true) { // First, see of we can perform the requested action and // build a list of eligible objects List deleteIDs = new List(); List deleteGroups = new List(); List takeGroups = new List(); + List takeDeleteGroups = new List(); + + ScenePresence sp = null; + if(remoteClient != null) + sp = remoteClient.SceneAgent as ScenePresence; + else if(action != DeRezAction.Return) + return; // only Return can be called without a client // Start with true for both, then remove the flags if objects // that we can't derez are part of the selection @@ -2157,17 +2154,17 @@ namespace OpenSim.Region.Framework.Scenes { if (action == DeRezAction.TakeCopy) { - if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) + if (!Permissions.CanTakeCopyObject(grp, sp)) permissionToTakeCopy = false; } else { permissionToTakeCopy = false; } - if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) + if (!Permissions.CanTakeObject(grp, sp)) permissionToTake = false; - if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) + if (!Permissions.CanDeleteObject(grp, remoteClient)) permissionToDelete = false; } @@ -2208,13 +2205,14 @@ namespace OpenSim.Region.Framework.Scenes { if (Permissions.CanReturnObjects( null, - remoteClient.AgentId, + remoteClient, new List() {grp})) { permissionToTake = true; permissionToDelete = true; - - AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); + if(AddToReturns) + AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, + "parcel owner return"); } } else // Auto return passes through here with null agent @@ -2224,26 +2222,24 @@ namespace OpenSim.Region.Framework.Scenes } } - if (permissionToTake && (!permissionToDelete)) - takeGroups.Add(grp); - if (permissionToDelete) { if (permissionToTake) + takeDeleteGroups.Add(grp); + else deleteGroups.Add(grp); deleteIDs.Add(grp.LocalId); } + else if(permissionToTake) + takeGroups.Add(grp); } SendKillObject(deleteIDs); - if (deleteGroups.Count > 0) + if (takeDeleteGroups.Count > 0) { - foreach (SceneObjectGroup g in deleteGroups) - deleteIDs.Remove(g.LocalId); - m_asyncSceneObjectDeleter.DeleteToInventory( - action, destinationID, deleteGroups, remoteClient, + action, destinationID, takeDeleteGroups, remoteClient, true); } if (takeGroups.Count > 0) @@ -2252,7 +2248,7 @@ namespace OpenSim.Region.Framework.Scenes action, destinationID, takeGroups, remoteClient, false); } - if (deleteIDs.Count > 0) + if (deleteGroups.Count > 0) { foreach (SceneObjectGroup g in deleteGroups) DeleteSceneObject(g, true); @@ -2640,6 +2636,7 @@ namespace OpenSim.Region.Framework.Scenes // We can only call this after adding the scene object, since the scene object references the scene // to find out if scripts should be activated at all. + group.AggregatePerms(); group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); group.ScheduleGroupForFullUpdate(); @@ -2649,7 +2646,7 @@ namespace OpenSim.Region.Framework.Scenes } public virtual bool returnObjects(SceneObjectGroup[] returnobjects, - UUID AgentId) + IClientAPI client) { List localIDs = new List(); @@ -2659,8 +2656,8 @@ namespace OpenSim.Region.Framework.Scenes "parcel owner return"); localIDs.Add(grp.RootPart.LocalId); } - DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, - UUID.Zero); + DeRezObjects(client, localIDs, UUID.Zero, DeRezAction.Return, + UUID.Zero, false); return true; } @@ -2691,9 +2688,6 @@ namespace OpenSim.Region.Framework.Scenes { if (ownerID != UUID.Zero) return; - - if (!Permissions.CanDeedObject(remoteClient.AgentId, groupID)) - return; } List groups = new List(); @@ -2724,21 +2718,22 @@ namespace OpenSim.Region.Framework.Scenes child.TriggerScriptChangedEvent(Changed.OWNER); } } - else // The object was deeded to the group + else // The object deeded to the group { - if (!Permissions.IsGod(remoteClient.AgentId) && sog.OwnerID != remoteClient.AgentId) - continue; - - if (!Permissions.CanTransferObject(sog.UUID, groupID)) - continue; - - if (sog.GroupID != groupID) + if (!Permissions.CanDeedObject(remoteClient, sog, groupID)) continue; sog.SetOwnerId(groupID); - // Make the group mask be the previous owner mask - sog.RootPart.GroupMask = sog.RootPart.OwnerMask; + + // this is wrong, GroupMask is used for group sharing, still possible to set + // this whould give owner rights to users that are member of group but don't have role powers to edit +// sog.RootPart.GroupMask = sog.RootPart.OwnerMask; + + // we should keep all permissions on deed to group + // and with this comented code, if user does not set next permissions on the object + // and on ALL contents of ALL prims, he may loose rights, making the object useless sog.ApplyNextOwnerPermissions(); + sog.AggregatePerms(); sog.ScheduleGroupForFullUpdate(); @@ -2748,8 +2743,6 @@ namespace OpenSim.Region.Framework.Scenes child.Inventory.ChangeInventoryOwner(groupID); child.TriggerScriptChangedEvent(Changed.OWNER); } - - } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 2d62b50af4..4fef9c3012 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -183,11 +183,12 @@ namespace OpenSim.Region.Framework.Scenes part.SendFullUpdate(remoteClient); // A prim is only tainted if it's allowed to be edited by the person clicking it. - if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) - || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) + if (Permissions.CanChangeSelectedState(part, (ScenePresence)remoteClient.SceneAgent)) { + bool oldsel = part.IsSelected; part.IsSelected = true; - EventManager.TriggerParcelPrimCountTainted(); + if(!oldsel) + EventManager.TriggerParcelPrimCountTainted(); } part.SendPropertiesToClient(remoteClient); @@ -229,6 +230,7 @@ namespace OpenSim.Region.Framework.Scenes if (so.OwnerID == remoteClient.AgentId) { so.SetGroup(groupID, remoteClient); + EventManager.TriggerParcelPrimCountTainted(); } } } @@ -250,8 +252,7 @@ namespace OpenSim.Region.Framework.Scenes // handled by group, but by prim. Legacy cruft. // TODO: Make selection flagging per prim! // - if (Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId) - || Permissions.CanMoveObject(part.ParentGroup.UUID, remoteClient.AgentId)) + if (Permissions.CanChangeSelectedState(part, (ScenePresence)remoteClient.SceneAgent)) { part.IsSelected = false; if (!part.ParentGroup.IsAttachment && oldgprSelect != part.ParentGroup.IsSelected) @@ -327,7 +328,7 @@ namespace OpenSim.Region.Framework.Scenes if(group == null || group.IsDeleted) return; - if (Permissions.CanMoveObject(group.UUID, remoteClient.AgentId))// && PermissionsMngr.) + if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.) { group.GrabMovement(objectID, offset, pos, remoteClient); } @@ -388,7 +389,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(objectID); if (group != null) { - if (Permissions.CanMoveObject(group.UUID, remoteClient.AgentId))// && PermissionsMngr.) + if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.) { group.SpinStart(remoteClient); } @@ -406,7 +407,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(objectID); if (group != null) { - if (Permissions.CanMoveObject(group.UUID, remoteClient.AgentId))// && PermissionsMngr.) + if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.) { group.SpinMovement(rotation, remoteClient); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index 893b38c152..c55a7a6412 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -37,52 +37,60 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.Framework.Scenes { #region Delegates - public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectID); + public delegate uint GenerateClientFlagsHandler(SceneObjectPart part, ScenePresence sp, uint curEffectivePerms); public delegate void SetBypassPermissionsHandler(bool value); public delegate bool BypassPermissionsHandler(); public delegate bool PropagatePermissionsHandler(); - public delegate bool RezObjectHandler(int objectCount, UUID owner, Vector3 objectPosition, Scene scene); - public delegate bool DeleteObjectHandler(UUID objectID, UUID deleter, Scene scene); - public delegate bool TransferObjectHandler(UUID objectID, UUID recipient, Scene scene); - public delegate bool TakeObjectHandler(UUID objectID, UUID stealer, Scene scene); - public delegate bool SellGroupObjectHandler(UUID userID, UUID groupID, Scene scene); - public delegate bool TakeCopyObjectHandler(UUID objectID, UUID userID, Scene inScene); - public delegate bool DuplicateObjectHandler(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition); - public delegate bool EditObjectHandler(UUID objectID, UUID editorID, Scene scene); - public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID, Scene scene); - public delegate bool MoveObjectHandler(UUID objectID, UUID moverID, Scene scene); - public delegate bool ObjectEntryHandler(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene); - public delegate bool ReturnObjectsHandler(ILandObject land, UUID user, List objects, Scene scene); - public delegate bool InstantMessageHandler(UUID user, UUID target, Scene startScene); - public delegate bool InventoryTransferHandler(UUID user, UUID target, Scene startScene); - public delegate bool ViewScriptHandler(UUID script, UUID objectID, UUID user, Scene scene); - public delegate bool ViewNotecardHandler(UUID script, UUID objectID, UUID user, Scene scene); - public delegate bool EditScriptHandler(UUID script, UUID objectID, UUID user, Scene scene); - public delegate bool EditNotecardHandler(UUID notecard, UUID objectID, UUID user, Scene scene); - public delegate bool RunScriptHandler(UUID script, UUID objectID, UUID user, Scene scene); - public delegate bool CompileScriptHandler(UUID ownerUUID, int scriptType, Scene scene); - public delegate bool StartScriptHandler(UUID script, UUID user, Scene scene); - public delegate bool StopScriptHandler(UUID script, UUID user, Scene scene); - public delegate bool ResetScriptHandler(UUID prim, UUID script, UUID user, Scene scene); - public delegate bool TerraformLandHandler(UUID user, Vector3 position, Scene requestFromScene); - public delegate bool RunConsoleCommandHandler(UUID user, Scene requestFromScene); - public delegate bool IssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand); - public delegate bool IsGodHandler(UUID user, Scene requestFromScene); - public delegate bool IsGridGodHandler(UUID user, Scene requestFromScene); + public delegate bool RezObjectHandler(int objectCount, UUID owner, Vector3 objectPosition); + public delegate bool DeleteObjectHandlerByIDs(UUID objectID, UUID deleter); + public delegate bool DeleteObjectHandler(SceneObjectGroup sog, ScenePresence sp); + public delegate bool TransferObjectHandler(UUID objectID, UUID recipient); + public delegate bool TakeObjectHandler(SceneObjectGroup sog, ScenePresence sp); + public delegate bool SellGroupObjectHandler(UUID userID, UUID groupID); + public delegate bool SellObjectHandlerByUserID(SceneObjectGroup sog, UUID userID, byte saleType); + public delegate bool SellObjectHandler(SceneObjectGroup sog, ScenePresence sp, byte saleType); + public delegate bool TakeCopyObjectHandler(SceneObjectGroup sog, ScenePresence sp); + public delegate bool DuplicateObjectHandler(SceneObjectGroup sog, ScenePresence sp); + public delegate bool EditObjectByIDsHandler(UUID objectID, UUID editorID); + public delegate bool EditObjectHandler(SceneObjectGroup sog, ScenePresence sp); + public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID); + public delegate bool MoveObjectHandler(SceneObjectGroup sog, ScenePresence sp); + public delegate bool ObjectEntryHandler(SceneObjectGroup sog, bool enteringRegion, Vector3 newPoint); + public delegate bool ObjectEnterWithScriptsHandler(SceneObjectGroup sog, ILandObject land); + public delegate bool ReturnObjectsHandler(ILandObject land, ScenePresence sp, List objects); + public delegate bool InstantMessageHandler(UUID user, UUID target); + public delegate bool InventoryTransferHandler(UUID user, UUID target); + public delegate bool ViewScriptHandler(UUID script, UUID objectID, UUID user); + public delegate bool ViewNotecardHandler(UUID script, UUID objectID, UUID user); + public delegate bool EditScriptHandler(UUID script, UUID objectID, UUID user); + public delegate bool EditNotecardHandler(UUID notecard, UUID objectID, UUID user); + public delegate bool RunScriptHandlerByIDs(UUID script, UUID objectID, UUID user); + public delegate bool RunScriptHandler(TaskInventoryItem item, SceneObjectPart part); + public delegate bool CompileScriptHandler(UUID ownerUUID, int scriptType); + public delegate bool StartScriptHandler(UUID script, UUID user); + public delegate bool StopScriptHandler(UUID script, UUID user); + public delegate bool ResetScriptHandler(UUID prim, UUID script, UUID user); + public delegate bool TerraformLandHandler(UUID user, Vector3 position); + public delegate bool RunConsoleCommandHandler(UUID user); + public delegate bool IssueEstateCommandHandler(UUID user, bool ownerCommand); + public delegate bool IsGodHandler(UUID user); + public delegate bool IsGridGodHandler(UUID user); public delegate bool IsAdministratorHandler(UUID user); public delegate bool IsEstateManagerHandler(UUID user); - public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene); - public delegate bool EditParcelPropertiesHandler(UUID user, ILandObject parcel, GroupPowers p, Scene scene, bool allowManager); - public delegate bool SellParcelHandler(UUID user, ILandObject parcel, Scene scene); - public delegate bool AbandonParcelHandler(UUID user, ILandObject parcel, Scene scene); - public delegate bool ReclaimParcelHandler(UUID user, ILandObject parcel, Scene scene); - public delegate bool DeedParcelHandler(UUID user, ILandObject parcel, Scene scene); - public delegate bool DeedObjectHandler(UUID user, UUID group, Scene scene); - public delegate bool BuyLandHandler(UUID user, ILandObject parcel, Scene scene); + public delegate bool EditParcelHandler(UUID user, ILandObject parcel); + public delegate bool EditParcelPropertiesHandler(UUID user, ILandObject parcel, GroupPowers p, bool allowManager); + public delegate bool SellParcelHandler(UUID user, ILandObject parcel); + public delegate bool AbandonParcelHandler(UUID user, ILandObject parcel); + public delegate bool ReclaimParcelHandler(UUID user, ILandObject parcel); + public delegate bool DeedParcelHandler(UUID user, ILandObject parcel); + public delegate bool DeedObjectHandler(ScenePresence sp, SceneObjectGroup sog, UUID targetGroupID); + public delegate bool BuyLandHandler(UUID user, ILandObject parcel); public delegate bool LinkObjectHandler(UUID user, UUID objectID); public delegate bool DelinkObjectHandler(UUID user, UUID objectID); public delegate bool CreateObjectInventoryHandler(int invType, UUID objectID, UUID userID); public delegate bool CopyObjectInventoryHandler(UUID itemID, UUID objectID, UUID userID); + public delegate bool DoObjectInvToObjectInv(TaskInventoryItem item, SceneObjectPart sourcePart, SceneObjectPart destPart); + public delegate bool DoDropInObjectInv(InventoryItemBase item, ScenePresence sp, SceneObjectPart destPart); public delegate bool DeleteObjectInventoryHandler(UUID itemID, UUID objectID, UUID userID); public delegate bool TransferObjectInventoryHandler(UUID itemID, UUID objectID, UUID userID); public delegate bool CreateUserInventoryHandler(int invType, UUID userID); @@ -112,16 +120,23 @@ namespace OpenSim.Region.Framework.Scenes public event BypassPermissionsHandler OnBypassPermissions; public event PropagatePermissionsHandler OnPropagatePermissions; public event RezObjectHandler OnRezObject; + public event DeleteObjectHandlerByIDs OnDeleteObjectByIDs; public event DeleteObjectHandler OnDeleteObject; public event TransferObjectHandler OnTransferObject; public event TakeObjectHandler OnTakeObject; + public event SellGroupObjectHandler OnSellGroupObject; + public event SellObjectHandlerByUserID OnSellObjectByUserID; + public event SellObjectHandler OnSellObject; + public event TakeCopyObjectHandler OnTakeCopyObject; public event DuplicateObjectHandler OnDuplicateObject; + public event EditObjectByIDsHandler OnEditObjectByIDs; public event EditObjectHandler OnEditObject; public event EditObjectInventoryHandler OnEditObjectInventory; public event MoveObjectHandler OnMoveObject; public event ObjectEntryHandler OnObjectEntry; + public event ObjectEnterWithScriptsHandler OnObjectEnterWithScripts; public event ReturnObjectsHandler OnReturnObjects; public event InstantMessageHandler OnInstantMessage; public event InventoryTransferHandler OnInventoryTransfer; @@ -129,6 +144,7 @@ namespace OpenSim.Region.Framework.Scenes public event ViewNotecardHandler OnViewNotecard; public event EditScriptHandler OnEditScript; public event EditNotecardHandler OnEditNotecard; + public event RunScriptHandlerByIDs OnRunScriptByIDs; public event RunScriptHandler OnRunScript; public event CompileScriptHandler OnCompileScript; public event StartScriptHandler OnStartScript; @@ -137,7 +153,6 @@ namespace OpenSim.Region.Framework.Scenes public event TerraformLandHandler OnTerraformLand; public event RunConsoleCommandHandler OnRunConsoleCommand; public event IssueEstateCommandHandler OnIssueEstateCommand; - public event IsGodHandler OnIsGod; public event IsGridGodHandler OnIsGridGod; public event IsAdministratorHandler OnIsAdministrator; public event IsEstateManagerHandler OnIsEstateManager; @@ -153,6 +168,8 @@ namespace OpenSim.Region.Framework.Scenes public event DelinkObjectHandler OnDelinkObject; public event CreateObjectInventoryHandler OnCreateObjectInventory; public event CopyObjectInventoryHandler OnCopyObjectInventory; + public event DoObjectInvToObjectInv OnDoObjectInvToObjectInv; + public event DoDropInObjectInv OnDropInObjectInv; public event DeleteObjectInventoryHandler OnDeleteObjectInventory; public event TransferObjectInventoryHandler OnTransferObjectInventory; public event CreateUserInventoryHandler OnCreateUserInventory; @@ -167,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes #region Object Permission Checks - public uint GenerateClientFlags(UUID userID, UUID objectID) + public uint GenerateClientFlags( SceneObjectPart part, ScenePresence sp) { // libomv will moan about PrimFlags.ObjectYouOfficer being // obsolete... @@ -179,12 +196,9 @@ namespace OpenSim.Region.Framework.Scenes PrimFlags.ObjectTransfer | PrimFlags.ObjectYouOwner | PrimFlags.ObjectAnyOwner | - PrimFlags.ObjectOwnerModify | - PrimFlags.ObjectYouOfficer; + PrimFlags.ObjectOwnerModify; #pragma warning restore 0612 - SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); - if (part == null) return 0; @@ -196,7 +210,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handlerGenerateClientFlags.GetInvocationList(); foreach (GenerateClientFlagsHandler check in list) { - perms &= check(userID, objectID); + perms &= check(part, sp, perms); } } return perms; @@ -248,7 +262,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (RezObjectHandler h in list) { - if (h(objectCount, owner,objectPosition, m_scene) == false) + if (h(objectCount, owner,objectPosition) == false) return false; } } @@ -262,141 +276,52 @@ namespace OpenSim.Region.Framework.Scenes { bool result = true; - DeleteObjectHandler handler = OnDeleteObject; + DeleteObjectHandlerByIDs handler = OnDeleteObjectByIDs; if (handler != null) { Delegate[] list = handler.GetInvocationList(); - foreach (DeleteObjectHandler h in list) + foreach (DeleteObjectHandlerByIDs h in list) { - if (h(objectID, deleter, m_scene) == false) + if (h(objectID, deleter) == false) { result = false; break; } } } - return result; } + public bool CanDeleteObject(SceneObjectGroup sog, IClientAPI client) + { + DeleteObjectHandler handler = OnDeleteObject; + if (handler != null) + { + if(sog == null || client == null || client.SceneAgent == null) + return false; + + ScenePresence sp = client.SceneAgent as ScenePresence; + + Delegate[] list = handler.GetInvocationList(); + foreach (DeleteObjectHandler h in list) + { + if (h(sog, sp) == false) + return false; + } + } + + return true; + } + public bool CanTransferObject(UUID objectID, UUID recipient) { - bool result = true; - TransferObjectHandler handler = OnTransferObject; if (handler != null) { Delegate[] list = handler.GetInvocationList(); foreach (TransferObjectHandler h in list) { - if (h(objectID, recipient, m_scene) == false) - { - result = false; - break; - } - } - } - - return result; - } - - #endregion - - #region TAKE OBJECT - public bool CanTakeObject(UUID objectID, UUID AvatarTakingUUID) - { - bool result = true; - - TakeObjectHandler handler = OnTakeObject; - if (handler != null) - { - Delegate[] list = handler.GetInvocationList(); - foreach (TakeObjectHandler h in list) - { - if (h(objectID, AvatarTakingUUID, m_scene) == false) - { - result = false; - break; - } - } - } - -// m_log.DebugFormat( -// "[SCENE PERMISSIONS]: CanTakeObject() fired for object {0}, taker {1}, result {2}", -// objectID, AvatarTakingUUID, result); - - return result; - } - - #endregion - - #region SELL GROUP OBJECT - public bool CanSellGroupObject(UUID userID, UUID groupID, Scene scene) - { - bool result = true; - - SellGroupObjectHandler handler = OnSellGroupObject; - if (handler != null) - { - Delegate[] list = handler.GetInvocationList(); - foreach (SellGroupObjectHandler h in list) - { - if (h(userID, groupID, scene) == false) - { - result = false; - break; - } - } - } - - //m_log.DebugFormat( - // "[SCENE PERMISSIONS]: CanSellGroupObject() fired for user {0}, group {1}, result {2}", - // userID, groupID, result); - - return result; - } - - #endregion - - - #region TAKE COPY OBJECT - public bool CanTakeCopyObject(UUID objectID, UUID userID) - { - bool result = true; - - TakeCopyObjectHandler handler = OnTakeCopyObject; - if (handler != null) - { - Delegate[] list = handler.GetInvocationList(); - foreach (TakeCopyObjectHandler h in list) - { - if (h(objectID, userID, m_scene) == false) - { - result = false; - break; - } - } - } - -// m_log.DebugFormat( -// "[SCENE PERMISSIONS]: CanTakeCopyObject() fired for object {0}, user {1}, result {2}", -// objectID, userID, result); - - return result; - } - - #endregion - - #region DUPLICATE OBJECT - public bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Vector3 objectPosition) - { - DuplicateObjectHandler handler = OnDuplicateObject; - if (handler != null) - { - Delegate[] list = handler.GetInvocationList(); - foreach (DuplicateObjectHandler h in list) - { - if (h(objectCount, objectID, owner, m_scene, objectPosition) == false) + if (h(objectID, recipient) == false) return false; } } @@ -405,16 +330,181 @@ namespace OpenSim.Region.Framework.Scenes #endregion + #region TAKE OBJECT + public bool CanTakeObject(SceneObjectGroup sog, ScenePresence sp) + { + TakeObjectHandler handler = OnTakeObject; + if (handler != null) + { + if(sog == null || sp == null) + return false; + + Delegate[] list = handler.GetInvocationList(); + foreach (TakeObjectHandler h in list) + { + if (h(sog, sp) == false) + return false; + } + } +// m_log.DebugFormat( +// "[SCENE PERMISSIONS]: CanTakeObject() fired for object {0}, taker {1}, result {2}", +// objectID, AvatarTakingUUID, result); + return true; + } + + #endregion + + #region SELL GROUP OBJECT + public bool CanSellGroupObject(UUID userID, UUID groupID) + { + SellGroupObjectHandler handler = OnSellGroupObject; + if (handler != null) + { + Delegate[] list = handler.GetInvocationList(); + foreach (SellGroupObjectHandler h in list) + { + if (h(userID, groupID) == false) + return false; + } + } + //m_log.DebugFormat( + // "[SCENE PERMISSIONS]: CanSellGroupObject() fired for user {0}, group {1}, result {2}", + // userID, groupID, result); + return true; + } + + #endregion + + #region SELL OBJECT + public bool CanSellObject(IClientAPI client, SceneObjectGroup sog, byte saleType) + { + SellObjectHandler handler = OnSellObject; + if (handler != null) + { + if(sog == null || client == null || client.SceneAgent == null) + return false; + + ScenePresence sp = client.SceneAgent as ScenePresence; + Delegate[] list = handler.GetInvocationList(); + foreach (SellObjectHandler h in list) + { + if (h(sog, sp, saleType) == false) + return false; + } + } + return true; + } + + public bool CanSellObject(UUID userID, SceneObjectGroup sog, byte saleType) + { + SellObjectHandlerByUserID handler = OnSellObjectByUserID; + if (handler != null) + { + if(sog == null) + return false; + Delegate[] list = handler.GetInvocationList(); + foreach (SellObjectHandlerByUserID h in list) + { + if (h(sog, userID, saleType) == false) + return false; + } + } + return true; + } + + #endregion + + + #region TAKE COPY OBJECT + public bool CanTakeCopyObject(SceneObjectGroup sog, ScenePresence sp) + { + TakeCopyObjectHandler handler = OnTakeCopyObject; + if (handler != null) + { + if(sog == null || sp == null) + return false; + Delegate[] list = handler.GetInvocationList(); + foreach (TakeCopyObjectHandler h in list) + { + if (h(sog, sp) == false) + return false; + } + } +// m_log.DebugFormat( +// "[SCENE PERMISSIONS]: CanTakeCopyObject() fired for object {0}, user {1}, result {2}", +// objectID, userID, result); + return true; + } + + #endregion + + #region DUPLICATE OBJECT + public bool CanDuplicateObject(SceneObjectGroup sog, UUID agentID) + { + DuplicateObjectHandler handler = OnDuplicateObject; + if (handler != null) + { + if(sog == null || sog.IsDeleted) + return false; + ScenePresence sp = m_scene.GetScenePresence(agentID); + if(sp == null || sp.IsDeleted) + return false; + Delegate[] list = handler.GetInvocationList(); + foreach (DuplicateObjectHandler h in list) + { + if (h(sog, sp) == false) + return false; + } + } + return true; + } + + #endregion + + #region persence EDIT or MOVE OBJECT + private const uint CANSELECTMASK = (uint)( + PrimFlags.ObjectMove | + PrimFlags.ObjectModify | + PrimFlags.ObjectOwnerModify + ); + + public bool CanChangeSelectedState(SceneObjectPart part, ScenePresence sp) + { + uint perms = GenerateClientFlags(part, sp); + return (perms & CANSELECTMASK) != 0; + } + + #endregion #region EDIT OBJECT public bool CanEditObject(UUID objectID, UUID editorID) + { + EditObjectByIDsHandler handler = OnEditObjectByIDs; + if (handler != null) + { + Delegate[] list = handler.GetInvocationList(); + foreach (EditObjectByIDsHandler h in list) + { + if (h(objectID, editorID) == false) + return false; + } + } + return true; + } + + public bool CanEditObject(SceneObjectGroup sog, IClientAPI client) { EditObjectHandler handler = OnEditObject; if (handler != null) { + if(sog == null || client == null || client.SceneAgent == null) + return false; + + ScenePresence sp = client.SceneAgent as ScenePresence; + Delegate[] list = handler.GetInvocationList(); foreach (EditObjectHandler h in list) { - if (h(objectID, editorID, m_scene) == false) + if (h(sog, sp) == false) return false; } } @@ -429,7 +519,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (EditObjectInventoryHandler h in list) { - if (h(objectID, editorID, m_scene) == false) + if (h(objectID, editorID) == false) return false; } } @@ -439,15 +529,20 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region MOVE OBJECT - public bool CanMoveObject(UUID objectID, UUID moverID) + public bool CanMoveObject(SceneObjectGroup sog, IClientAPI client) { MoveObjectHandler handler = OnMoveObject; if (handler != null) { + if(sog == null || client == null || client.SceneAgent == null) + return false; + + ScenePresence sp = client.SceneAgent as ScenePresence; + Delegate[] list = handler.GetInvocationList(); foreach (MoveObjectHandler h in list) { - if (h(objectID, moverID, m_scene) == false) + if (h(sog, sp) == false) return false; } } @@ -457,7 +552,7 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region OBJECT ENTRY - public bool CanObjectEntry(UUID objectID, bool enteringRegion, Vector3 newPoint) + public bool CanObjectEntry(SceneObjectGroup sog, bool enteringRegion, Vector3 newPoint) { ObjectEntryHandler handler = OnObjectEntry; if (handler != null) @@ -465,7 +560,22 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (ObjectEntryHandler h in list) { - if (h(objectID, enteringRegion, newPoint, m_scene) == false) + if (h(sog, enteringRegion, newPoint) == false) + return false; + } + } + return true; + } + + public bool CanObjectEnterWithScripts(SceneObjectGroup sog, ILandObject land) + { + ObjectEnterWithScriptsHandler handler = OnObjectEnterWithScripts; + if (handler != null) + { + Delegate[] list = handler.GetInvocationList(); + foreach (ObjectEnterWithScriptsHandler h in list) + { + if (h(sog, land) == false) return false; } } @@ -475,29 +585,30 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region RETURN OBJECT - public bool CanReturnObjects(ILandObject land, UUID user, List objects) + public bool CanReturnObjects(ILandObject land, IClientAPI client, List objects) { - bool result = true; - ReturnObjectsHandler handler = OnReturnObjects; if (handler != null) { + if(objects == null) + return false; + + ScenePresence sp = null; + if(client != null && client.SceneAgent != null) + sp = client.SceneAgent as ScenePresence; + Delegate[] list = handler.GetInvocationList(); foreach (ReturnObjectsHandler h in list) { - if (h(land, user, objects, m_scene) == false) - { - result = false; - break; - } + if (h(land, sp, objects) == false) + return false; } } - // m_log.DebugFormat( // "[SCENE PERMISSIONS]: CanReturnObjects() fired for user {0} for {1} objects on {2}, result {3}", // user, objects.Count, land.LandData.Name, result); - return result; + return true; } #endregion @@ -511,7 +622,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (InstantMessageHandler h in list) { - if (h(user, target, m_scene) == false) + if (h(user, target) == false) return false; } } @@ -529,7 +640,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (InventoryTransferHandler h in list) { - if (h(user, target, m_scene) == false) + if (h(user, target) == false) return false; } } @@ -547,7 +658,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (ViewScriptHandler h in list) { - if (h(script, objectID, user, m_scene) == false) + if (h(script, objectID, user) == false) return false; } } @@ -562,7 +673,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (ViewNotecardHandler h in list) { - if (h(script, objectID, user, m_scene) == false) + if (h(script, objectID, user) == false) return false; } } @@ -580,7 +691,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (EditScriptHandler h in list) { - if (h(script, objectID, user, m_scene) == false) + if (h(script, objectID, user) == false) return false; } } @@ -595,7 +706,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (EditNotecardHandler h in list) { - if (h(script, objectID, user, m_scene) == false) + if (h(script, objectID, user) == false) return false; } } @@ -607,19 +718,37 @@ namespace OpenSim.Region.Framework.Scenes #region RUN SCRIPT (When Script Placed in Object) public bool CanRunScript(UUID script, UUID objectID, UUID user) { - RunScriptHandler handler = OnRunScript; + RunScriptHandlerByIDs handler = OnRunScriptByIDs; if (handler != null) { Delegate[] list = handler.GetInvocationList(); - foreach (RunScriptHandler h in list) + foreach (RunScriptHandlerByIDs h in list) { - if (h(script, objectID, user, m_scene) == false) + if (h(script, objectID, user) == false) return false; } } return true; } + public bool CanRunScript(TaskInventoryItem item, SceneObjectPart part) + { + RunScriptHandler handler = OnRunScript; + if (handler != null) + { + if(item == null || part == null) + return false; + Delegate[] list = handler.GetInvocationList(); + foreach (RunScriptHandler h in list) + { + if (h(item, part) == false) + return false; + } + } + return true; + } + + #endregion #region COMPILE SCRIPT (When Script needs to get (re)compiled) @@ -631,7 +760,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (CompileScriptHandler h in list) { - if (h(ownerUUID, scriptType, m_scene) == false) + if (h(ownerUUID, scriptType) == false) return false; } } @@ -649,7 +778,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (StartScriptHandler h in list) { - if (h(script, user, m_scene) == false) + if (h(script, user) == false) return false; } } @@ -667,7 +796,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (StopScriptHandler h in list) { - if (h(script, user, m_scene) == false) + if (h(script, user) == false) return false; } } @@ -685,7 +814,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (ResetScriptHandler h in list) { - if (h(prim, script, user, m_scene) == false) + if (h(prim, script, user) == false) return false; } } @@ -703,7 +832,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (TerraformLandHandler h in list) { - if (h(user, pos, m_scene) == false) + if (h(user, pos) == false) return false; } } @@ -721,7 +850,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (RunConsoleCommandHandler h in list) { - if (h(user, m_scene) == false) + if (h(user) == false) return false; } } @@ -739,7 +868,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (IssueEstateCommandHandler h in list) { - if (h(user, m_scene, ownerCommand) == false) + if (h(user, ownerCommand) == false) return false; } } @@ -750,13 +879,13 @@ namespace OpenSim.Region.Framework.Scenes #region CAN BE GODLIKE public bool IsGod(UUID user) { - IsGodHandler handler = OnIsGod; + IsAdministratorHandler handler = OnIsAdministrator; if (handler != null) { Delegate[] list = handler.GetInvocationList(); - foreach (IsGodHandler h in list) + foreach (IsAdministratorHandler h in list) { - if (h(user, m_scene) == false) + if (h(user) == false) return false; } } @@ -771,7 +900,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (IsGridGodHandler h in list) { - if (h(user, m_scene) == false) + if (h(user) == false) return false; } } @@ -819,7 +948,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (EditParcelPropertiesHandler h in list) { - if (h(user, parcel, p, m_scene, allowManager) == false) + if (h(user, parcel, p, allowManager) == false) return false; } } @@ -836,7 +965,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (SellParcelHandler h in list) { - if (h(user, parcel, m_scene) == false) + if (h(user, parcel) == false) return false; } } @@ -853,7 +982,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (AbandonParcelHandler h in list) { - if (h(user, parcel, m_scene) == false) + if (h(user, parcel) == false) return false; } } @@ -869,7 +998,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (ReclaimParcelHandler h in list) { - if (h(user, parcel, m_scene) == false) + if (h(user, parcel) == false) return false; } } @@ -884,22 +1013,27 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (DeedParcelHandler h in list) { - if (h(user, parcel, m_scene) == false) + if (h(user, parcel) == false) return false; } } return true; } - public bool CanDeedObject(UUID user, UUID group) + public bool CanDeedObject(IClientAPI client, SceneObjectGroup sog, UUID targetGroupID) { DeedObjectHandler handler = OnDeedObject; if (handler != null) { + if(sog == null || client == null || client.SceneAgent == null || targetGroupID == UUID.Zero) + return false; + + ScenePresence sp = client.SceneAgent as ScenePresence; + Delegate[] list = handler.GetInvocationList(); foreach (DeedObjectHandler h in list) { - if (h(user, group, m_scene) == false) + if (h(sp, sog, targetGroupID) == false) return false; } } @@ -914,7 +1048,7 @@ namespace OpenSim.Region.Framework.Scenes Delegate[] list = handler.GetInvocationList(); foreach (BuyLandHandler h in list) { - if (h(user, parcel, m_scene) == false) + if (h(user, parcel) == false) return false; } } @@ -990,6 +1124,45 @@ namespace OpenSim.Region.Framework.Scenes return true; } + public bool CanDoObjectInvToObjectInv(TaskInventoryItem item, SceneObjectPart sourcePart, SceneObjectPart destPart) + { + DoObjectInvToObjectInv handler = OnDoObjectInvToObjectInv; + if (handler != null) + { + if (sourcePart == null || destPart == null || item == null) + return false; + Delegate[] list = handler.GetInvocationList(); + foreach (DoObjectInvToObjectInv h in list) + { + if (h(item, sourcePart, destPart) == false) + return false; + } + } + return true; + } + + public bool CanDropInObjectInv(InventoryItemBase item, IClientAPI client, SceneObjectPart destPart) + { + DoDropInObjectInv handler = OnDropInObjectInv; + if (handler != null) + { + if (client == null || client.SceneAgent == null|| destPart == null || item == null) + return false; + + ScenePresence sp = client.SceneAgent as ScenePresence; + if(sp == null || sp.IsDeleted) + return false; + + Delegate[] list = handler.GetInvocationList(); + foreach (DoDropInObjectInv h in list) + { + if (h(item, sp, destPart) == false) + return false; + } + } + return true; + } + public bool CanDeleteObjectInventory(UUID itemID, UUID objectID, UUID userID) { DeleteObjectInventoryHandler handler = OnDeleteObjectInventory; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2137b42417..715ae5cc30 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -540,6 +540,9 @@ namespace OpenSim.Region.Framework.Scenes private Timer m_mapGenerationTimer = new Timer(); private bool m_generateMaptiles; + protected int m_lastHealth = -1; + protected int m_lastUsers = -1; + #endregion Fields #region Properties @@ -805,6 +808,8 @@ namespace OpenSim.Region.Framework.Scenes private float m_minReprioritizationDistance = 32f; public bool ObjectsCullingByDistance = false; + private ExpiringCache TeleportTargetsCoolDown = new ExpiringCache(); + public AgentCircuitManager AuthenticateHandler { get { return m_authenticateHandler; } @@ -1212,6 +1217,30 @@ namespace OpenSim.Region.Framework.Scenes StatsReporter.OnSendStatsResult += SendSimStatsPackets; StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; + IConfig restartConfig = config.Configs["RestartModule"]; + if (restartConfig != null) + { + string markerPath = restartConfig.GetString("MarkerPath", String.Empty); + + if (markerPath != String.Empty) + { + string path = Path.Combine(markerPath, RegionInfo.RegionID.ToString() + ".started"); + try + { + string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); + FileStream fs = File.Create(path); + System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + Byte[] buf = enc.GetBytes(pidstring); + fs.Write(buf, 0, buf.Length); + fs.Close(); + } + catch (Exception) + { + } + } + } + + StartTimerWatchdog(); } public Scene(RegionInfo regInfo) @@ -1482,6 +1511,14 @@ namespace OpenSim.Region.Framework.Scenes return; } + IEtcdModule etcd = RequestModuleInterface(); + if (etcd != null) + { + etcd.Delete("Health"); + etcd.Delete("HealthFlags"); + etcd.Delete("RootAgents"); + } + m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); @@ -1520,6 +1557,8 @@ namespace OpenSim.Region.Framework.Scenes m_log.Debug("[SCENE]: Persisting changed objects"); Backup(true); + m_log.Debug("[SCENE]: Closing scene"); + m_sceneGraph.Close(); base.Close(); @@ -2351,6 +2390,7 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerOnSceneObjectLoaded(group); SceneObjectPart rootPart = group.GetPart(group.UUID); rootPart.Flags &= ~PrimFlags.Scripted; + group.AggregateDeepPerms(); rootPart.TrimPermissions(); // Don't do this here - it will get done later on when sculpt data is loaded. @@ -2603,8 +2643,8 @@ namespace OpenSim.Region.Framework.Scenes { // Otherwise, use this default creation code; sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); - AddNewSceneObject(sceneObject, true); sceneObject.SetGroup(groupID, null); + AddNewSceneObject(sceneObject, true); if (AgentPreferencesService != null) // This will override the brave new full perm world! { @@ -2622,6 +2662,7 @@ namespace OpenSim.Region.Framework.Scenes if (UserManagementModule != null) sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID); + sceneObject.AggregateDeepPerms(); sceneObject.ScheduleGroupForFullUpdate(); return sceneObject; @@ -2768,7 +2809,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup sog = (SceneObjectGroup)e; if (sog != null && !sog.IsAttachment) { - if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0)) + if (!exceptNoCopy || ((sog.EffectiveOwnerPerms & (uint)PermissionMask.Copy) != 0)) { DeleteSceneObject((SceneObjectGroup)e, false); } @@ -2782,7 +2823,7 @@ namespace OpenSim.Region.Framework.Scenes } if (toReturn.Count > 0) { - returnObjects(toReturn.ToArray(), UUID.Zero); + returnObjects(toReturn.ToArray(), null); } } @@ -2944,15 +2985,15 @@ namespace OpenSim.Region.Framework.Scenes // Return 'true' if position inside region. public bool PositionIsInCurrentRegion(Vector3 pos) { - bool ret = false; - int xx = (int)Math.Floor(pos.X); - int yy = (int)Math.Floor(pos.Y); - if (xx < 0 || yy < 0) + float t = pos.X; + if (t < 0 || t >= RegionInfo.RegionSizeX) return false; - if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) - ret = true; - return ret; + t = pos.Y; + if (t < 0 || t >= RegionInfo.RegionSizeY) + return false; + + return true; } /// @@ -3603,7 +3644,9 @@ namespace OpenSim.Region.Framework.Scenes /// Group of new object public void DuplicateObject(uint originalPrim, Vector3 offset, uint flags, UUID AgentID, UUID GroupID) { - SceneObjectGroup copy = SceneGraph.DuplicateObject(originalPrim, offset, flags, AgentID, GroupID, Quaternion.Identity); + bool createSelected = (flags & (uint)PrimFlags.CreateSelected) != 0; + SceneObjectGroup copy = SceneGraph.DuplicateObject(originalPrim, offset, AgentID, + GroupID, Quaternion.Identity, createSelected); if (copy != null) EventManager.TriggerObjectAddedToScene(copy); } @@ -3633,6 +3676,8 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart target = GetSceneObjectPart(localID); SceneObjectPart target2 = GetSceneObjectPart(RayTargetObj); + bool createSelected = (dupeFlags & (uint)PrimFlags.CreateSelected) != 0; + if (target != null && target2 != null) { Vector3 direction = Vector3.Normalize(RayEnd - RayStart); @@ -3674,13 +3719,13 @@ namespace OpenSim.Region.Framework.Scenes Quaternion worldRot = target2.GetWorldRotation(); // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); - copy = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); + copy = m_sceneGraph.DuplicateObject(localID, pos, AgentID, GroupID, worldRot, createSelected); //obj.Rotation = worldRot; //obj.UpdateGroupRotationR(worldRot); } else { - copy = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, Quaternion.Identity); + copy = m_sceneGraph.DuplicateObject(localID, pos, AgentID, GroupID, Quaternion.Identity, createSelected); } if (copy != null) @@ -3983,7 +4028,7 @@ namespace OpenSim.Region.Framework.Scenes if (!LoginsEnabled) { - reason = "Logins Disabled"; + reason = "Logins to this region are disabled"; return false; } @@ -5077,65 +5122,59 @@ Label_GroupsDone: #endregion #region Script Engine + public bool LSLScriptDanger(SceneObjectPart part, Vector3 pos) + { + + ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y); + if (parcel == null) + return true; + + LandData ldata = parcel.LandData; + if (ldata == null) + return true; + + uint landflags = ldata.Flags; + + uint mask = (uint)(ParcelFlags.CreateObjects | ParcelFlags.AllowAPrimitiveEntry); + if((landflags & mask) != mask) + return true; + + if((landflags & (uint)ParcelFlags.AllowOtherScripts) != 0) + return false; + + if(part == null) + return true; + if(part.GroupID == ldata.GroupID && (landflags & (uint)ParcelFlags.AllowGroupScripts) != 0) + return false; + + return true; + } private bool ScriptDanger(SceneObjectPart part, Vector3 pos) { + if (part == null) + return false; + ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y); - if (part != null) + if (parcel != null) { - if (parcel != null) - { - if ((parcel.LandData.Flags & (uint)ParcelFlags.AllowOtherScripts) != 0) - { - return true; - } - else if ((part.OwnerID == parcel.LandData.OwnerID) || Permissions.IsGod(part.OwnerID)) - { - return true; - } - else if (((parcel.LandData.Flags & (uint)ParcelFlags.AllowGroupScripts) != 0) - && (parcel.LandData.GroupID != UUID.Zero) && (parcel.LandData.GroupID == part.GroupID)) - { - return true; - } - else - { - return false; - } - } - else - { + if ((parcel.LandData.Flags & (uint)ParcelFlags.AllowOtherScripts) != 0) + return true; - if (pos.X > 0f && pos.X < RegionInfo.RegionSizeX && pos.Y > 0f && pos.Y < RegionInfo.RegionSizeY) - { - // The only time parcel != null when an object is inside a region is when - // there is nothing behind the landchannel. IE, no land plugin loaded. - return true; - } - else - { - // The object is outside of this region. Stop piping events to it. - return false; - } - } + if ((part.OwnerID == parcel.LandData.OwnerID) || Permissions.IsGod(part.OwnerID)) + return true; + + if (((parcel.LandData.Flags & (uint)ParcelFlags.AllowGroupScripts) != 0) + && (parcel.LandData.GroupID != UUID.Zero) && (parcel.LandData.GroupID == part.GroupID)) + return true; } else { - return false; + if (pos.X > 0f && pos.X < RegionInfo.RegionSizeX && pos.Y > 0f && pos.Y < RegionInfo.RegionSizeY) + return true; } - } - public bool ScriptDanger(uint localID, Vector3 pos) - { - SceneObjectPart part = GetSceneObjectPart(localID); - if (part != null) - { - return ScriptDanger(part, pos); - } - else - { - return false; - } + return false; } public bool PipeEventsForScript(uint localID) @@ -5512,23 +5551,24 @@ Label_GroupsDone: return 0; } - if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) + if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 2000) { health+=1; flags |= 1; } - if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000) + if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 2000) { health+=1; flags |= 2; } - if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000) + if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 2000) { health+=1; flags |= 4; } + /* else { int pid = System.Diagnostics.Process.GetCurrentProcess().Id; @@ -5541,6 +5581,7 @@ proc.WaitForExit(); Thread.Sleep(1000); Environment.Exit(1); } + */ if (flags != 7) return health; @@ -6305,6 +6346,32 @@ Environment.Exit(1); public void TimerWatchdog(object sender, ElapsedEventArgs e) { CheckHeartbeat(); + + IEtcdModule etcd = RequestModuleInterface(); + int flags; + string message; + if (etcd != null) + { + int health = GetHealth(out flags, out message); + if (health != m_lastHealth) + { + m_lastHealth = health; + + etcd.Store("Health", health.ToString(), 300000); + etcd.Store("HealthFlags", flags.ToString(), 300000); + } + + int roots = 0; + foreach (ScenePresence sp in GetScenePresences()) + if (!sp.IsChildAgent && !sp.IsNPC) + roots++; + + if (m_lastUsers != roots) + { + m_lastUsers = roots; + etcd.Store("RootAgents", roots.ToString(), 300000); + } + } } /// This method deals with movement when an avatar is automatically moving (but this is distinct from the @@ -6461,5 +6528,21 @@ Environment.Exit(1); m_eventManager.TriggerExtraSettingChanged(this, name, String.Empty); } + + public bool InTeleportTargetsCoolDown(UUID sourceID, UUID targetID, double timeout) + { + lock(TeleportTargetsCoolDown) + { + UUID lastSource = UUID.Zero; + TeleportTargetsCoolDown.TryGetValue(targetID, out lastSource); + if(lastSource == UUID.Zero) + { + TeleportTargetsCoolDown.Add(targetID, sourceID, timeout); + return false; + } + TeleportTargetsCoolDown.AddOrUpdate(targetID, sourceID, timeout); + return lastSource == sourceID; + } + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 2f65ce2ae9..a005068ecf 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -343,7 +343,7 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.ForceInventoryPersistence(); sceneObject.HasGroupChanged = true; } - + sceneObject.AggregateDeepPerms(); return ret; } @@ -549,6 +549,8 @@ namespace OpenSim.Region.Framework.Scenes // that are part of the Scene Object being removed m_numTotalPrim -= grp.PrimCount; + bool isPh = (grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics; + int nphysparts = 0; // Go through all parts (primitives and meshes) of this Scene Object foreach (SceneObjectPart part in grp.Parts) { @@ -559,10 +561,13 @@ namespace OpenSim.Region.Framework.Scenes m_numMesh--; else m_numPrim--; + + if(isPh && part.PhysicsShapeType != (byte)PhysShapeType.none) + nphysparts++; } - if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) - RemovePhysicalPrim(grp.PrimCount); + if (nphysparts > 0 ) + RemovePhysicalPrim(nphysparts); } bool ret = Entities.Remove(uuid); @@ -1358,7 +1363,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup grp = part.ParentGroup; if (grp != null) { - if (m_parentScene.Permissions.CanEditObject(grp.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(grp, remoteClient)) { // These two are exceptions SL makes in the interpretation // of the change flags. Must check them here because otherwise @@ -1379,7 +1384,7 @@ namespace OpenSim.Region.Framework.Scenes if ((data.change & (ObjectChangeType.Position | ObjectChangeType.Rotation)) != 0) { // Are we allowed to move it? - if (m_parentScene.Permissions.CanMoveObject(grp.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanMoveObject(grp, remoteClient)) { // Strip all but move and rotation from request data.change &= (ObjectChangeType.Group | ObjectChangeType.Position | ObjectChangeType.Rotation); @@ -1406,7 +1411,7 @@ namespace OpenSim.Region.Framework.Scenes if (part != null) { - if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(part.ParentGroup, remoteClient)) { bool physbuild = false; if (part.ParentGroup.RootPart.PhysActor != null) @@ -1428,7 +1433,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) { - if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(group, remoteClient)) { bool physbuild = false; if (group.RootPart.PhysActor != null) @@ -1474,7 +1479,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) { - if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanMoveObject(group, remoteClient)) { group.UpdateSingleRotation(rot, localID); } @@ -1492,7 +1497,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) { - if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanMoveObject(group, remoteClient)) { group.UpdateSingleRotation(rot, pos, localID); } @@ -1510,7 +1515,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) { - if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanMoveObject(group, remoteClient)) { group.UpdateGroupRotationR(rot); } @@ -1529,7 +1534,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) { - if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanMoveObject(group, remoteClient)) { group.UpdateGroupRotationPR(pos, rot); } @@ -1547,7 +1552,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) { - if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId) || group.IsAttachment) + if (m_parentScene.Permissions.CanMoveObject(group, remoteClient) || group.IsAttachment) { group.UpdateSinglePosition(pos, localID); } @@ -1561,17 +1566,6 @@ namespace OpenSim.Region.Framework.Scenes /// /// public void UpdatePrimGroupPosition(uint localId, Vector3 pos, IClientAPI remoteClient) - { - UpdatePrimGroupPosition(localId, pos, remoteClient.AgentId); - } - - /// - /// Update the position of the given group. - /// - /// - /// - /// - public void UpdatePrimGroupPosition(uint localId, Vector3 pos, UUID updatingAgentId) { SceneObjectGroup group = GetGroupByPrim(localId); @@ -1580,7 +1574,7 @@ namespace OpenSim.Region.Framework.Scenes if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) { // Set the new attachment point data in the object - byte attachmentPoint = group.GetAttachmentPoint(); + byte attachmentPoint = (byte)group.AttachmentPoint; group.UpdateGroupPosition(pos); group.IsAttachment = false; group.AbsolutePosition = group.RootPart.AttachedPos; @@ -1589,8 +1583,8 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (m_parentScene.Permissions.CanMoveObject(group.UUID, updatingAgentId) - && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos)) + if (m_parentScene.Permissions.CanMoveObject(group, remoteClient) + && m_parentScene.Permissions.CanObjectEntry(group, false, pos)) { group.UpdateGroupPosition(pos); } @@ -1614,7 +1608,7 @@ namespace OpenSim.Region.Framework.Scenes if (group != null) { - if (m_parentScene.Permissions.CanEditObject(group.UUID,remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(group, remoteClient)) { group.UpdateTextureEntry(localID, texture); } @@ -1638,7 +1632,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) { - if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(group, remoteClient)) { // VolumeDetect can't be set via UI and will always be off when a change is made there // now only change volume dtc if phantom off @@ -1685,7 +1679,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(primLocalID); if (group != null) { - if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(group, remoteClient)) { group.SetPartName(Util.CleanString(name), primLocalID); group.HasGroupChanged = true; @@ -1703,7 +1697,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(primLocalID); if (group != null) { - if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(group, remoteClient)) { group.SetPartDescription(Util.CleanString(description), primLocalID); group.HasGroupChanged = true; @@ -1725,7 +1719,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(primLocalID); if (group != null) { - if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(group, remoteClient)) { SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); if (part != null) @@ -1742,7 +1736,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = GetGroupByPrim(primLocalID); if (group != null) { - if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) + if (m_parentScene.Permissions.CanEditObject(group, remoteClient)) { SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); if (part != null) @@ -1996,6 +1990,7 @@ namespace OpenSim.Region.Framework.Scenes { newRoot.TriggerScriptChangedEvent(Changed.LINK); newRoot.ParentGroup.HasGroupChanged = true; + newRoot.ParentGroup.InvalidatePartsLinkMaps(); newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } } @@ -2012,6 +2007,7 @@ namespace OpenSim.Region.Framework.Scenes // from the database. They will be rewritten immediately, // minus the rows for the unlinked child prims. m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID); + g.InvalidatePartsLinkMaps(); g.TriggerScriptChangedEvent(Changed.LINK); g.HasGroupChanged = true; // Persist g.ScheduleGroupForFullUpdate(); @@ -2025,27 +2021,9 @@ namespace OpenSim.Region.Framework.Scenes protected internal void MakeObjectSearchable(IClientAPI remoteClient, bool IncludeInSearch, uint localID) { - UUID user = remoteClient.AgentId; - UUID objid = UUID.Zero; - SceneObjectPart obj = null; - - EntityBase[] entityList = GetEntities(); - foreach (EntityBase ent in entityList) - { - if (ent is SceneObjectGroup) - { - SceneObjectGroup sog = ent as SceneObjectGroup; - - foreach (SceneObjectPart part in sog.Parts) - { - if (part.LocalId == localID) - { - objid = part.UUID; - obj = part; - } - } - } - } + SceneObjectGroup sog = GetGroupByPrim(localID); + if(sog == null) + return; //Protip: In my day, we didn't call them searchable objects, we called them limited point-to-point joints //aka ObjectFlags.JointWheel = IncludeInSearch @@ -2062,15 +2040,15 @@ namespace OpenSim.Region.Framework.Scenes // libomv will complain about PrimFlags.JointWheel being // deprecated, so we #pragma warning disable 0612 - if (IncludeInSearch && m_parentScene.Permissions.CanEditObject(objid, user)) + if (IncludeInSearch && m_parentScene.Permissions.CanEditObject(sog, remoteClient)) { - obj.ParentGroup.RootPart.AddFlag(PrimFlags.JointWheel); - obj.ParentGroup.HasGroupChanged = true; + sog.RootPart.AddFlag(PrimFlags.JointWheel); + sog.HasGroupChanged = true; } - else if (!IncludeInSearch && m_parentScene.Permissions.CanMoveObject(objid,user)) + else if (!IncludeInSearch && m_parentScene.Permissions.CanMoveObject(sog, remoteClient)) { - obj.ParentGroup.RootPart.RemFlag(PrimFlags.JointWheel); - obj.ParentGroup.HasGroupChanged = true; + sog.RootPart.RemFlag(PrimFlags.JointWheel); + sog.HasGroupChanged = true; } #pragma warning restore 0612 } @@ -2086,7 +2064,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// null if duplication fails, otherwise the duplicated object /// - public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot) + public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, UUID AgentID, UUID GroupID, Quaternion rot, bool createSelected) { // m_log.DebugFormat( // "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}", @@ -2095,27 +2073,28 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup original = GetGroupByPrim(originalPrimID); if (original != null) { - if (m_parentScene.Permissions.CanDuplicateObject( - original.PrimCount, original.UUID, AgentID, original.AbsolutePosition)) + if (m_parentScene.Permissions.CanDuplicateObject(original, AgentID)) { SceneObjectGroup copy = original.Copy(true); copy.AbsolutePosition = copy.AbsolutePosition + offset; + SceneObjectPart[] parts = copy.Parts; + + m_numTotalPrim += parts.Length; + if (original.OwnerID != AgentID) { - copy.SetOwnerId(AgentID); - copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID); - - SceneObjectPart[] partList = copy.Parts; + copy.SetOwner(AgentID, GroupID); if (m_parentScene.Permissions.PropagatePermissions()) { - foreach (SceneObjectPart child in partList) + foreach (SceneObjectPart child in parts) { child.Inventory.ChangeInventoryOwner(AgentID); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } + copy.AggregatePerms(); } } @@ -2125,10 +2104,6 @@ namespace OpenSim.Region.Framework.Scenes lock (SceneObjectGroupsByFullID) SceneObjectGroupsByFullID[copy.UUID] = copy; - SceneObjectPart[] parts = copy.Parts; - - m_numTotalPrim += parts.Length; - foreach (SceneObjectPart part in parts) { if (part.GetPrimType() == PrimType.SCULPT) @@ -2144,28 +2119,19 @@ namespace OpenSim.Region.Framework.Scenes // PROBABLE END OF FIXME - // Since we copy from a source group that is in selected - // state, but the copy is shown deselected in the viewer, - // We need to clear the selection flag here, else that - // prim never gets persisted at all. The client doesn't - // think it's selected, so it will never send a deselect... - copy.IsSelected = false; - - m_numPrim += copy.Parts.Length; + copy.IsSelected = createSelected; if (rot != Quaternion.Identity) - { copy.UpdateGroupRotationR(rot); - } - - copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1); - copy.HasGroupChanged = true; - copy.ScheduleGroupForFullUpdate(); - copy.ResumeScripts(); // required for physics to update it's position - copy.AbsolutePosition = copy.AbsolutePosition; + copy.ResetChildPrimPhysicsPositions(); + copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1); + copy.ResumeScripts(); + + copy.HasGroupChanged = true; + copy.ScheduleGroupForFullUpdate(); return copy; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 9f98554ac0..12e53a8d27 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -111,7 +111,7 @@ namespace OpenSim.Region.Framework.Scenes /// The user inventory item being added. /// The item UUID that should be used by the new item. /// - public bool AddInventoryItem(UUID agentID, uint localID, InventoryItemBase item, UUID copyItemID) + public bool AddInventoryItem(UUID agentID, uint localID, InventoryItemBase item, UUID copyItemID, bool withModRights = true) { // m_log.DebugFormat( // "[PRIM INVENTORY]: Adding inventory item {0} from {1} to part with local ID {2}", @@ -120,69 +120,72 @@ namespace OpenSim.Region.Framework.Scenes UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID; SceneObjectPart part = GetPart(localID); - if (part != null) - { - TaskInventoryItem taskItem = new TaskInventoryItem(); - - taskItem.ItemID = newItemId; - taskItem.AssetID = item.AssetID; - taskItem.Name = item.Name; - taskItem.Description = item.Description; - taskItem.OwnerID = part.OwnerID; // Transfer ownership - taskItem.CreatorID = item.CreatorIdAsUuid; - taskItem.Type = item.AssetType; - taskItem.InvType = item.InvType; - - if (agentID != part.OwnerID && m_scene.Permissions.PropagatePermissions()) - { - taskItem.BasePermissions = item.BasePermissions & - item.NextPermissions; - taskItem.CurrentPermissions = item.CurrentPermissions & - item.NextPermissions; - taskItem.EveryonePermissions = item.EveryOnePermissions & - item.NextPermissions; - taskItem.GroupPermissions = item.GroupPermissions & - item.NextPermissions; - taskItem.NextPermissions = item.NextPermissions; - // We're adding this to a prim we don't own. Force - // owner change - taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; - } - else - { - taskItem.BasePermissions = item.BasePermissions; - taskItem.CurrentPermissions = item.CurrentPermissions; - taskItem.EveryonePermissions = item.EveryOnePermissions; - taskItem.GroupPermissions = item.GroupPermissions; - taskItem.NextPermissions = item.NextPermissions; - } - - taskItem.Flags = item.Flags; - -// m_log.DebugFormat( -// "[PRIM INVENTORY]: Flags are 0x{0:X} for item {1} added to part {2} by {3}", -// taskItem.Flags, taskItem.Name, localID, remoteClient.Name); - - // TODO: These are pending addition of those fields to TaskInventoryItem -// taskItem.SalePrice = item.SalePrice; -// taskItem.SaleType = item.SaleType; - taskItem.CreationDate = (uint)item.CreationDate; - - bool addFromAllowedDrop = agentID != part.OwnerID; - - part.Inventory.AddInventoryItem(taskItem, addFromAllowedDrop); - - return true; - } - else + if (part == null) { m_log.ErrorFormat( "[PRIM INVENTORY]: " + "Couldn't find prim local ID {0} in group {1}, {2} to add inventory item ID {3}", localID, Name, UUID, newItemId); + return false; } - return false; + TaskInventoryItem taskItem = new TaskInventoryItem(); + + taskItem.ItemID = newItemId; + taskItem.AssetID = item.AssetID; + taskItem.Name = item.Name; + taskItem.Description = item.Description; + taskItem.OwnerID = part.OwnerID; // Transfer ownership + taskItem.CreatorID = item.CreatorIdAsUuid; + taskItem.Type = item.AssetType; + taskItem.InvType = item.InvType; + + if (agentID != part.OwnerID && m_scene.Permissions.PropagatePermissions()) + { + taskItem.BasePermissions = item.BasePermissions & + item.NextPermissions; + taskItem.CurrentPermissions = item.CurrentPermissions & + item.NextPermissions; + taskItem.EveryonePermissions = item.EveryOnePermissions & + item.NextPermissions; + taskItem.GroupPermissions = item.GroupPermissions & + item.NextPermissions; + taskItem.NextPermissions = item.NextPermissions; + // We're adding this to a prim we don't own. Force + // owner change + taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; + + } + else + { + taskItem.BasePermissions = item.BasePermissions; + taskItem.CurrentPermissions = item.CurrentPermissions; + taskItem.EveryonePermissions = item.EveryOnePermissions; + taskItem.GroupPermissions = item.GroupPermissions; + taskItem.NextPermissions = item.NextPermissions; + } + + taskItem.Flags = item.Flags; + +// m_log.DebugFormat( +// "[PRIM INVENTORY]: Flags are 0x{0:X} for item {1} added to part {2} by {3}", +// taskItem.Flags, taskItem.Name, localID, remoteClient.Name); + + // TODO: These are pending addition of those fields to TaskInventoryItem +// taskItem.SalePrice = item.SalePrice; +// taskItem.SaleType = item.SaleType; + taskItem.CreationDate = (uint)item.CreationDate; + + bool addFromAllowedDrop; + if(withModRights) + addFromAllowedDrop = false; + else + addFromAllowedDrop = (part.ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0; + + part.Inventory.AddInventoryItem(taskItem, addFromAllowedDrop); + part.ParentGroup.AggregatePerms(); + return true; + } /// @@ -248,6 +251,194 @@ namespace OpenSim.Region.Framework.Scenes return -1; } + // new test code, to place in better place later + private object PermissionsLock = new object(); + + private uint m_EffectiveEveryOnePerms; + public uint EffectiveEveryOnePerms + { + get + { + // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) + // bc this is on heavy duty code paths + // but for now we need to test the concept +// AggregateDeepPerms(); + return m_EffectiveEveryOnePerms; + } + } + + private uint m_EffectiveGroupPerms; + public uint EffectiveGroupPerms + { + get + { + // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) + // bc this is on heavy duty code paths + // but for now we need to test the concept +// AggregateDeepPerms(); + return m_EffectiveGroupPerms; + } + } + + private uint m_EffectiveGroupOrEveryOnePerms; + public uint EffectiveGroupOrEveryOnePerms + { + get + { + // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) + // bc this is on heavy duty code paths + // but for now we need to test the concept +// AggregateDeepPerms(); + return m_EffectiveGroupOrEveryOnePerms; + } + } + + private uint m_EffectiveOwnerPerms; + public uint EffectiveOwnerPerms + { + get + { + // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) + // bc this is on heavy duty code paths + // but for now we need to test the concept + // AggregateDeepPerms(); + return m_EffectiveOwnerPerms; + } + } + + // aggregates perms scanning parts and their contents + // AggregatePerms does same using cached parts content perms + public void AggregateDeepPerms() + { + lock(PermissionsLock) + { + // aux + const uint allmask = (uint)PermissionMask.AllEffective; + const uint movemodmask = (uint)(PermissionMask.Move | PermissionMask.Modify); + const uint copytransfermast = (uint)(PermissionMask.Copy | PermissionMask.Transfer); + + uint basePerms = (RootPart.BaseMask & allmask) | (uint)PermissionMask.Move; + bool noBaseTransfer = (basePerms & (uint)PermissionMask.Transfer) == 0; + + uint rootOwnerPerms = RootPart.OwnerMask; + uint owner = rootOwnerPerms; + uint rootGroupPerms = RootPart.GroupMask; + uint group = rootGroupPerms; + uint rootEveryonePerms = RootPart.EveryoneMask; + uint everyone = rootEveryonePerms; + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + part.AggregateInnerPerms(); + owner &= part.AggregatedInnerOwnerPerms; + group &= part.AggregatedInnerGroupPerms; + everyone &= part.AggregatedInnerEveryonePerms; + } + // recover modify and move + rootOwnerPerms &= movemodmask; + owner |= rootOwnerPerms; + if((owner & copytransfermast) == 0) + owner |= (uint)PermissionMask.Transfer; + + owner &= basePerms; + m_EffectiveOwnerPerms = owner; + uint ownertransfermask = owner & (uint)PermissionMask.Transfer; + + // recover modify and move + rootGroupPerms &= movemodmask; + group |= rootGroupPerms; + if(noBaseTransfer) + group &=~(uint)PermissionMask.Copy; + else + group |= ownertransfermask; + + uint groupOrEveryone = group; + m_EffectiveGroupPerms = group & owner; + + // recover move + rootEveryonePerms &= (uint)PermissionMask.Move; + everyone |= rootEveryonePerms; + everyone &= ~(uint)PermissionMask.Modify; + if(noBaseTransfer) + everyone &=~(uint)PermissionMask.Copy; + else + everyone |= ownertransfermask; + + groupOrEveryone |= everyone; + + m_EffectiveEveryOnePerms = everyone & owner; + m_EffectiveGroupOrEveryOnePerms = groupOrEveryone & owner; + } + } + + // aggregates perms scanning parts, assuming their contents was already aggregated and cached + // ie is AggregateDeepPerms without the part.AggregateInnerPerms() call on parts loop + public void AggregatePerms() + { + lock(PermissionsLock) + { + // aux + const uint allmask = (uint)PermissionMask.AllEffective; + const uint movemodmask = (uint)(PermissionMask.Move | PermissionMask.Modify); + const uint copytransfermast = (uint)(PermissionMask.Copy | PermissionMask.Transfer); + + uint basePerms = (RootPart.BaseMask & allmask) | (uint)PermissionMask.Move; + bool noBaseTransfer = (basePerms & (uint)PermissionMask.Transfer) == 0; + + uint rootOwnerPerms = RootPart.OwnerMask; + uint owner = rootOwnerPerms; + uint rootGroupPerms = RootPart.GroupMask; + uint group = rootGroupPerms; + uint rootEveryonePerms = RootPart.EveryoneMask; + uint everyone = rootEveryonePerms; + + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + owner &= part.AggregatedInnerOwnerPerms; + group &= part.AggregatedInnerGroupPerms; + everyone &= part.AggregatedInnerEveryonePerms; + } + // recover modify and move + rootOwnerPerms &= movemodmask; + owner |= rootOwnerPerms; + if((owner & copytransfermast) == 0) + owner |= (uint)PermissionMask.Transfer; + + owner &= basePerms; + m_EffectiveOwnerPerms = owner; + uint ownertransfermask = owner & (uint)PermissionMask.Transfer; + + // recover modify and move + rootGroupPerms &= movemodmask; + group |= rootGroupPerms; + if(noBaseTransfer) + group &=~(uint)PermissionMask.Copy; + else + group |= ownertransfermask; + + uint groupOrEveryone = group; + m_EffectiveGroupPerms = group & owner; + + // recover move + rootEveryonePerms &= (uint)PermissionMask.Move; + everyone |= rootEveryonePerms; + everyone &= ~(uint)PermissionMask.Modify; + if(noBaseTransfer) + everyone &=~(uint)PermissionMask.Copy; + else + everyone |= ownertransfermask; + + groupOrEveryone |= everyone; + + m_EffectiveEveryOnePerms = everyone & owner; + m_EffectiveGroupOrEveryOnePerms = groupOrEveryone & owner; + } + } + public uint GetEffectivePermissions() { return GetEffectivePermissions(false); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5928764a24..e73795e0ce 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -117,9 +117,6 @@ namespace OpenSim.Region.Framework.Scenes NOT_STATUS_ROTATE_Z = 0xF7 } - // This flag has the same purpose as InventoryItemFlags.ObjectSlamPerm - public static readonly uint SLAM = 16; - // private PrimCountTaintedDelegate handlerPrimCountTainted = null; /// @@ -156,7 +153,7 @@ namespace OpenSim.Region.Framework.Scenes timeLastChanged = DateTime.UtcNow.Ticks; if (!m_hasGroupChanged) timeFirstChanged = DateTime.UtcNow.Ticks; - if (m_rootPart != null && m_rootPart.UUID != null && m_scene != null) + if (m_rootPart != null && m_scene != null) { /* if (m_rand == null) @@ -379,6 +376,8 @@ namespace OpenSim.Region.Framework.Scenes public bool m_dupeInProgress = false; internal Dictionary m_savedScriptState; + public UUID MonitoringObject { get; set; } + #region Properties /// @@ -539,7 +538,7 @@ namespace OpenSim.Region.Framework.Scenes public bool inTransit = false; - public delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos); + private delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos, TeleportObjectData tpData); /// /// The absolute position of this scene object in the scene @@ -561,7 +560,7 @@ namespace OpenSim.Region.Framework.Scenes { inTransit = true; SOGCrossDelegate d = CrossAsync; - d.BeginInvoke(this, val, CrossAsyncCompleted, d); + d.BeginInvoke(this, val, null, CrossAsyncCompleted, d); } return; } @@ -602,7 +601,6 @@ namespace OpenSim.Region.Framework.Scenes av.sitSOGmoved(); } - // now that position is changed tell it to scripts if (triggerScriptEvent) { @@ -618,64 +616,75 @@ namespace OpenSim.Region.Framework.Scenes } } - public SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val) + private SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val, TeleportObjectData tpdata) { Scene sogScene = sog.m_scene; + SceneObjectPart root = sog.RootPart; + + bool isTeleport = tpdata != null; + + if(!isTeleport) + { + if (root.DIE_AT_EDGE) + { + try + { + sogScene.DeleteSceneObject(sog, false); + } + catch (Exception) + { + m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border."); + } + return sog; + } + + if (root.RETURN_AT_EDGE) + { + // We remove the object here + try + { + List localIDs = new List(); + localIDs.Add(root.LocalId); + sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition, + "Returned at region cross"); + sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero, false); + } + catch (Exception) + { + m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border."); + } + return sog; + } + } + + if (root.KeyframeMotion != null) + root.KeyframeMotion.StartCrossingCheck(); + + if(root.PhysActor != null) + root.PhysActor.CrossingStart(); + IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface(); - Vector3 newpos = Vector3.Zero; - OpenSim.Services.Interfaces.GridRegion destination = null; - - if (sog.RootPart.DIE_AT_EDGE) - { - try - { - sogScene.DeleteSceneObject(sog, false); - } - catch (Exception) - { - m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border."); - } - return sog; - } - - if (sog.RootPart.RETURN_AT_EDGE) - { - // We remove the object here - try - { - List localIDs = new List(); - localIDs.Add(sog.RootPart.LocalId); - sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition, - "Returned at region cross"); - sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero); - } - catch (Exception) - { - m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border."); - } - return sog; - } - - if (sog.m_rootPart.KeyframeMotion != null) - sog.m_rootPart.KeyframeMotion.StartCrossingCheck(); - if (entityTransfer == null) return sog; + Vector3 newpos = Vector3.Zero; + OpenSim.Services.Interfaces.GridRegion destination = null; + destination = entityTransfer.GetObjectDestination(sog, val, out newpos); if (destination == null) return sog; if (sog.m_sittingAvatars.Count == 0) { - entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, true); + entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, !isTeleport, true); return sog; } string reason = String.Empty; EntityTransferContext ctx = new EntityTransferContext(); + Vector3 curPos = root.GroupPosition; foreach (ScenePresence av in sog.m_sittingAvatars) { // We need to cross these agents. First, let's find @@ -686,10 +695,15 @@ namespace OpenSim.Region.Framework.Scenes // We set the avatar position as being the object // position to get the region to send to - if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason)) - { + if(av.IsNPC) + continue; + + if(av.IsInTransit) return sog; - } + + if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason)) + return sog; + m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); } @@ -697,8 +711,10 @@ namespace OpenSim.Region.Framework.Scenes // be made to stand up List avsToCross = new List(); - - foreach (ScenePresence av in sog.m_sittingAvatars) + List avsToCrossFar = new List(); + ulong destHandle = destination.RegionHandle; + List sittingAvatars = GetSittingAvatars(); + foreach (ScenePresence av in sittingAvatars) { byte cflags = 1; @@ -712,68 +728,175 @@ namespace OpenSim.Region.Framework.Scenes else cflags = 3; } + if(!av.knowsNeighbourRegion(destHandle)) + cflags |= 8; // 1 is crossing // 2 is sitting // 4 is sitting at sittarget - av.crossingFlags = cflags; + // 8 far crossing avinfo.av = av; avinfo.ParentID = av.ParentID; avsToCross.Add(avinfo); + if(!av.knowsNeighbourRegion(destHandle)) + { + cflags |= 8; + avsToCrossFar.Add(av); + } + + if(av.IsNPC) + av.crossingFlags = 0; + else + av.crossingFlags = cflags; + av.PrevSitOffset = av.OffsetPosition; av.ParentID = 0; } + Vector3 vel = root.Velocity; + Vector3 avel = root.AngularVelocity; + Vector3 acc = root.Acceleration; + Quaternion ori = root.RotationOffset; + + if(isTeleport) + { + root.Stop(); + sogScene.ForEachScenePresence(delegate(ScenePresence av) + { + av.ControllingClient.SendEntityUpdate(root,PrimUpdateFlags.SendInTransit); + av.ControllingClient.SendEntityTerseUpdateImmediate(root); + }); + + root.Velocity = tpdata.vel; + root.AngularVelocity = tpdata.avel; + root.Acceleration = tpdata.acc; + root.RotationOffset = tpdata.ori; + } + if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, false)) { + if(isTeleport) + { + sogScene.ForEachScenePresence(delegate(ScenePresence oav) + { + if(sittingAvatars.Contains(oav)) + return; + if(oav.knowsNeighbourRegion(destHandle)) + return; + oav.ControllingClient.SendEntityUpdate(root, PrimUpdateFlags.Kill); + foreach (ScenePresence sav in sittingAvatars) + { + sav.SendKillTo(oav); + } + }); + } + bool crossedfar = false; + foreach (ScenePresence av in avsToCrossFar) + { + if(entityTransfer.CrossAgentCreateFarChild(av,destination, newpos, ctx)) + crossedfar = true; + else + av.crossingFlags = 0; + } + + if(crossedfar) + Thread.Sleep(1000); + foreach (avtocrossInfo avinfo in avsToCross) { ScenePresence av = avinfo.av; - if (!av.IsInTransit) // just in case... + av.IsInTransit = true; + m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); + + if(av.crossingFlags > 0) + entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, false, ctx); + + if (av.IsChildAgent) { - m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); - - av.IsInTransit = true; - -// CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; -// d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); - entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, ctx); - if (av.IsChildAgent) + // avatar crossed do some extra cleanup + if (av.ParentUUID != UUID.Zero) { - // avatar crossed do some extra cleanup - if (av.ParentUUID != UUID.Zero) - { - av.ClearControls(); - av.ParentPart = null; - } + av.ClearControls(); + av.ParentPart = null; } - else - { - // avatar cross failed we need do dedicated standUp - // part of it was done at CrossAgentToNewRegionAsync - // so for now just remove the sog controls - // this may need extra care - av.UnRegisterSeatControls(sog.UUID); - } - av.ParentUUID = UUID.Zero; + av.ParentPart = null; // In any case av.IsInTransit = false; av.crossingFlags = 0; m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname); } else - m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val); + { + // avatar cross failed we need do dedicated standUp + // part of it was done at CrossAgentToNewRegionAsync + // so for now just remove the sog controls + // this may need extra care + av.UnRegisterSeatControls(sog.UUID); + av.ParentUUID = UUID.Zero; + av.ParentPart = null; + Vector3 oldp = curPos; + oldp.X = Util.Clamp(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f); + oldp.Y = Util.Clamp(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f); + av.AbsolutePosition = oldp; + av.crossingFlags = 0; + av.sitAnimation = "SIT"; + av.IsInTransit = false; + if(av.Animator!= null) + av.Animator.SetMovementAnimations("STAND"); + av.AddToPhysicalScene(false); + sogScene.ForEachScenePresence(delegate(ScenePresence oav) + { + if(sittingAvatars.Contains(oav)) + return; + if(oav.knowsNeighbourRegion(destHandle)) + av.SendAvatarDataToAgent(oav); + else + { + av.SendAvatarDataToAgent(oav); + av.SendAppearanceToAgent(oav); + if (av.Animator != null) + av.Animator.SendAnimPackToClient(oav.ControllingClient); + av.SendAttachmentsToAgentNF(oav); // not ok + } + }); + m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} failed.", av.Firstname, av.Lastname); + } } + + if(crossedfar) + { + Thread.Sleep(10000); + foreach (ScenePresence av in avsToCrossFar) + { + if(av.IsChildAgent) + { + av.Scene.CloseAgent(av.UUID, false); + } + else + av.RemoveNeighbourRegion(destHandle); + } + } + avsToCrossFar.Clear(); avsToCross.Clear(); sog.RemoveScriptInstances(true); sog.Clear(); return sog; } - else // cross failed, put avas back ?? + else { + if(isTeleport) + { + if((tpdata.flags & OSTPOBJ_STOPONFAIL) == 0) + { + root.Velocity = vel; + root.AngularVelocity = avel; + root.Acceleration = acc; + } + root.RotationOffset = ori; + } foreach (avtocrossInfo avinfo in avsToCross) { ScenePresence av = avinfo.av; @@ -783,7 +906,6 @@ namespace OpenSim.Region.Framework.Scenes } } avsToCross.Clear(); - return sog; } @@ -795,11 +917,14 @@ namespace OpenSim.Region.Framework.Scenes if (!sog.IsDeleted) { SceneObjectPart rootp = sog.m_rootPart; + Vector3 oldp = rootp.GroupPosition; oldp.X = Util.Clamp(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f); oldp.Y = Util.Clamp(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f); rootp.GroupPosition = oldp; + rootp.Stop(); + SceneObjectPart[] parts = sog.m_parts.GetArray(); foreach (SceneObjectPart part in parts) @@ -813,47 +938,150 @@ namespace OpenSim.Region.Framework.Scenes av.sitSOGmoved(); } - sog.Velocity = Vector3.Zero; - if (sog.m_rootPart.KeyframeMotion != null) sog.m_rootPart.KeyframeMotion.CrossingFailure(); if (sog.RootPart.PhysActor != null) - { sog.RootPart.PhysActor.CrossingFailure(); - } sog.inTransit = false; + AttachToBackup(); sog.ScheduleGroupForFullUpdate(); } } -/* outdated - private void CrossAgentToNewRegionCompleted(ScenePresence agent) + private class TeleportObjectData { - //// If the cross was successful, this agent is a child agent - if (agent.IsChildAgent) + public int flags; + public Vector3 vel; + public Vector3 avel; + public Vector3 acc; + public Quaternion ori; + public UUID sourceID; + } + + // copy from LSL_constants.cs + const int OSTPOBJ_STOPATTARGET = 0x1; // stops at destination + const int OSTPOBJ_STOPONFAIL = 0x2; // stops at start if tp fails + const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation + + public int TeleportObject(UUID sourceID, Vector3 targetPosition, Quaternion rotation, int flags) + { + if(inTransit || IsDeleted || IsAttachmentCheckFull() || IsSelected || Scene == null) + return -1; + + inTransit = true; + + PhysicsActor pa = RootPart.PhysActor; + if(pa == null || RootPart.KeyframeMotion != null /*|| m_sittingAvatars.Count == 0*/) { - if (agent.ParentUUID != UUID.Zero) - { - agent.HandleForceReleaseControls(agent.ControllingClient,agent.UUID); - agent.ParentPart = null; -// agent.ParentPosition = Vector3.Zero; -// agent.ParentUUID = UUID.Zero; - } + inTransit = false; + return -1; } - agent.ParentUUID = UUID.Zero; -// agent.Reset(); -// else // Not successful -// agent.RestoreInCurrentScene(); + bool stop = (flags & OSTPOBJ_STOPATTARGET) != 0; + bool setrot = (flags & OSTPOBJ_SETROT) != 0; - // In any case - agent.IsInTransit = false; + rotation.Normalize(); + + Quaternion currentRot = RootPart.RotationOffset; + if(setrot) + rotation = Quaternion.Conjugate(currentRot) * rotation; - m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); + bool dorot = setrot | (Math.Abs(rotation.W) < 0.99999); + + Vector3 vel = Vector3.Zero; + Vector3 avel = Vector3.Zero; + Vector3 acc = Vector3.Zero; + + if(!stop) + { + vel = RootPart.Velocity; + avel = RootPart.AngularVelocity; + acc = RootPart.Acceleration; + } + Quaternion ori = RootPart.RotationOffset; + + if(dorot) + { + if(!stop) + { + vel *= rotation; + avel *= rotation; + acc *= rotation; + } + ori *= rotation; + } + + if(Scene.PositionIsInCurrentRegion(targetPosition)) + { + if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 1.0)) + { + inTransit = false; + return -2; + } + + Vector3 curPos = AbsolutePosition; + ILandObject curLand = Scene.LandChannel.GetLandObject(curPos.X, curPos.Y); + float posX = targetPosition.X; + float posY = targetPosition.Y; + ILandObject land = Scene.LandChannel.GetLandObject(posX, posY); + if(land != null && land != curLand) + { + if(!Scene.Permissions.CanObjectEnterWithScripts(this, land)) + { + inTransit = false; + return -3; + } + + UUID agentID; + foreach (ScenePresence av in m_sittingAvatars) + { + agentID = av.UUID; + if(land.IsRestrictedFromLand(agentID) || land.IsBannedFromLand(agentID)) + { + inTransit = false; + return -4; + } + } + } + + RootPart.Velocity = vel; + RootPart.AngularVelocity = avel; + RootPart.Acceleration = acc; + RootPart.RotationOffset = ori; + + Vector3 s = RootPart.Scale * RootPart.RotationOffset; + float h = Scene.GetGroundHeight(posX, posY) + 0.5f * (float)Math.Abs(s.Z) + 0.01f; + if(targetPosition.Z < h) + targetPosition.Z = h; + + inTransit = false; + AbsolutePosition = targetPosition; + RootPart.ScheduleTerseUpdate(); + return 1; + } + + if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 20.0)) + { + inTransit = false; + return -1; + } + + TeleportObjectData tdata = new TeleportObjectData(); + tdata.flags = flags; + tdata.vel = vel; + tdata.avel = avel; + tdata.acc = acc; + tdata.ori = ori; + tdata.sourceID = sourceID; + + + SOGCrossDelegate d = CrossAsync; + d.BeginInvoke(this, targetPosition, tdata, CrossAsyncCompleted, d); + return 0; } -*/ + public override Vector3 Velocity { get { return RootPart.Velocity; } @@ -1786,63 +2014,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Attach this scene object to the given avatar. - /// - /// - /// - /// - private void AttachToAgent( - ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) - { - if (avatar != null) - { - // don't attach attachments to child agents - if (avatar.IsChildAgent) return; - - // Remove from database and parcel prim count - m_scene.DeleteFromStorage(so.UUID); - m_scene.EventManager.TriggerParcelPrimCountTainted(); - - so.AttachedAvatar = avatar.UUID; - - if (so.RootPart.PhysActor != null) - { - m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor); - so.RootPart.PhysActor = null; - } - - so.AbsolutePosition = attachOffset; - so.RootPart.AttachedPos = attachOffset; - so.IsAttachment = true; - so.RootPart.SetParentLocalId(avatar.LocalId); - so.AttachmentPoint = attachmentpoint; - - avatar.AddAttachment(this); - - if (!silent) - { - // Killing it here will cause the client to deselect it - // It then reappears on the avatar, deselected - // through the full update below - // - if (IsSelected) - { - m_scene.SendKillObject(new List { m_rootPart.LocalId }); - } - - IsSelected = false; // fudge.... - ScheduleGroupForFullUpdate(); - } - } - else - { - m_log.WarnFormat( - "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present", - UUID, avatar.ControllingClient.AgentId, Scene.RegionInfo.RegionName); - } - } - public byte GetAttachmentPoint() { return m_rootPart.Shape.State; @@ -1957,6 +2128,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.LinkNum == 2) RootPart.LinkNum = 1; + InvalidatePartsLinkMaps(); } /// @@ -2233,7 +2405,8 @@ namespace OpenSim.Region.Framework.Scenes { if (part.OwnerID != userId) { - part.LastOwnerID = part.OwnerID; + if(part.GroupID != part.OwnerID) + part.LastOwnerID = part.OwnerID; part.OwnerID = userId; } }); @@ -2313,7 +2486,7 @@ namespace OpenSim.Region.Framework.Scenes RootPart.UUID); m_scene.AddReturn(OwnerID == GroupID ? LastOwnerID : OwnerID, Name, AbsolutePosition, "parcel autoreturn"); m_scene.DeRezObjects(null, new List() { RootPart.LocalId }, UUID.Zero, - DeRezAction.Return, UUID.Zero); + DeRezAction.Return, UUID.Zero, false); return; } @@ -2443,17 +2616,16 @@ namespace OpenSim.Region.Framework.Scenes dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; - if (userExposed) dupe.m_rootPart.TrimPermissions(); List partList = new List(m_parts.GetArray()); partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) - { - return p1.LinkNum.CompareTo(p2.LinkNum); - } - ); + { + return p1.LinkNum.CompareTo(p2.LinkNum); + } + ); foreach (SceneObjectPart part in partList) { @@ -2505,12 +2677,15 @@ namespace OpenSim.Region.Framework.Scenes if (dupe.m_rootPart.PhysActor != null) dupe.m_rootPart.PhysActor.Building = false; // tell physics to finish building + dupe.AggregateDeepPerms(); + dupe.HasGroupChanged = true; dupe.AttachToBackup(); - ScheduleGroupForFullUpdate(); + dupe.ScheduleGroupForFullUpdate(); } + dupe.InvalidatePartsLinkMaps(); m_dupeInProgress = false; return dupe; } @@ -2746,25 +2921,33 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Set the owner of the root part. + /// Set the owner of all linkset. /// - /// /// /// - public void SetRootPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID) + public void SetOwner(UUID cAgentID, UUID cGroupID) { - part.LastOwnerID = part.OwnerID; - part.OwnerID = cAgentID; - part.GroupID = cGroupID; + SceneObjectPart rpart = RootPart; + UUID oldowner = rpart.OwnerID; + ForEachPart(delegate(SceneObjectPart part) + { + if(part.GroupID != part.OwnerID) + part.LastOwnerID = part.OwnerID; + part.OwnerID = cAgentID; + part.GroupID = cGroupID; + }); - if (part.OwnerID != cAgentID) + if (oldowner != cAgentID) { // Apply Next Owner Permissions if we're not bypassing permissions if (!m_scene.Permissions.BypassPermissions()) + { ApplyNextOwnerPermissions(); + AggregatePerms(); + } } - part.ScheduleFullUpdate(); + rpart.ScheduleFullUpdate(); } /// @@ -3264,6 +3447,7 @@ namespace OpenSim.Region.Framework.Scenes ResetChildPrimPhysicsPositions(); InvalidBoundsRadius(); + InvalidatePartsLinkMaps(); if (m_rootPart.PhysActor != null) m_rootPart.PhysActor.Building = false; @@ -3420,6 +3604,8 @@ namespace OpenSim.Region.Framework.Scenes objectGroup.HasGroupChangedDueToDelink = true; InvalidBoundsRadius(); + InvalidatePartsLinkMaps(); + objectGroup.AggregatePerms(); if (sendEvents) linkPart.TriggerScriptChangedEvent(Changed.LINK); @@ -3958,8 +4144,8 @@ namespace OpenSim.Region.Framework.Scenes public void AdjustChildPrimPermissions(bool forceTaskInventoryPermissive) { - uint newOwnerMask = (uint)(PermissionMask.All | PermissionMask.Export) & 0xfffffff8; // Mask folded bits - uint foldedPerms = RootPart.OwnerMask & 3; + uint newOwnerMask = (uint)(PermissionMask.All | PermissionMask.Export) & 0xfffffff0; // Mask folded bits + uint foldedPerms = RootPart.OwnerMask & (uint)PermissionMask.FoldedMask; ForEachPart(part => { @@ -3970,14 +4156,14 @@ namespace OpenSim.Region.Framework.Scenes part.Inventory.ApplyGodPermissions(part.BaseMask); }); - uint lockMask = ~(uint)(PermissionMask.Move | PermissionMask.Modify); - uint lockBit = RootPart.OwnerMask & (uint)(PermissionMask.Move | PermissionMask.Modify); + uint lockMask = ~(uint)(PermissionMask.Move); + uint lockBit = RootPart.OwnerMask & (uint)(PermissionMask.Move); RootPart.OwnerMask = (RootPart.OwnerMask & lockBit) | ((newOwnerMask | foldedPerms) & lockMask); // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: RootPart.OwnerMask now {0} for {1} in {2}", // (OpenMetaverse.PermissionMask)RootPart.OwnerMask, Name, Scene.Name); - + AggregatePerms(); RootPart.ScheduleFullUpdate(); } @@ -4002,6 +4188,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectPart part in Parts) part.Inventory.ApplyGodPermissions(RootPart.BaseMask); + AggregatePerms(); } HasGroupChanged = true; @@ -4647,7 +4834,7 @@ namespace OpenSim.Region.Framework.Scenes } if ((change & ObjectChangeType.Position) != 0) { - if (IsAttachment || m_scene.Permissions.CanObjectEntry(group.UUID, false, data.position)) + if (IsAttachment || m_scene.Permissions.CanObjectEntry(group, false, data.position)) UpdateGroupPosition(data.position); updateType = updatetype.groupterse; } @@ -5056,6 +5243,49 @@ namespace OpenSim.Region.Framework.Scenes return Ptot; } + public void GetInertiaData(out float TotalMass, out Vector3 CenterOfMass, out Vector3 Inertia, out Vector4 aux ) + { + PhysicsActor pa = RootPart.PhysActor; + + if(((RootPart.Flags & PrimFlags.Physics) !=0) && pa !=null) + { + PhysicsInertiaData inertia; + + inertia = pa.GetInertiaData(); + + TotalMass = inertia.TotalMass; + CenterOfMass = inertia.CenterOfMass; + Inertia = inertia.Inertia; + aux = inertia.InertiaRotation; + + return; + } + + TotalMass = GetMass(); + CenterOfMass = GetCenterOfMass() - AbsolutePosition; + CenterOfMass *= Quaternion.Conjugate(RootPart.RotationOffset); + Inertia = Vector3.Zero; + aux = Vector4.Zero; + } + + public void SetInertiaData(float TotalMass, Vector3 CenterOfMass, Vector3 Inertia, Vector4 aux ) + { + PhysicsInertiaData inertia = new PhysicsInertiaData(); + inertia.TotalMass = TotalMass; + inertia.CenterOfMass = CenterOfMass; + inertia.Inertia = Inertia; + inertia.InertiaRotation = aux; + + if(TotalMass < 0) + RootPart.PhysicsInertia = null; + else + RootPart.PhysicsInertia = new PhysicsInertiaData(inertia); + + PhysicsActor pa = RootPart.PhysActor; + if(pa !=null) + pa.SetInertiaData(inertia); + } + /// /// Set the user group to which this scene object belongs. /// @@ -5217,6 +5447,7 @@ namespace OpenSim.Region.Framework.Scenes { part.ResetOwnerChangeFlag(); }); + AggregatePerms(); } // clear some references to easy cg @@ -5230,6 +5461,84 @@ namespace OpenSim.Region.Framework.Scenes m_PlaySoundSlavePrims.Clear(); m_LoopSoundMasterPrim = null; m_targets.Clear(); + m_partsNameToLinkMap.Clear(); + } + + private Dictionary m_partsNameToLinkMap = new Dictionary(); + private string GetLinkNumber_lastname; + private int GetLinkNumber_lastnumber; + + // this scales bad but so does GetLinkNumPart + public int GetLinkNumber(string name) + { + if(String.IsNullOrEmpty(name) || name == "Object") + return -1; + + lock(m_partsNameToLinkMap) + { + if(m_partsNameToLinkMap.Count == 0) + { + GetLinkNumber_lastname = String.Empty; + GetLinkNumber_lastnumber = -1; + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + string s = parts[i].Name; + if(String.IsNullOrEmpty(s) || s == "Object" || s == "Primitive") + continue; + + if(m_partsNameToLinkMap.ContainsKey(s)) + { + int ol = parts[i].LinkNum; + if(ol < m_partsNameToLinkMap[s]) + m_partsNameToLinkMap[s] = ol; + } + else + m_partsNameToLinkMap[s] = parts[i].LinkNum; + } + } + + if(name == GetLinkNumber_lastname) + return GetLinkNumber_lastnumber; + + if(m_partsNameToLinkMap.ContainsKey(name)) + { + lock(m_partsNameToLinkMap) + { + GetLinkNumber_lastname = name; + GetLinkNumber_lastnumber = m_partsNameToLinkMap[name]; + return GetLinkNumber_lastnumber; + } + } + } + + if(m_sittingAvatars.Count > 0) + { + int j = m_parts.Count + 1; + + ScenePresence[] avs = m_sittingAvatars.ToArray(); + for (int i = 0; i < avs.Length; i++, j++) + { + if (avs[i].Name == name) + { + GetLinkNumber_lastname = name; + GetLinkNumber_lastnumber = j; + return j; + } + } + } + + return -1; + } + + public void InvalidatePartsLinkMaps() + { + lock(m_partsNameToLinkMap) + { + m_partsNameToLinkMap.Clear(); + GetLinkNumber_lastname = String.Empty; + GetLinkNumber_lastnumber = -1; + } } #endregion diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b8ac089826..19bf53f0fd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -244,11 +244,6 @@ namespace OpenSim.Region.Framework.Scenes public uint TimeStampTerse; - // The following two are to hold the attachment data - // while an object is inworld - [XmlIgnore] - public byte AttachPoint = 0; - [XmlIgnore] public Quaternion AttachRotation = Quaternion.Identity; @@ -277,7 +272,11 @@ namespace OpenSim.Region.Framework.Scenes public scriptEvents AggregateScriptEvents; - public Vector3 AttachedPos; + public Vector3 AttachedPos + { + get; + set; + } // rotation locks on local X,Y and or Z axis bit flags // bits are as in llSetStatus defined in SceneObjectGroup.axisSelect enum @@ -407,6 +406,8 @@ namespace OpenSim.Region.Framework.Scenes private SOPVehicle m_vehicleParams = null; + private PhysicsInertiaData m_physicsInertia; + public KeyframeMotion KeyframeMotion { get; set; @@ -476,8 +477,8 @@ namespace OpenSim.Region.Framework.Scenes APIDActive = false; Flags = 0; CreateSelected = true; - TrimPermissions(); + AggregateInnerPerms(); } #endregion Constructors @@ -637,6 +638,8 @@ namespace OpenSim.Region.Framework.Scenes set { m_name = value; + if(ParentGroup != null) + ParentGroup.InvalidatePartsLinkMaps(); PhysicsActor pa = PhysActor; @@ -1063,7 +1066,7 @@ namespace OpenSim.Region.Framework.Scenes m_angularVelocity = value; PhysicsActor actor = PhysActor; - if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE) + if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this) { actor.RotationalVelocity = m_angularVelocity; } @@ -1089,6 +1092,12 @@ namespace OpenSim.Region.Framework.Scenes m_acceleration = Vector3.Zero; else m_acceleration = value; + + PhysicsActor actor = PhysActor; + if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this) + { + actor.Acceleration = m_acceleration; + } } } @@ -2013,7 +2022,7 @@ namespace OpenSim.Region.Framework.Scenes // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future public void SetVelocity(Vector3 pVel, bool localGlobalTF) { - if (ParentGroup == null || ParentGroup.IsDeleted) + if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) return; if (ParentGroup.IsAttachment) @@ -2040,7 +2049,7 @@ namespace OpenSim.Region.Framework.Scenes // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF) { - if (ParentGroup == null || ParentGroup.IsDeleted) + if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) return; if (ParentGroup.IsAttachment) @@ -2074,6 +2083,9 @@ namespace OpenSim.Region.Framework.Scenes /// true for the local frame, false for the global frame public void ApplyAngularImpulse(Vector3 impulsei, bool localGlobalTF) { + if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) + return; + Vector3 impulse = impulsei; if (localGlobalTF) @@ -2228,7 +2240,11 @@ namespace OpenSim.Region.Framework.Scenes dupe.LocalId = plocalID; // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. - dupe.LastOwnerID = OwnerID; + if(OwnerID != GroupID) + dupe.LastOwnerID = OwnerID; + else + dupe.LastOwnerID = LastOwnerID; // redundant ? + dupe.RezzerID = RezzerID; byte[] extraP = new byte[Shape.ExtraParams.Length]; @@ -2537,6 +2553,35 @@ namespace OpenSim.Region.Framework.Scenes return (uint)Flags | (uint)LocalFlags; } + // some of this lines need be moved to other place later + + // effective permitions considering only this part inventory contents perms + public uint AggregatedInnerOwnerPerms {get; private set; } + public uint AggregatedInnerGroupPerms {get; private set; } + public uint AggregatedInnerEveryonePerms {get; private set; } + private object InnerPermsLock = new object(); + + public void AggregateInnerPerms() + { + // assuming child prims permissions masks are irrelevant on a linkset + // root part is handle at SOG since its masks are the sog masks + const uint mask = (uint)PermissionMask.AllEffective; + + uint owner = mask; + uint group = mask; + uint everyone = mask; + + lock(InnerPermsLock) // do we really need this? + { + if(Inventory != null) + Inventory.AggregateInnerPerms(ref owner, ref group, ref everyone); + + AggregatedInnerOwnerPerms = owner & mask; + AggregatedInnerGroupPerms = group & mask; + AggregatedInnerEveryonePerms = everyone & mask; + } + } + public Vector3 GetGeometricCenter() { // this is not real geometric center but a average of positions relative to root prim acording to @@ -3340,25 +3385,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter /// public void SendFullUpdateToClient(IClientAPI remoteClient) { - SendFullUpdateToClient(remoteClient, OffsetPosition); - } - - /// - /// Sends a full update to the client - /// - /// - /// - public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos) - { - if (ParentGroup == null) - return; - - // Suppress full updates during attachment editing - // sl Does send them - // if (ParentGroup.IsSelected && ParentGroup.IsAttachment) - // return; - - if (ParentGroup.IsDeleted) + if (ParentGroup == null || ParentGroup.IsDeleted) return; if (ParentGroup.IsAttachment @@ -3516,6 +3543,18 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter Force = force; } + public PhysicsInertiaData PhysicsInertia + { + get + { + return m_physicsInertia; + } + set + { + m_physicsInertia = value; + } + } + public SOPVehicle VehicleParams { get @@ -3689,7 +3728,18 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter bool hasDimple; bool hasProfileCut; - PrimType primType = GetPrimType(); + if(Shape.SculptEntry) + { + if (Shape.SculptType != (byte)SculptType.Mesh) + return 1; // sculp + + //hack to detect new upload with faces data enconded on pbs + if ((Shape.ProfileCurve & 0xf0) != (byte)HollowShape.Triangle) + // old broken upload TODO + return 8; + } + + PrimType primType = GetPrimType(true); HasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut); switch (primType) @@ -3733,13 +3783,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (hasProfileCut) ret += 2; if (hasHollow) ret += 1; break; - case PrimType.SCULPT: - // Special mesh handling - if (Shape.SculptType == (byte)SculptType.Mesh) - ret = 8; // if it's a mesh then max 8 faces - else - ret = 1; // if it's a sculpt then max 1 face - break; } return ret; @@ -3750,9 +3793,9 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter /// /// /// - public PrimType GetPrimType() + public PrimType GetPrimType(bool ignoreSculpt = false) { - if (Shape.SculptEntry) + if (Shape.SculptEntry && !ignoreSculpt) return PrimType.SCULPT; if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square) @@ -4464,7 +4507,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter break; } - + AggregateInnerPerms(); SendFullUpdateToAllClients(); } } @@ -4481,6 +4524,8 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter EveryoneMask = source.EveryoneMask & BaseMask; NextOwnerMask = source.NextOwnerMask & BaseMask; + AggregateInnerPerms(); + if (OwnerMask != prevOwnerMask || GroupMask != prevGroupMask || EveryoneMask != prevEveryoneMask || @@ -4714,8 +4759,13 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (VolumeDetectActive) // change if not the default only pa.SetVolumeDetect(1); + + bool isroot = (m_localId == ParentGroup.RootPart.LocalId); - if (m_vehicleParams != null && m_localId == ParentGroup.RootPart.LocalId) + if(isroot && m_physicsInertia != null) + pa.SetInertiaData(m_physicsInertia); + + if (isroot && m_vehicleParams != null ) { m_vehicleParams.SetVehicle(pa); if(isPhysical && !isPhantom && m_vehicleParams.CameraDecoupled) @@ -5181,7 +5231,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter /// The scene the prim is being rezzed into public void ApplyPermissionsOnRez(InventoryItemBase item, bool userInventory, Scene scene) { - if ((OwnerID != item.Owner) || ((item.CurrentPermissions & SceneObjectGroup.SLAM) != 0) || ((item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)) + if ((OwnerID != item.Owner) || ((item.CurrentPermissions & (uint)PermissionMask.Slam) != 0) || ((item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)) { if (scene.Permissions.PropagatePermissions()) { @@ -5212,16 +5262,13 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (OwnerID != item.Owner) { - //LogPermissions("Before ApplyNextOwnerPermissions"); + if(OwnerID != GroupID) + LastOwnerID = OwnerID; + OwnerID = item.Owner; + Inventory.ChangeInventoryOwner(item.Owner); if (scene.Permissions.PropagatePermissions()) ApplyNextOwnerPermissions(); - - //LogPermissions("After ApplyNextOwnerPermissions"); - - LastOwnerID = OwnerID; - OwnerID = item.Owner; - Inventory.ChangeInventoryOwner(item.Owner); } } @@ -5245,6 +5292,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter GroupMask = 0; // Giving an object zaps group permissions Inventory.ApplyNextOwnerPermissions(); + AggregateInnerPerms(); } public void UpdateLookAt() @@ -5306,6 +5354,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter item.OwnerChanged = false; Inventory.UpdateInventoryItem(item, false, false); } + AggregateInnerPerms(); } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 6557003a12..b53c355333 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -360,7 +360,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}", // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); - if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) + if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item, m_part)) { StoreScriptError(item.ItemID, "no permission"); return false; @@ -807,6 +807,7 @@ namespace OpenSim.Region.Framework.Scenes else m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + m_part.AggregateInnerPerms(); m_inventorySerial++; //m_inventorySerial += 2; HasInventoryChanged = true; @@ -829,7 +830,7 @@ namespace OpenSim.Region.Framework.Scenes // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); } m_items.LockItemsForWrite(false); - + m_part.AggregateInnerPerms(); m_inventorySerial++; } @@ -943,8 +944,7 @@ namespace OpenSim.Region.Framework.Scenes group.SetGroup(m_part.GroupID, null); - // TODO: Remove magic number badness - if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number + if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) { if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) { @@ -964,10 +964,10 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in partList) { - // TODO: Remove magic number badness - if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number + if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) { - part.LastOwnerID = part.OwnerID; + if(part.GroupID != part.OwnerID) + part.LastOwnerID = part.OwnerID; part.OwnerID = item.OwnerID; part.Inventory.ChangeInventoryOwner(item.OwnerID); } @@ -981,6 +981,7 @@ namespace OpenSim.Region.Framework.Scenes } // old code end rootPart.TrimPermissions(); + group.AggregateDeepPerms(); } return true; @@ -1022,16 +1023,20 @@ namespace OpenSim.Region.Framework.Scenes item.AssetID = m_items[item.ItemID].AssetID; m_items[item.ItemID] = item; + m_inventorySerial++; if (fireScriptEvents) m_part.TriggerScriptChangedEvent(Changed.INVENTORY); if (considerChanged) { + m_part.AggregateInnerPerms(); + m_part.ParentGroup.AggregatePerms(); HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; } m_items.LockItemsForWrite(false); + return true; } else @@ -1068,6 +1073,10 @@ namespace OpenSim.Region.Framework.Scenes m_items.LockItemsForWrite(true); m_items.Remove(itemID); m_items.LockItemsForWrite(false); + + m_part.AggregateInnerPerms(); + m_part.ParentGroup.AggregatePerms(); + m_inventorySerial++; m_part.TriggerScriptChangedEvent(Changed.INVENTORY); @@ -1170,7 +1179,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (TaskInventoryItem item in m_items.Values) { UUID ownerID = item.OwnerID; - uint everyoneMask = 0; + uint everyoneMask = item.EveryonePermissions; uint baseMask = item.BasePermissions; uint ownerMask = item.CurrentPermissions; uint groupMask = item.GroupPermissions; @@ -1319,6 +1328,16 @@ namespace OpenSim.Region.Framework.Scenes } } + public void AggregateInnerPerms(ref uint owner, ref uint group, ref uint everyone) + { + foreach (TaskInventoryItem item in m_items.Values) + { + owner &= item.CurrentPermissions; + group &= item.GroupPermissions; + everyone &= item.EveryonePermissions; + } + } + public uint MaskEffectivePermissions() { uint mask=0x7fffffff; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9545c13d85..6d4cb52752 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1778,6 +1778,20 @@ namespace OpenSim.Region.Framework.Scenes private Dictionary m_knownChildRegionsSizeInfo = new Dictionary(); + public void AddNeighbourRegion(GridRegion region, string capsPath) + { + lock (m_knownChildRegions) + { + ulong regionHandle = region.RegionHandle; + m_knownChildRegions.Add(regionHandle,capsPath); + + spRegionSizeInfo sizeInfo = new spRegionSizeInfo(); + sizeInfo.sizeX = region.RegionSizeX; + sizeInfo.sizeY = region.RegionSizeY; + m_knownChildRegionsSizeInfo[regionHandle] = sizeInfo; + } + } + public void AddNeighbourRegionSizeInfo(GridRegion region) { lock (m_knownChildRegions) @@ -1826,6 +1840,12 @@ namespace OpenSim.Region.Framework.Scenes } } + public bool knowsNeighbourRegion(ulong regionHandle) + { + lock (m_knownChildRegions) + return m_knownChildRegions.ContainsKey(regionHandle); + } + public void DropOldNeighbours(List oldRegions) { foreach (ulong handle in oldRegions) @@ -2010,6 +2030,7 @@ namespace OpenSim.Region.Framework.Scenes return; } + m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); if(!haveGroupInformation && !IsChildAgent && !IsNPC) @@ -2029,11 +2050,6 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat("[CompleteMovement]: Missing COF for {0} is {1}", client.AgentId, COF); } - // Tell the client that we're totally ready - ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); - - m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); - if (!string.IsNullOrEmpty(m_callbackURI)) { // We cannot sleep here since this would hold up the inbound packet processing thread, as @@ -2054,6 +2070,7 @@ namespace OpenSim.Region.Framework.Scenes Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); m_callbackURI = null; + m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); } // else // { @@ -2062,19 +2079,58 @@ namespace OpenSim.Region.Framework.Scenes // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); // } - m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + + // Tell the client that we're totally ready + ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); + m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + + bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0; + + int delayctnr = Util.EnvironmentTickCount(); + + if (!IsChildAgent) + { + if( ParentPart != null && !IsNPC && (crossingFlags & 0x08) != 0) + { + +// SceneObjectPart root = ParentPart.ParentGroup.RootPart; +// if(root.LocalId != ParentPart.LocalId) +// ControllingClient.SendEntityTerseUpdateImmediate(root); +// ControllingClient.SendEntityTerseUpdateImmediate(ParentPart); + ParentPart.ParentGroup.SendFullUpdateToClient(ControllingClient); + } + + // verify baked textures and cache + bool cachedbaked = false; + + if (IsNPC) + cachedbaked = true; + else + { + if (m_scene.AvatarFactory != null && !isHGTP) + cachedbaked = m_scene.AvatarFactory.ValidateBakedTextureCache(this); + + // not sure we need this + if (!cachedbaked) + { + if (m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(UUID); + } + } + m_log.DebugFormat("[CompleteMovement] Baked check: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + } if(m_teleportFlags > 0) { gotCrossUpdate = false; // sanity check - Thread.Sleep(500); // let viewers catch us + if(Util.EnvironmentTickCountSubtract(delayctnr)< 500) + Thread.Sleep(500); // let viewers catch us } if(!gotCrossUpdate) RotateToLookAt(look); // HG - bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0; if(isHGTP) { // ControllingClient.SendNameReply(m_uuid, Firstname, Lastname); @@ -2101,28 +2157,11 @@ namespace OpenSim.Region.Framework.Scenes if (!IsChildAgent) { - // verify baked textures and cache - bool cachedbaked = false; - - if (IsNPC) - cachedbaked = true; - else - { - if (m_scene.AvatarFactory != null && !isHGTP) - cachedbaked = m_scene.AvatarFactory.ValidateBakedTextureCache(this); - - // not sure we need this - if (!cachedbaked) - { - if (m_scene.AvatarFactory != null) - m_scene.AvatarFactory.QueueAppearanceSave(UUID); - } - } - List allpresences = m_scene.GetScenePresences(); // send avatar object to all presences including us, so they cross it into region // then hide if necessary + SendInitialAvatarDataToAllAgents(allpresences); // send this look @@ -2230,13 +2269,18 @@ namespace OpenSim.Region.Framework.Scenes m_lastChildAgentUpdateDrawDistance = DrawDistance; m_lastChildAgentUpdatePosition = AbsolutePosition; m_childUpdatesBusy = false; // allow them + + } m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + + // send the rest of the world if (m_teleportFlags > 0 && !IsNPC || m_currentParcelHide) SendInitialDataToMe(); + // priority uses avatar position only // m_reprioritizationLastPosition = AbsolutePosition; @@ -3110,6 +3154,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 standPos = sitPartWorldPosition + adjustmentForSitPose; m_pos = standPos; + } // We need to wait until we have calculated proper stand positions before sitting up the physical @@ -3124,6 +3169,7 @@ namespace OpenSim.Region.Framework.Scenes part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); SendAvatarDataToAllAgents(); + m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on } // reset to default sitAnimation @@ -3256,6 +3302,7 @@ namespace OpenSim.Region.Framework.Scenes // Moved here to avoid a race with default sit anim // The script event needs to be raised after the default sit anim is set. part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); + m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on } } @@ -3405,6 +3452,7 @@ namespace OpenSim.Region.Framework.Scenes Animator.SetMovementAnimations("SIT"); part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); + m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on } public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) @@ -3968,7 +4016,7 @@ namespace OpenSim.Region.Framework.Scenes int count = 0; foreach (ScenePresence p in presences) { - p.ControllingClient.SendAvatarDataImmediate(this); + p.ControllingClient.SendEntityFullUpdateImmediate(this); if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod) // either just kill the object // p.ControllingClient.SendKillObject(new List {LocalId}); @@ -3981,7 +4029,7 @@ namespace OpenSim.Region.Framework.Scenes public void SendInitialAvatarDataToAgent(ScenePresence p) { - p.ControllingClient.SendAvatarDataImmediate(this); + p.ControllingClient.SendEntityFullUpdateImmediate(this); if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod) // either just kill the object // p.ControllingClient.SendKillObject(new List {LocalId}); @@ -3998,12 +4046,12 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && !avatar.IsViewerUIGod) return; - avatar.ControllingClient.SendAvatarDataImmediate(this); + avatar.ControllingClient.SendEntityFullUpdateImmediate(this); } public void SendAvatarDataToAgentNF(ScenePresence avatar) { - avatar.ControllingClient.SendAvatarDataImmediate(this); + avatar.ControllingClient.SendEntityFullUpdateImmediate(this); } /// @@ -6440,7 +6488,7 @@ namespace OpenSim.Region.Framework.Scenes if (check) { // check is relative to current parcel only - if (currentParcelUUID == null || oldhide == currentParcelHide) + if (oldhide == currentParcelHide) return; allpresences = m_scene.GetScenePresences(); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index b8d210cac6..87d1ace1b4 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -114,7 +114,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization // Script state may, or may not, exist. Not having any, is NOT // ever a problem. sceneObject.LoadScriptState(reader); - + sceneObject.AggregateDeepPerms(); return sceneObject; } @@ -278,7 +278,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization // Script state may, or may not, exist. Not having any, is NOT // ever a problem. sceneObject.LoadScriptState(doc); - + sceneObject.AggregatePerms(); return sceneObject; } catch (Exception e) @@ -453,9 +453,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("Torque", ProcessTorque); m_SOPXmlProcessors.Add("VolumeDetectActive", ProcessVolumeDetectActive); - m_SOPXmlProcessors.Add("Vehicle", ProcessVehicle); + m_SOPXmlProcessors.Add("PhysicsInertia", ProcessPhysicsInertia); + m_SOPXmlProcessors.Add("RotationAxisLocks", ProcessRotationAxisLocks); m_SOPXmlProcessors.Add("PhysicsShapeType", ProcessPhysicsShapeType); m_SOPXmlProcessors.Add("Density", ProcessDensity); @@ -781,6 +782,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } } + private static void ProcessPhysicsInertia(SceneObjectPart obj, XmlReader reader) + { + PhysicsInertiaData pdata = PhysicsInertiaData.FromXml2(reader); + + if (pdata == null) + { + obj.PhysicsInertia = null; + m_log.DebugFormat( + "[SceneObjectSerializer]: Parsing PhysicsInertiaData for object part {0} {1} encountered errors. Please see earlier log entries.", + obj.Name, obj.UUID); + } + else + { + obj.PhysicsInertia = pdata; + } + } + private static void ProcessShape(SceneObjectPart obj, XmlReader reader) { List errorNodeNames; @@ -1498,6 +1516,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (sop.VehicleParams != null) sop.VehicleParams.ToXml2(writer); + if (sop.PhysicsInertia != null) + sop.PhysicsInertia.ToXml2(writer); + if(sop.RotationAxisLocks != 0) writer.WriteElementString("RotationAxisLocks", sop.RotationAxisLocks.ToString().ToLower()); writer.WriteElementString("PhysicsShapeType", sop.PhysicsShapeType.ToString().ToLower()); @@ -1739,6 +1760,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization reader.ReadEndElement(); // SceneObjectPart + obj.AggregateInnerPerms(); // m_log.DebugFormat("[SceneObjectSerializer]: parsed SOP {0} {1}", obj.Name, obj.UUID); return obj; } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs index 01bc491566..0f022dd58f 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs @@ -70,6 +70,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization //obj.RegenerateFullIDs(); scene.AddNewSceneObject(obj, true); + obj.AggregateDeepPerms(); } } else diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs index 56723bfd95..4d2eb3fe89 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs @@ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectGroup dupeSo = scene.SceneGraph.DuplicateObject( - part1.LocalId, new Vector3(10, 0, 0), 0, ownerId, UUID.Zero, Quaternion.Identity); + part1.LocalId, new Vector3(10, 0, 0), ownerId, UUID.Zero, Quaternion.Identity, false); Assert.That(dupeSo.Parts.Length, Is.EqualTo(2)); SceneObjectPart dupePart1 = dupeSo.GetLinkNumPart(1); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs index e1e973cdd3..abf8c488c5 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs @@ -157,29 +157,28 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Cross sceneA.SceneGraph.UpdatePrimGroupPosition( - so1.LocalId, new Vector3(so1StartPos.X, so1StartPos.Y - 20, so1StartPos.Z), userId); + so1.LocalId, new Vector3(so1StartPos.X, so1StartPos.Y - 20, so1StartPos.Z), sp1SceneA.ControllingClient); // crossing is async Thread.Sleep(500); SceneObjectGroup so1PostCross; - { - ScenePresence sp1SceneAPostCross = sceneA.GetScenePresence(userId); - Assert.IsTrue(sp1SceneAPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly false"); + ScenePresence sp1SceneAPostCross = sceneA.GetScenePresence(userId); + Assert.IsTrue(sp1SceneAPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly false"); - ScenePresence sp1SceneBPostCross = sceneB.GetScenePresence(userId); - TestClient sceneBTc = ((TestClient)sp1SceneBPostCross.ControllingClient); - sceneBTc.CompleteMovement(); + ScenePresence sp1SceneBPostCross = sceneB.GetScenePresence(userId); + TestClient sceneBTc = ((TestClient)sp1SceneBPostCross.ControllingClient); + sceneBTc.CompleteMovement(); - Assert.IsFalse(sp1SceneBPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true"); - Assert.IsTrue(sp1SceneBPostCross.IsSatOnObject); + Assert.IsFalse(sp1SceneBPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true"); + Assert.IsTrue(sp1SceneBPostCross.IsSatOnObject); + + Assert.IsNull(sceneA.GetSceneObjectGroup(so1Id), "uck"); + so1PostCross = sceneB.GetSceneObjectGroup(so1Id); + Assert.NotNull(so1PostCross); + Assert.AreEqual(1, so1PostCross.GetSittingAvatarsCount()); - Assert.IsNull(sceneA.GetSceneObjectGroup(so1Id), "uck"); - so1PostCross = sceneB.GetSceneObjectGroup(so1Id); - Assert.NotNull(so1PostCross); - Assert.AreEqual(1, so1PostCross.GetSittingAvatarsCount()); - } Vector3 so1PostCrossPos = so1PostCross.AbsolutePosition; @@ -187,7 +186,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Recross sceneB.SceneGraph.UpdatePrimGroupPosition( - so1PostCross.LocalId, new Vector3(so1PostCrossPos.X, so1PostCrossPos.Y + 20, so1PostCrossPos.Z), userId); + so1PostCross.LocalId, new Vector3(so1PostCrossPos.X, so1PostCrossPos.Y + 20, so1PostCrossPos.Z), sp1SceneBPostCross.ControllingClient); // crossing is async Thread.Sleep(500); @@ -255,13 +254,19 @@ namespace OpenSim.Region.Framework.Scenes.Tests lmmA.EventManagerOnNoLandDataFromStorage(); lmmB.EventManagerOnNoLandDataFromStorage(); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + TestClient tc = new TestClient(acd, sceneA); + List destinationTestClients = new List(); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); + ScenePresence sp1SceneA = SceneHelpers.AddScenePresence(sceneA, tc, acd); + SceneObjectGroup so1 = SceneHelpers.AddSceneObject(sceneA, 1, userId, "", sceneObjectIdTail); UUID so1Id = so1.UUID; so1.AbsolutePosition = new Vector3(128, 10, 20); // Cross with a negative value. We must make this call rather than setting AbsolutePosition directly // because only this will execute permission checks in the source region. - sceneA.SceneGraph.UpdatePrimGroupPosition(so1.LocalId, new Vector3(128, -10, 20), userId); + sceneA.SceneGraph.UpdatePrimGroupPosition(so1.LocalId, new Vector3(128, -10, 20), sp1SceneA.ControllingClient); // crossing is async Thread.Sleep(500); diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 83b534b0ca..d39c224129 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1097,7 +1097,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void SendAvatarDataImmediate(ISceneEntity avatar) + public void SendEntityFullUpdateImmediate(ISceneEntity ent) + { + + } + + public void SendEntityTerseUpdateImmediate(ISceneEntity ent) { } diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index ed27385efb..92b583136c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -134,11 +134,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments private int llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint) { SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host); - if (hostPart == null) return 0; - if (hostPart.ParentGroup.IsAttachment) + SceneObjectGroup hostgroup = hostPart.ParentGroup; + + if (hostgroup== null || hostgroup.IsAttachment) return 0; IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface(); @@ -156,32 +157,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments if (!m_scene.TryGetScenePresence(item.PermsGranter, out target)) return 0; - if (target.UUID != hostPart.ParentGroup.OwnerID) + if (target.UUID != hostgroup.OwnerID) { - uint effectivePerms = hostPart.ParentGroup.GetEffectivePermissions(); + uint effectivePerms = hostgroup.EffectiveOwnerPerms; if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) return 0; - hostPart.ParentGroup.SetOwnerId(target.UUID); - hostPart.ParentGroup.SetRootPartOwner(hostPart.ParentGroup.RootPart, target.UUID, target.ControllingClient.ActiveGroupId); + hostgroup.SetOwner(target.UUID, target.ControllingClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { - foreach (SceneObjectPart child in hostPart.ParentGroup.Parts) + foreach (SceneObjectPart child in hostgroup.Parts) { child.Inventory.ChangeInventoryOwner(target.UUID); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } + hostgroup.AggregatePerms(); } - hostPart.ParentGroup.RootPart.ObjectSaleType = 0; - hostPart.ParentGroup.RootPart.SalePrice = 10; + hostgroup.RootPart.ObjectSaleType = 0; + hostgroup.RootPart.SalePrice = 10; - hostPart.ParentGroup.HasGroupChanged = true; - hostPart.ParentGroup.RootPart.SendPropertiesToClient(target.ControllingClient); - hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); + hostgroup.HasGroupChanged = true; + hostgroup.RootPart.SendPropertiesToClient(target.ControllingClient); + hostgroup.RootPart.ScheduleFullUpdate(); } return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, false, true) ? 1 : 0; diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/EtcdMonitoringModule.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/EtcdMonitoringModule.cs new file mode 100644 index 0000000000..921bbfbbee --- /dev/null +++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/EtcdMonitoringModule.cs @@ -0,0 +1,195 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using netcd; +using netcd.Serialization; +using netcd.Advanced; +using netcd.Advanced.Requests; + +namespace OpenSim.Region.OptionalModules.Framework.Monitoring +{ + /// + /// Allows to store monitoring data in etcd, a high availability + /// name-value store. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EtcdMonitoringModule")] + public class EtcdMonitoringModule : INonSharedRegionModule, IEtcdModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected Scene m_scene; + protected IEtcdClient m_client; + protected bool m_enabled = false; + protected string m_etcdBasePath = String.Empty; + protected bool m_appendRegionID = true; + + public string Name + { + get { return "EtcdMonitoringModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource source) + { + if (source.Configs["Etcd"] == null) + return; + + IConfig etcdConfig = source.Configs["Etcd"]; + + string etcdUrls = etcdConfig.GetString("EtcdUrls", String.Empty); + if (etcdUrls == String.Empty) + return; + + m_etcdBasePath = etcdConfig.GetString("BasePath", m_etcdBasePath); + m_appendRegionID = etcdConfig.GetBoolean("AppendRegionID", m_appendRegionID); + + if (!m_etcdBasePath.EndsWith("/")) + m_etcdBasePath += "/"; + + try + { + string[] endpoints = etcdUrls.Split(new char[] {','}); + List uris = new List(); + foreach (string endpoint in endpoints) + uris.Add(new Uri(endpoint.Trim())); + + m_client = new EtcdClient(uris.ToArray(), new DefaultSerializer(), new DefaultSerializer()); + } + catch (Exception e) + { + m_log.DebugFormat("[ETCD]: Error initializing connection: " + e.ToString()); + return; + } + + m_log.DebugFormat("[ETCD]: Etcd module configured"); + m_enabled = true; + } + + public void Close() + { + //m_client = null; + m_scene = null; + } + + public void AddRegion(Scene scene) + { + m_scene = scene; + + if (m_enabled) + { + if (m_appendRegionID) + m_etcdBasePath += m_scene.RegionInfo.RegionID.ToString() + "/"; + + m_log.DebugFormat("[ETCD]: Using base path {0} for all keys", m_etcdBasePath); + + try + { + m_client.Advanced.CreateDirectory(new CreateDirectoryRequest() {Key = m_etcdBasePath}); + } + catch (Exception e) + { + m_log.ErrorFormat("Exception trying to create base path {0}: " + e.ToString(), m_etcdBasePath); + } + + scene.RegisterModuleInterface(this); + } + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + } + + public bool Store(string k, string v) + { + return Store(k, v, 0); + } + + public bool Store(string k, string v, int ttl) + { + Response resp = m_client.Advanced.SetKey(new SetKeyRequest() { Key = m_etcdBasePath + k, Value = v, TimeToLive = ttl }); + + if (resp == null) + return false; + + if (resp.ErrorCode.HasValue) + { + m_log.DebugFormat("[ETCD]: Error {0} ({1}) storing {2} => {3}", resp.Cause, (int)resp.ErrorCode, m_etcdBasePath + k, v); + + return false; + } + + return true; + } + + public string Get(string k) + { + Response resp = m_client.Advanced.GetKey(new GetKeyRequest() { Key = m_etcdBasePath + k }); + + if (resp == null) + return String.Empty; + + if (resp.ErrorCode.HasValue) + { + m_log.DebugFormat("[ETCD]: Error {0} ({1}) getting {2}", resp.Cause, (int)resp.ErrorCode, m_etcdBasePath + k); + + return String.Empty; + } + + return resp.Node.Value; + } + + public void Delete(string k) + { + m_client.Advanced.DeleteKey(new DeleteKeyRequest() { Key = m_etcdBasePath + k }); + } + + public void Watch(string k, Action callback) + { + m_client.Advanced.WatchKey(new WatchKeyRequest() { Key = m_etcdBasePath + k, Callback = (x) => { callback(x.Node.Value); } }); + } + } +} diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs index 52fa908d4a..e8cb052263 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs @@ -329,7 +329,7 @@ namespace OpenSim.Region.OptionalModules.Materials AssetBase matAsset = m_scene.AssetService.Get(id.ToString()); if (matAsset == null || matAsset.Data == null || matAsset.Data.Length == 0 ) { - m_log.WarnFormat("[Materials]: Prim \"{0}\" ({1}) contains unknown material ID {2}", part.Name, part.UUID, id); + //m_log.WarnFormat("[Materials]: Prim \"{0}\" ({1}) contains unknown material ID {2}", part.Name, part.UUID, id); return; } diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs index 9c0fa7577d..61b6d682e6 100644 --- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs +++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs @@ -52,6 +52,7 @@ namespace OpenSim.Region.OptionalModules private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private bool m_enabled; + private Scene m_scene; public string Name { get { return "PrimLimitsModule"; } } public Type ReplaceableInterface { get { return null; } } @@ -77,11 +78,12 @@ namespace OpenSim.Region.OptionalModules public void AddRegion(Scene scene) { if (!m_enabled) - { return; - } + + m_scene = scene; scene.Permissions.OnRezObject += CanRezObject; scene.Permissions.OnObjectEntry += CanObjectEnter; + scene.Permissions.OnObjectEnterWithScripts += CanObjectEnterWithScripts; scene.Permissions.OnDuplicateObject += CanDuplicateObject; m_log.DebugFormat("[PRIM LIMITS]: Region {0} added", scene.RegionInfo.RegionName); @@ -89,14 +91,13 @@ namespace OpenSim.Region.OptionalModules public void RemoveRegion(Scene scene) { - if (m_enabled) - { + if (!m_enabled) return; - } - scene.Permissions.OnRezObject -= CanRezObject; - scene.Permissions.OnObjectEntry -= CanObjectEnter; - scene.Permissions.OnDuplicateObject -= CanDuplicateObject; + m_scene.Permissions.OnRezObject -= CanRezObject; + m_scene.Permissions.OnObjectEntry -= CanObjectEnter; + scene.Permissions.OnObjectEnterWithScripts -= CanObjectEnterWithScripts; + m_scene.Permissions.OnDuplicateObject -= CanDuplicateObject; } public void RegionLoaded(Scene scene) @@ -104,11 +105,12 @@ namespace OpenSim.Region.OptionalModules m_dialogModule = scene.RequestModuleInterface(); } - private bool CanRezObject(int objectCount, UUID ownerID, Vector3 objectPosition, Scene scene) + private bool CanRezObject(int objectCount, UUID ownerID, Vector3 objectPosition) { - ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); + + ILandObject lo = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); - string response = DoCommonChecks(objectCount, ownerID, lo, scene); + string response = DoCommonChecks(objectCount, ownerID, lo); if (response != null) { @@ -119,88 +121,99 @@ namespace OpenSim.Region.OptionalModules } //OnDuplicateObject - private bool CanDuplicateObject(int objectCount, UUID objectID, UUID ownerID, Scene scene, Vector3 objectPosition) + private bool CanDuplicateObject(SceneObjectGroup sog, ScenePresence sp) { - ILandObject lo = scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); + Vector3 objectPosition = sog.AbsolutePosition; + ILandObject lo = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); - string response = DoCommonChecks(objectCount, ownerID, lo, scene); + string response = DoCommonChecks(sog.PrimCount, sp.UUID, lo); if (response != null) { - m_dialogModule.SendAlertToUser(ownerID, response); + m_dialogModule.SendAlertToUser(sp.UUID, response); return false; } return true; } - private bool CanObjectEnter(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene) + private bool CanObjectEnter(SceneObjectGroup sog, bool enteringRegion, Vector3 newPoint) { - if (newPoint.X < -1f || newPoint.X > (scene.RegionInfo.RegionSizeX + 1) || - newPoint.Y < -1f || newPoint.Y > (scene.RegionInfo.RegionSizeY) ) + float newX = newPoint.X; + float newY = newPoint.Y; + if (newX < -1.0f || newX > (m_scene.RegionInfo.RegionSizeX + 1.0f) || + newY < -1.0f || newY > (m_scene.RegionInfo.RegionSizeY + 1.0f) ) return true; - SceneObjectPart obj = scene.GetSceneObjectPart(objectID); - - if (obj == null) + if (sog == null) return false; - // Prim counts are determined by the location of the root prim. if we're - // moving a child prim, just let it pass - if (!obj.IsRoot) - { - return true; - } - - ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); + ILandObject newParcel = m_scene.LandChannel.GetLandObject(newX, newY); if (newParcel == null) return true; - Vector3 oldPoint = obj.GroupPosition; - ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); - - // The prim hasn't crossed a region boundry so we don't need to worry - // about prim counts here - if(oldParcel != null && oldParcel.Equals(newParcel)) + if(!enteringRegion) { - return true; + Vector3 oldPoint = sog.AbsolutePosition; + ILandObject oldParcel = m_scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); + if(oldParcel != null && oldParcel.Equals(newParcel)) + return true; } - int objectCount = obj.ParentGroup.PrimCount; - int usedPrims = newParcel.PrimCounts.Total; - int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount(); + int objectCount = sog.PrimCount; // TODO: Add Special Case here for temporary prims - string response = DoCommonChecks(objectCount, obj.OwnerID, newParcel, scene); + string response = DoCommonChecks(objectCount, sog.OwnerID, newParcel); if (response != null) { - m_dialogModule.SendAlertToUser(obj.OwnerID, response); + if(m_dialogModule != null) + m_dialogModule.SendAlertToUser(sog.OwnerID, response); return false; } return true; } - private string DoCommonChecks(int objectCount, UUID ownerID, ILandObject lo, Scene scene) + private bool CanObjectEnterWithScripts(SceneObjectGroup sog, ILandObject newParcel) + { + if (sog == null) + return false; + + if (newParcel == null) + return true; + + int objectCount = sog.PrimCount; + + // TODO: Add Special Case here for temporary prims + + string response = DoCommonChecks(objectCount, sog.OwnerID, newParcel); + + if (response != null) + return false; + + return true; + } + + private string DoCommonChecks(int objectCount, UUID ownerID, ILandObject lo) { string response = null; int OwnedParcelsCapacity = lo.GetSimulatorMaxPrimCount(); if ((objectCount + lo.PrimCounts.Total) > OwnedParcelsCapacity) { - response = "Unable to rez object because the parcel is too full"; + response = "Unable to rez object because the parcel is full"; } else { - int maxPrimsPerUser = scene.RegionInfo.MaxPrimsPerUser; + int maxPrimsPerUser = m_scene.RegionInfo.MaxPrimsPerUser; if (maxPrimsPerUser >= 0) { // per-user prim limit is set if (ownerID != lo.LandData.OwnerID || lo.LandData.IsGroupOwned) { // caller is not the sole Parcel owner - EstateSettings estateSettings = scene.RegionInfo.EstateSettings; + EstateSettings estateSettings = m_scene.RegionInfo.EstateSettings; if (ownerID != estateSettings.EstateOwner) { // caller is NOT the Estate owner diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index a9fdb667c4..6cf0092266 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -665,7 +665,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore taskItem.AssetID = asset.FullID; host.Inventory.AddInventoryItem(taskItem, false); - + host.ParentGroup.AggregatePerms(); m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 6a7c735fd6..151a202e49 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -813,7 +813,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public void SendAvatarDataImmediate(ISceneEntity avatar) + public void SendEntityFullUpdateImmediate(ISceneEntity avatar) + { + } + + public void SendEntityTerseUpdateImmediate(ISceneEntity ent) { } diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index e22c6eae9a..b26fa3298d 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -523,9 +523,9 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator rootPart.AddFlag(PrimFlags.Phantom); - m_scene.AddNewSceneObject(sceneObject, true); sceneObject.SetGroup(groupID, null); - + m_scene.AddNewSceneObject(sceneObject, true); + sceneObject.AggregatePerms(); return sceneObject; } diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs index 33f033759b..2fa98b579e 100644 --- a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs +++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs @@ -256,6 +256,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase /// public string SOPName; + public virtual void CrossingStart() { } public abstract void CrossingFailure(); public abstract void link(PhysicsActor obj); @@ -462,6 +463,23 @@ namespace OpenSim.Region.PhysicsModules.SharedBase public abstract bool SubscribedEvents(); public virtual void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { } + public virtual void AddVDTCCollisionEvent(uint CollidedWith, ContactPoint contact) { } + + public virtual PhysicsInertiaData GetInertiaData() + { + PhysicsInertiaData data = new PhysicsInertiaData(); + data.TotalMass = this.Mass; + data.CenterOfMass = CenterOfMass - Position; + data.Inertia = Vector3.Zero; + data.InertiaRotation = Vector4.Zero; + return data; + } + + public virtual void SetInertiaData(PhysicsInertiaData inertia) + { + } + + public virtual float SimulationSuspended { get; set; } // Warning in a parent part it returns itself, not null public virtual PhysicsActor ParentActor { get { return this; } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs index a2fbf41ec6..9bf71f7687 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs @@ -85,7 +85,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private Vector3 m_lastposition; private Vector3 m_rotationalVelocity; private Vector3 _size; - private Vector3 _acceleration; + private Vector3 m_acceleration; private IntPtr Amotor; internal Vector3 m_force; @@ -109,8 +109,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde private float m_waterHeight; private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. - private int body_autodisable_frames; - public int bodydisablecontrol = 0; + private int m_body_autodisable_frames; + public int m_bodydisablecontrol = 0; private float m_gravmod = 1.0f; // Default we're a Geometry @@ -182,18 +182,21 @@ namespace OpenSim.Region.PhysicsModule.ubOde private float m_streamCost; public d.Mass primdMass; // prim inertia information on it's own referencial + private PhysicsInertiaData m_InertiaOverride; float primMass; // prim own mass float primVolume; // prim own volume; - float _mass; // object mass acording to case + float m_mass; // object mass acording to case public int givefakepos; private Vector3 fakepos; public int givefakeori; private Quaternion fakeori; + private PhysicsInertiaData m_fakeInertiaOverride; private int m_eventsubscription; private int m_cureventsubscription; private CollisionEventUpdate CollisionEventsThisFrame = null; + private CollisionEventUpdate CollisionVDTCEventsThisFrame = null; private bool SentEmptyCollisionsEvent; public volatile bool childPrim; @@ -465,6 +468,103 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } + public override PhysicsInertiaData GetInertiaData() + { + PhysicsInertiaData inertia; + if(childPrim) + { + if(_parent != null) + return _parent.GetInertiaData(); + else + { + inertia = new PhysicsInertiaData(); + inertia.TotalMass = -1; + return inertia; + } + } + + inertia = new PhysicsInertiaData(); + + // double buffering + if(m_fakeInertiaOverride != null) + { + d.Mass objdmass = new d.Mass(); + objdmass.I.M00 = m_fakeInertiaOverride.Inertia.X; + objdmass.I.M11 = m_fakeInertiaOverride.Inertia.Y; + objdmass.I.M22 = m_fakeInertiaOverride.Inertia.Z; + + objdmass.mass = m_fakeInertiaOverride.TotalMass; + + if(Math.Abs(m_fakeInertiaOverride.InertiaRotation.W) < 0.999) + { + d.Matrix3 inertiarotmat = new d.Matrix3(); + d.Quaternion inertiarot = new d.Quaternion(); + + inertiarot.X = m_fakeInertiaOverride.InertiaRotation.X; + inertiarot.Y = m_fakeInertiaOverride.InertiaRotation.Y; + inertiarot.Z = m_fakeInertiaOverride.InertiaRotation.Z; + inertiarot.W = m_fakeInertiaOverride.InertiaRotation.W; + d.RfromQ(out inertiarotmat, ref inertiarot); + d.MassRotate(ref objdmass, ref inertiarotmat); + } + + inertia.TotalMass = m_fakeInertiaOverride.TotalMass; + inertia.CenterOfMass = m_fakeInertiaOverride.CenterOfMass; + inertia.Inertia.X = objdmass.I.M00; + inertia.Inertia.Y = objdmass.I.M11; + inertia.Inertia.Z = objdmass.I.M22; + inertia.InertiaRotation.X = objdmass.I.M01; + inertia.InertiaRotation.Y = objdmass.I.M02; + inertia.InertiaRotation.Z = objdmass.I.M12; + return inertia; + } + + inertia.TotalMass = m_mass; + + if(Body == IntPtr.Zero || prim_geom == IntPtr.Zero) + { + inertia.CenterOfMass = Vector3.Zero; + inertia.Inertia = Vector3.Zero; + inertia.InertiaRotation = Vector4.Zero; + return inertia; + } + + d.Vector3 dtmp; + d.Mass m = new d.Mass(); + lock(_parent_scene.OdeLock) + { + d.AllocateODEDataForThread(0); + dtmp = d.GeomGetOffsetPosition(prim_geom); + d.BodyGetMass(Body, out m); + } + + Vector3 cm = new Vector3(-dtmp.X, -dtmp.Y, -dtmp.Z); + inertia.CenterOfMass = cm; + inertia.Inertia = new Vector3(m.I.M00, m.I.M11, m.I.M22); + inertia.InertiaRotation = new Vector4(m.I.M01, m.I.M02 , m.I.M12, 0); + + return inertia; + } + + public override void SetInertiaData(PhysicsInertiaData inertia) + { + if(childPrim) + { + if(_parent != null) + _parent.SetInertiaData(inertia); + return; + } + + if(inertia.TotalMass > 0) + m_fakeInertiaOverride = new PhysicsInertiaData(inertia); + else + m_fakeInertiaOverride = null; + + if (inertia.TotalMass > _parent_scene.maximumMassObject) + inertia.TotalMass = _parent_scene.maximumMassObject; + AddChange(changes.SetInertia,(object)m_fakeInertiaOverride); + } + public override Vector3 CenterOfMass { get @@ -569,7 +669,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (value.IsFinite()) { - AddChange(changes.Velocity, value); + if(m_outbounds) + _velocity = value; + else + AddChange(changes.Velocity, value); } else { @@ -642,8 +745,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override Vector3 Acceleration { - get { return _acceleration; } - set { } + get { return m_acceleration; } + set + { + if(m_outbounds) + m_acceleration = value; + } } public override Vector3 RotationalVelocity @@ -663,7 +770,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (value.IsFinite()) { - AddChange(changes.AngVelocity, value); + if(m_outbounds) + m_rotationalVelocity = value; + else + AddChange(changes.AngVelocity, value); } else { @@ -837,7 +947,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } public void SetAcceleration(Vector3 accel) { - _acceleration = accel; + m_acceleration = accel; } public override void AddForce(Vector3 force, bool pushforce) @@ -873,31 +983,68 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override void CrossingFailure() { - if (m_outbounds) + lock(_parent_scene.OdeLock) { - _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); - _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); - _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); + if (m_outbounds) + { + _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); + _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); + _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); + + m_lastposition = _position; + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; + + d.AllocateODEDataForThread(0); + + m_lastVelocity = _velocity; + if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) + m_vehicle.Stop(); + + if(Body != IntPtr.Zero) + d.BodySetLinearVel(Body, 0, 0, 0); // stop it + if (prim_geom != IntPtr.Zero) + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + + m_outbounds = false; + changeDisable(false); + base.RequestPhysicsterseUpdate(); + } + } + } + + public override void CrossingStart() + { + lock(_parent_scene.OdeLock) + { + if (m_outbounds || childPrim) + return; + + m_outbounds = true; m_lastposition = _position; - _velocity.X = 0; - _velocity.Y = 0; - _velocity.Z = 0; + m_lastorientation = _orientation; d.AllocateODEDataForThread(0); - - m_lastVelocity = _velocity; - if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) - m_vehicle.Stop(); - if(Body != IntPtr.Zero) - d.BodySetLinearVel(Body, 0, 0, 0); // stop it - if (prim_geom != IntPtr.Zero) - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + { + d.Vector3 dtmp = d.BodyGetAngularVel(Body); + m_rotationalVelocity.X = dtmp.X; + m_rotationalVelocity.Y = dtmp.Y; + m_rotationalVelocity.Z = dtmp.Z; - m_outbounds = false; - changeDisable(false); - base.RequestPhysicsterseUpdate(); + dtmp = d.BodyGetLinearVel(Body); + _velocity.X = dtmp.X; + _velocity.Y = dtmp.Y; + _velocity.Z = dtmp.Z; + + d.BodySetLinearVel(Body, 0, 0, 0); // stop it + d.BodySetAngularVel(Body, 0, 0, 0); + } + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + disableBodySoft(); // stop collisions + UnSubscribeEvents(); } } @@ -920,8 +1067,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde } set { + float old = m_density; m_density = value / 100f; - // for not prim mass is not updated since this implies full rebuild of body inertia TODO + // if(m_density != old) + // UpdatePrimBodyData(); } } public override float GravModifier @@ -989,11 +1138,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_cureventsubscription = 0; if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); + if (CollisionVDTCEventsThisFrame == null) + CollisionVDTCEventsThisFrame = new CollisionEventUpdate(); SentEmptyCollisionsEvent = false; } public override void UnSubscribeEvents() { + if (CollisionVDTCEventsThisFrame != null) + { + CollisionVDTCEventsThisFrame.Clear(); + CollisionVDTCEventsThisFrame = null; + } if (CollisionEventsThisFrame != null) { CollisionEventsThisFrame.Clear(); @@ -1012,22 +1168,51 @@ namespace OpenSim.Region.PhysicsModule.ubOde _parent_scene.AddCollisionEventReporting(this); } + public override void AddVDTCCollisionEvent(uint CollidedWith, ContactPoint contact) + { + if (CollisionVDTCEventsThisFrame == null) + CollisionVDTCEventsThisFrame = new CollisionEventUpdate(); + + CollisionVDTCEventsThisFrame.AddCollider(CollidedWith, contact); + _parent_scene.AddCollisionEventReporting(this); + } + internal void SleeperAddCollisionEvents() { - if (CollisionEventsThisFrame == null) - return; - if(CollisionEventsThisFrame.m_objCollisionList.Count == 0) - return; - foreach(KeyValuePair kvp in CollisionEventsThisFrame.m_objCollisionList) + if(CollisionEventsThisFrame != null && CollisionEventsThisFrame.m_objCollisionList.Count != 0) { - OdePrim other = _parent_scene.getPrim(kvp.Key); - if(other == null) - continue; - ContactPoint cp = kvp.Value; - cp.SurfaceNormal = - cp.SurfaceNormal; - cp.RelativeSpeed = -cp.RelativeSpeed; - other.AddCollisionEvent(ParentActor.LocalID,cp); + foreach(KeyValuePair kvp in CollisionEventsThisFrame.m_objCollisionList) + { + if(kvp.Key == 0) + continue; + OdePrim other = _parent_scene.getPrim(kvp.Key); + if(other == null) + continue; + ContactPoint cp = kvp.Value; + cp.SurfaceNormal = - cp.SurfaceNormal; + cp.RelativeSpeed = -cp.RelativeSpeed; + other.AddCollisionEvent(ParentActor.LocalID,cp); + } } + if(CollisionVDTCEventsThisFrame != null && CollisionVDTCEventsThisFrame.m_objCollisionList.Count != 0) + { + foreach(KeyValuePair kvp in CollisionVDTCEventsThisFrame.m_objCollisionList) + { + OdePrim other = _parent_scene.getPrim(kvp.Key); + if(other == null) + continue; + ContactPoint cp = kvp.Value; + cp.SurfaceNormal = - cp.SurfaceNormal; + cp.RelativeSpeed = -cp.RelativeSpeed; + other.AddCollisionEvent(ParentActor.LocalID,cp); + } + } + } + + internal void clearSleeperCollisions() + { + if(CollisionVDTCEventsThisFrame != null && CollisionVDTCEventsThisFrame.Count >0 ) + CollisionVDTCEventsThisFrame.Clear(); } public void SendCollisions(int timestep) @@ -1035,14 +1220,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_cureventsubscription < 50000) m_cureventsubscription += timestep; + + if (m_cureventsubscription < m_eventsubscription) + return; + if (CollisionEventsThisFrame == null) return; int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; - if (m_cureventsubscription < m_eventsubscription) - return; - if (!SentEmptyCollisionsEvent || ncolisions > 0) { base.SendCollisionUpdate(CollisionEventsThisFrame); @@ -1091,7 +1277,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_invTimeStep = 1f / m_timeStep; m_density = parent_scene.geomDefaultDensity; - body_autodisable_frames = parent_scene.bodyFramesAutoDisable; + m_body_autodisable_frames = parent_scene.bodyFramesAutoDisable; prim_geom = IntPtr.Zero; collide_geom = IntPtr.Zero; @@ -1714,26 +1900,29 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_log.Warn("[PHYSICS]: MakeBody root geom already had a body"); } + bool noInertiaOverride = (m_InertiaOverride == null); + + Body = d.BodyCreate(_parent_scene.world); + d.Matrix3 mymat = new d.Matrix3(); d.Quaternion myrot = new d.Quaternion(); d.Mass objdmass = new d.Mass { }; - Body = d.BodyCreate(_parent_scene.world); - - objdmass = primdMass; - - // rotate inertia myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; - d.RfromQ(out mymat, ref myrot); - d.MassRotate(ref objdmass, ref mymat); // set the body rotation d.BodySetRotation(Body, ref mymat); + if(noInertiaOverride) + { + objdmass = primdMass; + d.MassRotate(ref objdmass, ref mymat); + } + // recompute full object inertia if needed if (childrenPrim.Count > 0) { @@ -1756,27 +1945,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde continue; } - tmpdmass = prm.primdMass; - - // apply prim current rotation to inertia quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; quat.W = prm._orientation.W; d.RfromQ(out mat, ref quat); - d.MassRotate(ref tmpdmass, ref mat); - Vector3 ppos = prm._position; - ppos.X -= rcm.X; - ppos.Y -= rcm.Y; - ppos.Z -= rcm.Z; - // refer inertia to root prim center of mass position - d.MassTranslate(ref tmpdmass, - ppos.X, - ppos.Y, - ppos.Z); - - d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia // fix prim colision cats if (d.GeomGetBody(prm.prim_geom) != IntPtr.Zero) @@ -1789,6 +1963,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde d.GeomSetBody(prm.prim_geom, Body); prm.Body = Body; d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation + + if(noInertiaOverride) + { + tmpdmass = prm.primdMass; + + d.MassRotate(ref tmpdmass, ref mat); + Vector3 ppos = prm._position; + ppos.X -= rcm.X; + ppos.Y -= rcm.Y; + ppos.Z -= rcm.Z; + // refer inertia to root prim center of mass position + d.MassTranslate(ref tmpdmass, + ppos.X, + ppos.Y, + ppos.Z); + + d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia + } } } } @@ -1797,25 +1989,66 @@ namespace OpenSim.Region.PhysicsModule.ubOde // associate root geom with body d.GeomSetBody(prim_geom, Body); - d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); + if(noInertiaOverride) + d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); + else + { + Vector3 ncm = m_InertiaOverride.CenterOfMass * _orientation; + d.BodySetPosition(Body, + _position.X + ncm.X, + _position.Y + ncm.Y, + _position.Z + ncm.Z); + } + d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body - myrot.X = -myrot.X; - myrot.Y = -myrot.Y; - myrot.Z = -myrot.Z; + if(noInertiaOverride) + { + d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body + myrot.X = -myrot.X; + myrot.Y = -myrot.Y; + myrot.Z = -myrot.Z; - d.RfromQ(out mymat, ref myrot); - d.MassRotate(ref objdmass, ref mymat); + d.RfromQ(out mymat, ref myrot); + d.MassRotate(ref objdmass, ref mymat); - d.BodySetMass(Body, ref objdmass); - _mass = objdmass.mass; + d.BodySetMass(Body, ref objdmass); + m_mass = objdmass.mass; + } + else + { + objdmass.c.X = 0; + objdmass.c.Y = 0; + objdmass.c.Z = 0; + + objdmass.I.M00 = m_InertiaOverride.Inertia.X; + objdmass.I.M11 = m_InertiaOverride.Inertia.Y; + objdmass.I.M22 = m_InertiaOverride.Inertia.Z; + + objdmass.mass = m_InertiaOverride.TotalMass; + + if(Math.Abs(m_InertiaOverride.InertiaRotation.W) < 0.999) + { + d.Matrix3 inertiarotmat = new d.Matrix3(); + d.Quaternion inertiarot = new d.Quaternion(); + + inertiarot.X = m_InertiaOverride.InertiaRotation.X; + inertiarot.Y = m_InertiaOverride.InertiaRotation.Y; + inertiarot.Z = m_InertiaOverride.InertiaRotation.Z; + inertiarot.W = m_InertiaOverride.InertiaRotation.W; + d.RfromQ(out inertiarotmat, ref inertiarot); + d.MassRotate(ref objdmass, ref inertiarotmat); + } + d.BodySetMass(Body, ref objdmass); + + m_mass = objdmass.mass; + } // disconnect from world gravity so we can apply buoyancy d.BodySetGravityMode(Body, false); d.BodySetAutoDisableFlag(Body, true); - d.BodySetAutoDisableSteps(Body, body_autodisable_frames); + d.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); d.BodySetAutoDisableAngularThreshold(Body, 0.05f); d.BodySetAutoDisableLinearThreshold(Body, 0.05f); d.BodySetDamping(Body, .004f, .001f); @@ -1909,8 +2142,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde { d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); + _zeroFlag = false; - bodydisablecontrol = 0; + m_bodydisablecontrol = 0; } _parent_scene.addActiveGroups(this); } @@ -1988,7 +2222,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde SetInStaticSpace(prm); } prm.Body = IntPtr.Zero; - prm._mass = prm.primMass; + prm.m_mass = prm.primMass; prm.m_collisionscore = 0; } } @@ -2002,7 +2236,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } Body = IntPtr.Zero; } - _mass = primMass; + m_mass = primMass; m_collisionscore = 0; } @@ -2079,7 +2313,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body d.BodySetMass(Body, ref objdmass); - _mass = objdmass.mass; + m_mass = objdmass.mass; } private void FixInertia(Vector3 NewPos) @@ -2143,7 +2377,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body d.BodySetMass(Body, ref objdmass); - _mass = objdmass.mass; + m_mass = objdmass.mass; } private void FixInertia(Quaternion newrot) @@ -2209,7 +2443,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body d.BodySetMass(Body, ref objdmass); - _mass = objdmass.mass; + m_mass = objdmass.mass; } @@ -2224,7 +2458,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (primMass > _parent_scene.maximumMassObject) primMass = _parent_scene.maximumMassObject; - _mass = primMass; // just in case + m_mass = primMass; // just in case d.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z); @@ -2514,7 +2748,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_angularForceacc = Vector3.Zero; // m_torque = Vector3.Zero; _velocity = Vector3.Zero; - _acceleration = Vector3.Zero; + m_acceleration = Vector3.Zero; m_rotationalVelocity = Vector3.Zero; _target_velocity = Vector3.Zero; if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) @@ -2767,8 +3001,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde myrot.W = newOri.W; d.GeomSetQuaternion(prim_geom, ref myrot); _orientation = newOri; - if (Body != IntPtr.Zero && m_angularlocks != 0) - createAMotor(m_angularlocks); + + if (Body != IntPtr.Zero) + { + if(m_angularlocks != 0) + createAMotor(m_angularlocks); + } } if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) { @@ -3064,7 +3302,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void changeSetTorque(Vector3 newtorque) { - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { if (m_isphysical && Body != IntPtr.Zero) { @@ -3081,14 +3319,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void changeForce(Vector3 force) { m_force = force; - if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) + if (!m_isSelected && !m_outbounds && Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) d.BodyEnable(Body); } private void changeAddForce(Vector3 theforce) { m_forceacc += theforce; - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { lock (this) { @@ -3109,7 +3347,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void changeAddAngularImpulse(Vector3 aimpulse) { m_angularForceacc += aimpulse * m_invTimeStep; - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { lock (this) { @@ -3134,7 +3372,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde newVel *= len; } - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { if (Body != IntPtr.Zero) { @@ -3142,7 +3380,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde enableBodySoft(); else if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); - d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); } //resetCollisionAccounting(); @@ -3159,7 +3396,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde newAngVel *= len; } - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { if (Body != IntPtr.Zero) { @@ -3167,8 +3404,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde enableBodySoft(); else if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); - - d.BodySetAngularVel(Body, newAngVel.X, newAngVel.Y, newAngVel.Z); } //resetCollisionAccounting(); @@ -3304,6 +3539,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_useHoverPID = active; } + private void changeInertia(PhysicsInertiaData inertia) + { + m_InertiaOverride = inertia; + + if (Body != IntPtr.Zero) + DestroyBody(); + MakeBody(); + } + #endregion public void Move() @@ -3317,7 +3561,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) return; - if (++bodydisablecontrol < 50) + if (++m_bodydisablecontrol < 50) return; // clear residuals @@ -3325,11 +3569,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde d.BodySetLinearVel(Body,0f,0f,0f); _zeroFlag = true; d.BodyEnable(Body); - bodydisablecontrol = -4; + m_bodydisablecontrol = -4; } - if(bodydisablecontrol < 0) - bodydisablecontrol ++; + if(m_bodydisablecontrol < 0) + m_bodydisablecontrol ++; d.Vector3 lpos = d.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator @@ -3344,7 +3588,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde float fy = 0; float fz = 0; - float m_mass = _mass; + float mass = m_mass; if (m_usePID && m_PIDTau > 0) { @@ -3451,9 +3695,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde fz = _parent_scene.gravityz * b; } - fx *= m_mass; - fy *= m_mass; - fz *= m_mass; + fx *= mass; + fy *= mass; + fz *= mass; // constant force fx += m_force.X; @@ -3498,7 +3742,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { bool bodyenabled = d.BodyIsEnabled(Body); - if(bodydisablecontrol < 0) + if(m_bodydisablecontrol < 0) return; if (bodyenabled || !_zeroFlag) @@ -3513,9 +3757,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_outbounds = true; lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; + m_acceleration.X = 0; + m_acceleration.Y = 0; + m_acceleration.Z = 0; _velocity.X = 0; _velocity.Y = 0; @@ -3638,19 +3882,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde _orientation.W = ori.W; } - // update velocities and aceleration + // update velocities and acceleration if (_zeroFlag || lastZeroFlag) { // disable interpolators _velocity = Vector3.Zero; - _acceleration = Vector3.Zero; + m_acceleration = Vector3.Zero; m_rotationalVelocity = Vector3.Zero; } else { d.Vector3 vel = d.BodyGetLinearVel(Body); - _acceleration = _velocity; + m_acceleration = _velocity; if ((Math.Abs(vel.X) < 0.005f) && (Math.Abs(vel.Y) < 0.005f) && @@ -3658,28 +3902,28 @@ namespace OpenSim.Region.PhysicsModule.ubOde { _velocity = Vector3.Zero; float t = -m_invTimeStep; - _acceleration = _acceleration * t; + m_acceleration = m_acceleration * t; } else { _velocity.X = vel.X; _velocity.Y = vel.Y; _velocity.Z = vel.Z; - _acceleration = (_velocity - _acceleration) * m_invTimeStep; + m_acceleration = (_velocity - m_acceleration) * m_invTimeStep; } - if ((Math.Abs(_acceleration.X) < 0.01f) && - (Math.Abs(_acceleration.Y) < 0.01f) && - (Math.Abs(_acceleration.Z) < 0.01f)) + if ((Math.Abs(m_acceleration.X) < 0.01f) && + (Math.Abs(m_acceleration.Y) < 0.01f) && + (Math.Abs(m_acceleration.Z) < 0.01f)) { - _acceleration = Vector3.Zero; + m_acceleration = Vector3.Zero; } vel = d.BodyGetAngularVel(Body); if ((Math.Abs(vel.X) < 0.0001) && - (Math.Abs(vel.Y) < 0.0001) && - (Math.Abs(vel.Z) < 0.0001) - ) + (Math.Abs(vel.Y) < 0.0001) && + (Math.Abs(vel.Z) < 0.0001) + ) { m_rotationalVelocity = Vector3.Zero; } @@ -3939,6 +4183,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde changePIDHoverActive((bool)arg); break; + case changes.SetInertia: + changeInertia((PhysicsInertiaData) arg); + break; + case changes.Null: donullchange(); break; @@ -3955,7 +4203,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde _parent_scene.AddChange((PhysicsActor) this, what, arg); } - private struct strVehicleBoolParam { public int param; diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs index bed66ccad3..86d41eabf2 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs @@ -155,6 +155,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde VehicleRotationParam, VehicleFlags, SetVehicle, + SetInertia, Null //keep this last used do dim the methods array. does nothing but pulsing the prim } @@ -185,7 +186,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde float frictionMovementMult = 0.8f; - float TerrainBounce = 0.1f; + float TerrainBounce = 0.001f; float TerrainFriction = 0.3f; public float AvatarFriction = 0;// 0.9f * 0.5f; @@ -502,7 +503,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde d.WorldSetGravity(world, gravityx, gravityy, gravityz); - d.WorldSetLinearDamping(world, 0.002f); + d.WorldSetLinearDamping(world, 0.001f); d.WorldSetAngularDamping(world, 0.002f); d.WorldSetAngularDampingThreshold(world, 0f); d.WorldSetLinearDampingThreshold(world, 0f); @@ -528,6 +529,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde SharedTmpcontact.surface.mode = comumContactFlags; SharedTmpcontact.surface.mu = 0; SharedTmpcontact.surface.bounce = 0; + SharedTmpcontact.surface.bounce_vel = 1.5f; SharedTmpcontact.surface.soft_cfm = comumContactCFM; SharedTmpcontact.surface.soft_erp = comumContactERP; SharedTmpcontact.surface.slip1 = comumContactSLIP; @@ -726,8 +728,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (g1 == g2) return; // Can't collide with yourself - if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) - return; +// if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) +// return; /* // debug PhysicsActor dp2; @@ -1082,9 +1084,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde case ActorTypes.Prim: if (p2events) { - AddCollisionEventReporting(p2); + //AddCollisionEventReporting(p2); p2.AddCollisionEvent(p1.ParentActor.LocalID, contact); } + else if(p1.IsVolumeDtc) + p2.AddVDTCCollisionEvent(p1.ParentActor.LocalID, contact); + obj2LocalID = p2.ParentActor.LocalID; break; @@ -1098,9 +1103,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde { contact.SurfaceNormal = -contact.SurfaceNormal; contact.RelativeSpeed = -contact.RelativeSpeed; - AddCollisionEventReporting(p1); + //AddCollisionEventReporting(p1); p1.AddCollisionEvent(obj2LocalID, contact); } + else if(p2.IsVolumeDtc) + { + contact.SurfaceNormal = -contact.SurfaceNormal; + contact.RelativeSpeed = -contact.RelativeSpeed; + //AddCollisionEventReporting(p1); + p1.AddVDTCCollisionEvent(obj2LocalID, contact); + } break; } case ActorTypes.Ground: @@ -1109,7 +1121,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (p2events && !p2.IsVolumeDtc) { - AddCollisionEventReporting(p2); + //AddCollisionEventReporting(p2); p2.AddCollisionEvent(0, contact); } break; @@ -1161,8 +1173,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde { aprim.CollisionScore = 0; aprim.IsColliding = false; + if(!aprim.m_outbounds && d.BodyIsEnabled(aprim.Body)) + aprim.clearSleeperCollisions(); } } + lock (_activegroups) { try @@ -1657,11 +1672,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde // d.WorldSetQuickStepNumIterations(world, curphysiteractions); - int loopstartMS = Util.EnvironmentTickCount(); - int looptimeMS = 0; - int changestimeMS = 0; - int maxChangestime = (int)(reqTimeStep * 500f); // half the time - int maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time + double loopstartMS = Util.GetTimeStampMS(); + double looptimeMS = 0; + double changestimeMS = 0; + double maxChangestime = (int)(reqTimeStep * 500f); // half the time + double maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time + +// double collisionTime = 0; +// double qstepTIme = 0; +// double tmpTime = 0; d.AllocateODEDataForThread(~0U); @@ -1684,7 +1703,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde item.actor.Name, item.what.ToString()); } } - changestimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); + changestimeMS = Util.GetTimeStampMS() - loopstartMS; if (changestimeMS > maxChangestime) break; } @@ -1729,9 +1748,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_rayCastManager.ProcessQueuedRequests(); +// tmpTime = Util.GetTimeStampMS(); collision_optimized(); - List sleepers = new List(); +// collisionTime += Util.GetTimeStampMS() - tmpTime; + lock(_collisionEventPrimRemove) + { + foreach (PhysicsActor obj in _collisionEventPrimRemove) + _collisionEventPrim.Remove(obj); + + _collisionEventPrimRemove.Clear(); + } + + List sleepers = new List(); foreach (PhysicsActor obj in _collisionEventPrim) { if (obj == null) @@ -1761,18 +1790,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde foreach(OdePrim prm in sleepers) prm.SleeperAddCollisionEvents(); sleepers.Clear(); - - lock(_collisionEventPrimRemove) - { - foreach (PhysicsActor obj in _collisionEventPrimRemove) - _collisionEventPrim.Remove(obj); - - _collisionEventPrimRemove.Clear(); - } - + // do a ode simulation step +// tmpTime = Util.GetTimeStampMS(); d.WorldQuickStep(world, ODE_STEPSIZE); d.JointGroupEmpty(contactgroup); +// qstepTIme += Util.GetTimeStampMS() - tmpTime; // update managed ideia of physical data and do updates to core /* @@ -1813,7 +1836,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde step_time -= ODE_STEPSIZE; nodeframes++; - looptimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); + looptimeMS = Util.GetTimeStampMS() - loopstartMS; if (looptimeMS > maxLoopTime) break; } @@ -1881,6 +1904,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde int totgeoms = nstaticgeoms + nactivegeoms + ngroundgeoms + 1; // one ray int nbodies = d.NTotalBodies; int ngeoms = d.NTotalGeoms; +*/ +/* + looptimeMS /= nodeframes; + if(looptimeMS > 0.080) + { + collisionTime /= nodeframes; + qstepTIme /= nodeframes; + } */ // Finished with all sim stepping. If requested, dump world state to file for debugging. // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs index 163f43928a..0117800b96 100644 --- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs +++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs @@ -454,7 +454,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing if (physicsParms == null) { - m_log.WarnFormat("[MESH]: unknown mesh type for prim {0}",primName); + //m_log.WarnFormat("[MESH]: unknown mesh type for prim {0}",primName); return false; } @@ -712,7 +712,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing else { // if neither mesh or decomposition present, warn and use convex - m_log.WarnFormat("[MESH]: Data for PRIM shape type ( mesh or decomposition) not found for prim {0}",primName); + //m_log.WarnFormat("[MESH]: Data for PRIM shape type ( mesh or decomposition) not found for prim {0}",primName); } } vs.Clear(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ad7fc6c77f..47c3cb89c6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -424,6 +424,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return lease; } + protected SceneObjectPart MonitoringObject() + { + UUID m = m_host.ParentGroup.MonitoringObject; + if (m == UUID.Zero) + return null; + + SceneObjectPart p = m_ScriptEngine.World.GetSceneObjectPart(m); + if (p == null) + m_host.ParentGroup.MonitoringObject = UUID.Zero; + + return p; + } + protected virtual void ScriptSleep(int delay) { delay = (int)((float)delay * m_ScriptDelayFactor); @@ -481,12 +494,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID item; - m_host.AddScriptLPS(1); - - if ((item = GetScriptByName(name)) != UUID.Zero) - m_ScriptEngine.ResetScript(item); - else + if ((item = GetScriptByName(name)) == UUID.Zero) + { + m_host.AddScriptLPS(1); Error("llResetOtherScript", "Can't find script '" + name + "'"); + return; + } + if(item == m_item.ItemID) + llResetScript(); + else + { + m_host.AddScriptLPS(1); + m_ScriptEngine.ResetScript(item); + } } public LSL_Integer llGetScriptState(string name) @@ -2712,9 +2732,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// if TRUE, will cap the distance to 10m. protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted || part.ParentGroup.inTransit) return; + LSL_Vector currentPos = GetPartLocalPos(part); LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust); @@ -2722,7 +2743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part.ParentGroup.RootPart == part) { SceneObjectGroup parent = part.ParentGroup; - if (!parent.IsAttachment && !World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos)) + if (!parent.IsAttachment && !World.Permissions.CanObjectEntry(parent, false, (Vector3)toPos)) return; parent.UpdateGroupPosition((Vector3)toPos); } @@ -5738,29 +5759,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { return 0; - } + + object item = src.Data[index]; // Vectors & Rotations always return zero in SL, but // keys don't always return zero, it seems to be a bit complex. - else if (src.Data[index] is LSL_Vector || - src.Data[index] is LSL_Rotation) - { + if (item is LSL_Vector || item is LSL_Rotation) return 0; - } + try { - - if (src.Data[index] is LSL_Integer) - return (LSL_Integer)src.Data[index]; - else if (src.Data[index] is LSL_Float) - return Convert.ToInt32(((LSL_Float)src.Data[index]).value); - return new LSL_Integer(src.Data[index].ToString()); + if (item is LSL_Integer) + return (LSL_Integer)item; + else if (item is LSL_Float) + return Convert.ToInt32(((LSL_Float)item).value);; + return new LSL_Integer(item.ToString()); } catch (FormatException) { @@ -5772,38 +5789,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { - return 0.0; - } + return 0; + + object item = src.Data[index]; // Vectors & Rotations always return zero in SL - else if (src.Data[index] is LSL_Vector || - src.Data[index] is LSL_Rotation) - { + if(item is LSL_Vector || item is LSL_Rotation) return 0; - } + // valid keys seem to get parsed as integers then converted to floats - else + if (item is LSL_Key) { UUID uuidt; - if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt)) - { - return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value); - } + string s = item.ToString(); + if(UUID.TryParse(s, out uuidt)) + return Convert.ToDouble(new LSL_Integer(s).value); +// we can't do this because a string is also a LSL_Key for now :( +// else +// return 0; } + try { - if (src.Data[index] is LSL_Integer) - return Convert.ToDouble(((LSL_Integer)src.Data[index]).value); - else if (src.Data[index] is LSL_Float) - return Convert.ToDouble(((LSL_Float)src.Data[index]).value); - else if (src.Data[index] is LSL_String) + if (item is LSL_Integer) + return Convert.ToDouble(((LSL_Integer)item).value); + else if (item is LSL_Float) + return Convert.ToDouble(((LSL_Float)item).value); + else if (item is LSL_String) { - string str = ((LSL_String) src.Data[index]).m_string; + string str = ((LSL_String)item).m_string; Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)"); if (m != Match.Empty) { @@ -5811,12 +5828,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api double d = 0.0; if (!Double.TryParse(str, out d)) return 0.0; - return d; } return 0.0; } - return Convert.ToDouble(src.Data[index]); + return Convert.ToDouble(item); } catch (FormatException) { @@ -5828,13 +5844,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { return String.Empty; - } + return src.Data[index].ToString(); } @@ -5842,14 +5856,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } if (index >= src.Length || index < 0) - { - return ""; - } + return String.Empty; + + object item = src.Data[index]; // SL spits out an empty string for types other than key & string // At the time of patching, LSL_Key is currently LSL_String, @@ -5858,31 +5870,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // as it's own struct // NOTE: 3rd case is needed because a NULL_KEY comes through as // type 'obj' and wrongly returns "" - else if (!(src.Data[index] is LSL_String || - src.Data[index] is LSL_Key || - src.Data[index].ToString() == "00000000-0000-0000-0000-000000000000")) + if (!(item is LSL_String || + item is LSL_Key || + item.ToString() == "00000000-0000-0000-0000-000000000000")) { - return ""; + return String.Empty; } - return src.Data[index].ToString(); + return item.ToString(); } public LSL_Vector llList2Vector(LSL_List src, int index) { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { return new LSL_Vector(0, 0, 0); - } - if (src.Data[index].GetType() == typeof(LSL_Vector)) - { - return (LSL_Vector)src.Data[index]; - } + + object item = src.Data[index]; + + if (item.GetType() == typeof(LSL_Vector)) + return (LSL_Vector)item; // SL spits always out ZERO_VECTOR for anything other than // strings or vectors. Although keys always return ZERO_VECTOR, @@ -5890,28 +5900,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // a string, a key as string and a string that by coincidence // is a string, so we're going to leave that up to the // LSL_Vector constructor. - else if (!(src.Data[index] is LSL_String || - src.Data[index] is LSL_Vector)) - { - return new LSL_Vector(0, 0, 0); - } - else - { - return new LSL_Vector(src.Data[index].ToString()); - } + if(item is LSL_Vector) + return (LSL_Vector) item; + + if (item is LSL_String) + return new LSL_Vector(item.ToString()); + + return new LSL_Vector(0, 0, 0); } public LSL_Rotation llList2Rot(LSL_List src, int index) { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { return new LSL_Rotation(0, 0, 0, 1); - } + + object item = src.Data[index]; // SL spits always out ZERO_ROTATION for anything other than // strings or vectors. Although keys always return ZERO_ROTATION, @@ -5919,19 +5926,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // a string, a key as string and a string that by coincidence // is a string, so we're going to leave that up to the // LSL_Rotation constructor. - else if (!(src.Data[index] is LSL_String || - src.Data[index] is LSL_Rotation)) - { - return new LSL_Rotation(0, 0, 0, 1); - } - else if (src.Data[index].GetType() == typeof(LSL_Rotation)) - { - return (LSL_Rotation)src.Data[index]; - } - else - { + + if (item.GetType() == typeof(LSL_Rotation)) + return (LSL_Rotation)item; + + if (item is LSL_String) return new LSL_Rotation(src.Data[index].ToString()); - } + + return new LSL_Rotation(0, 0, 0, 1); } public LSL_List llList2List(LSL_List src, int start, int end) @@ -7963,7 +7965,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llScriptDanger(LSL_Vector pos) { m_host.AddScriptLPS(1); - bool result = World.ScriptDanger(m_host.LocalId, pos); + bool result = World.LSLScriptDanger(m_host, pos); if (result) { return 1; @@ -7972,7 +7974,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { return 0; } - } public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel) @@ -8849,10 +8850,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void llSetPhysicsMaterial(int material_bits, - float material_gravity_modifier, float material_restitution, - float material_friction, float material_density) + LSL_Float material_gravity_modifier, LSL_Float material_restitution, + LSL_Float material_friction, LSL_Float material_density) { - SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier); + SetPhysicsMaterial(m_host, material_bits, (float)material_density, (float)material_friction, (float)material_restitution, (float)material_gravity_modifier); } // vector up using libomv (c&p from sop ) @@ -11297,6 +11298,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; + case (int)ScriptBaseClass.PRIM_NORMAL: + case (int)ScriptBaseClass.PRIM_SPECULAR: + case (int)ScriptBaseClass.PRIM_ALPHA_MODE: + if (remain < 1) + return new LSL_List(); + + face = (int)rules.GetLSLIntegerItem(idx++); + tex = part.Shape.Textures; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + Primitive.TextureEntryFace texface = tex.GetFace((uint)face); + getLSLFaceMaterial(ref res, code, part, texface); + } + } + else + { + if (face >= 0 && face < GetNumberOfSides(part)) + { + Primitive.TextureEntryFace texface = tex.GetFace((uint)face); + getLSLFaceMaterial(ref res, code, part, texface); + } + } + break; + case (int)ScriptBaseClass.PRIM_LINK_TARGET: // TODO: Should be issuing a runtime script warning in this case. @@ -11310,6 +11337,108 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_List(); } +/* + private string filterTextureUUIDbyRights(UUID origID, SceneObjectPart part, bool checkTaskInventory, bool returnInvName) + { + if(checkTaskInventory) + { + lock (part.TaskInventory) + { + foreach (KeyValuePair inv in part.TaskInventory) + { + if (inv.Value.AssetID == origID) + { + if(inv.Value.InvType == (int)InventoryType.Texture) + { + if(returnInvName) + return inv.Value.Name; + else + return origID.ToString(); + } + else + return UUID.Zero.ToString(); + } + } + } + } + + if(World.Permissions.CanEditObject(m_host.ParentGroup.UUID, m_host.ParentGroup.RootPart.OwnerID)) + return origID.ToString(); + + return UUID.Zero.ToString(); + } +*/ + private void getLSLFaceMaterial(ref LSL_List res, int code, SceneObjectPart part, Primitive.TextureEntryFace texface) + { + UUID matID = texface.MaterialID; + if(matID != UUID.Zero) + { + AssetBase MatAsset = World.AssetService.Get(matID.ToString()); + if(MatAsset != null) + { + Byte[] data = MatAsset.Data; + OSDMap osdmat = (OSDMap)OSDParser.DeserializeLLSDXml(data); + if(osdmat != null && osdmat.ContainsKey("NormMap")) + { + string mapIDstr; + FaceMaterial mat = new FaceMaterial(matID, osdmat); + if(code == ScriptBaseClass.PRIM_NORMAL) + { +// mapIDstr = filterTextureUUIDbyRights(mat.NormalMapID, part, true, false); + mapIDstr = mat.NormalMapID.ToString(); + res.Add(new LSL_String(mapIDstr)); + res.Add(new LSL_Vector(mat.NormalRepeatX, mat.NormalRepeatY, 0)); + res.Add(new LSL_Vector(mat.NormalOffsetX, mat.NormalOffsetY, 0)); + res.Add(new LSL_Float(mat.NormalRotation)); + } + else if(code == ScriptBaseClass.PRIM_SPECULAR ) + { +// mapIDstr = filterTextureUUIDbyRights(mat.SpecularMapID, part, true, false); + const float colorScale = 1.0f/255f; + mapIDstr = mat.SpecularMapID.ToString(); + res.Add(new LSL_String(mapIDstr)); + res.Add(new LSL_Vector(mat.SpecularRepeatX, mat.SpecularRepeatY, 0)); + res.Add(new LSL_Vector(mat.SpecularOffsetX, mat.SpecularOffsetY, 0)); + res.Add(new LSL_Float(mat.SpecularRotation)); + res.Add(new LSL_Vector(mat.SpecularLightColor.R * colorScale, + mat.SpecularLightColor.G * colorScale, + mat.SpecularLightColor.B * colorScale)); + res.Add(new LSL_Integer(mat.SpecularLightExponent)); + res.Add(new LSL_Integer(mat.EnvironmentIntensity)); + } + else if(code == ScriptBaseClass.PRIM_ALPHA_MODE) + { + res.Add(new LSL_Integer(mat.DiffuseAlphaMode)); + res.Add(new LSL_Integer(mat.AlphaMaskCutoff)); + } + return; + } + } + matID = UUID.Zero; + } + if(matID == UUID.Zero) + { + if(code == (int)ScriptBaseClass.PRIM_NORMAL || code == (int)ScriptBaseClass.PRIM_SPECULAR ) + { + res.Add(new LSL_String(UUID.Zero.ToString())); + res.Add(new LSL_Vector(1.0, 1.0, 0)); + res.Add(new LSL_Vector(0, 0, 0)); + res.Add(new LSL_Float(0)); + + if(code == (int)ScriptBaseClass.PRIM_SPECULAR) + { + res.Add(new LSL_Vector(1.0, 1.0, 1.0)); + res.Add(new LSL_Integer(51)); + res.Add(new LSL_Integer(0)); + } + } + else if(code == (int)ScriptBaseClass.PRIM_ALPHA_MODE) + { + res.Add(new LSL_Integer(1)); + res.Add(new LSL_Integer(0)); + } + } + } public LSL_List llGetPrimMediaParams(int face, LSL_List rules) { @@ -15867,7 +15996,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - group.RootPart.AttachPoint = group.RootPart.Shape.State; group.RootPart.AttachedPos = group.AbsolutePosition; group.ResetIDs(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index e769c6da10..e12cedf96a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -260,7 +260,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); } - // Returns of the function is allowed. Throws a script exception if not allowed. + // Returns if OSSL is enabled. Throws a script exception if OSSL is not allowed.. + // for safe funtions always active + public void CheckThreatLevel() + { + if (!m_OSFunctionsEnabled) + OSSLError(String.Format("{0} permission denied. All OS functions are disabled.")); // throws + } + + // Returns if the function is allowed. Throws a script exception if not allowed. public void CheckThreatLevel(ThreatLevel level, string function) { if (!m_OSFunctionsEnabled) @@ -1716,7 +1724,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer osCheckODE() { + CheckThreatLevel(); m_host.AddScriptLPS(1); + LSL_Integer ret = 0; // false if (m_ScriptEngine.World.PhysicsScene != null) { @@ -1757,10 +1767,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetPhysicsEngineName() { - // not doing security checks - // this whould limit the use of this - + CheckThreatLevel(); m_host.AddScriptLPS(1); + string ret = "NoEngine"; if (m_ScriptEngine.World.PhysicsScene != null) { @@ -1771,6 +1780,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } return ret; } + public string osGetSimulatorVersion() { // High because it can be used to target attacks to known weaknesses @@ -2038,6 +2048,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.Inventory.AddInventoryItemExclusive(taskItem, false); else m_host.Inventory.AddInventoryItem(taskItem, false); + m_host.ParentGroup.AggregatePerms(); return taskItem; } @@ -3537,7 +3548,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Float health = new LSL_Float(-1); ScenePresence presence = World.GetScenePresence(new UUID(avatar)); - if (presence != null) health = presence.Health; + if (presence != null) + health = presence.Health; return health; } @@ -3577,7 +3589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID avatarId = new UUID(avatar); ScenePresence presence = World.GetScenePresence(avatarId); - if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition())) + if (presence != null) { float health = presence.Health; health += (float)healing; @@ -3597,7 +3609,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID avatarId = new UUID(avatar); ScenePresence presence = World.GetScenePresence(avatarId); - if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition())) + if (presence != null) { if (health > 100.0) health = 100.0; @@ -3616,7 +3628,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID avatarId = new UUID(avatar); ScenePresence presence = World.GetScenePresence(avatarId); - if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition())) + if (presence != null) presence.HealRate = (float)healrate; } @@ -4362,6 +4374,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osCollisionSound(string impact_sound, double impact_volume) { + CheckThreatLevel(); m_host.AddScriptLPS(1); if(impact_sound == "") @@ -4394,6 +4407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // still not very usefull, detector is lost on rez, restarts, etc public void osVolumeDetect(int detect) { + CheckThreatLevel(); m_host.AddScriptLPS(1); if (m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted || m_host.ParentGroup.IsAttachment) @@ -4402,5 +4416,285 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.ScriptSetVolumeDetect(detect != 0); } + /// + /// Get inertial data + /// + /// + /// + /// + /// a LSL list with contents: + /// LSL_Float mass, the total mass of a linkset + /// LSL_Vector CenterOfMass, center mass relative to root prim + /// LSL_Vector Inertia, elements of diagonal of inertia Ixx,Iyy,Izz divided by total mass + /// LSL_Vector aux, elements of upper triagle of inertia Ixy (= Iyx), Ixz (= Izx), Iyz(= Izy) divided by total mass + /// + public LSL_List osGetInertiaData() + { + CheckThreatLevel(); + m_host.AddScriptLPS(1); + + LSL_List result = new LSL_List(); + float TotalMass; + Vector3 CenterOfMass; + Vector3 Inertia; + Vector4 aux; + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return result; + + sog.GetInertiaData(out TotalMass, out CenterOfMass, out Inertia, out aux ); + if(TotalMass > 0) + { + float t = 1.0f/TotalMass; + Inertia.X *= t; + Inertia.Y *= t; + Inertia.Z *= t; + + aux.X *= t; + aux.Y *= t; + aux.Z *= t; + } + + result.Add(new LSL_Float(TotalMass)); + result.Add(new LSL_Vector(CenterOfMass.X, CenterOfMass.Y, CenterOfMass.Z)); + result.Add(new LSL_Vector(Inertia.X, Inertia.Y, Inertia.Z)); + result.Add(new LSL_Vector(aux.X, aux.Y, aux.Z)); + return result; + } + + /// + /// set inertial data + /// replaces the automatic calculation of mass, center of mass and inertia + /// + /// + /// total mass of linkset + /// location of center of mass relative to root prim in local coords + /// moment of inertia relative to principal axis and center of mass,Ixx, Iyy, Izz divided by mass + /// rotation of the inertia, relative to local axis + /// + /// the inertia argument is is inertia divided by mass, so corresponds only to the geometric distribution of mass and both can be changed independently. + /// + + public void osSetInertia(LSL_Float mass, LSL_Vector centerOfMass, LSL_Vector principalInertiaScaled, LSL_Rotation lslrot) + { + CheckThreatLevel(); + m_host.AddScriptLPS(1); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + if(mass < 0 || principalInertiaScaled.x < 0 || principalInertiaScaled.y < 0 || principalInertiaScaled.z < 0) + return; + + // need more checks + + Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); + Vector3 Inertia; + float m = (float)mass; + + Inertia.X = m * (float)principalInertiaScaled.x; + Inertia.Y = m * (float)principalInertiaScaled.y; + Inertia.Z = m * (float)principalInertiaScaled.z; + + Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.y, (float)lslrot.s); + rot.Normalize(); + + sog.SetInertiaData(m, CenterOfMass, Inertia, rot ); + } + + /// + /// set inertial data as a sphere + /// replaces the automatic calculation of mass, center of mass and inertia + /// + /// + /// total mass of linkset + /// size of the Box + /// location of center of mass relative to root prim in local coords + /// rotation of the box, and so inertia, relative to local axis + /// + /// + public void osSetInertiaAsBox(LSL_Float mass, LSL_Vector boxSize, LSL_Vector centerOfMass, LSL_Rotation lslrot) + { + CheckThreatLevel(); + m_host.AddScriptLPS(1); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + if(mass < 0) + return; + + // need more checks + + Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); + Vector3 Inertia; + float lx = (float)boxSize.x; + float ly = (float)boxSize.y; + float lz = (float)boxSize.z; + float m = (float)mass; + float t = m / 12.0f; + + Inertia.X = t * (ly*ly + lz*lz); + Inertia.Y = t * (lx*lx + lz*lz); + Inertia.Z = t * (lx*lx + ly*ly); + + Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s); + rot.Normalize(); + + sog.SetInertiaData(m, CenterOfMass, Inertia, rot ); + } + + /// + /// set inertial data as a sphere + /// replaces the automatic calculation of mass, center of mass and inertia + /// + /// + /// total mass of linkset + /// radius of the sphere + /// location of center of mass relative to root prim in local coords + /// + /// + public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, LSL_Vector centerOfMass) + { + CheckThreatLevel(); + m_host.AddScriptLPS(1); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + if(mass < 0) + return; + + // need more checks + + Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); + Vector3 Inertia; + float r = (float)radius; + float m = (float)mass; + float t = 0.4f * m * r * r; + + Inertia.X = t; + Inertia.Y = t; + Inertia.Z = t; + + sog.SetInertiaData(m, CenterOfMass, Inertia, new Vector4(0f, 0f, 0f,1.0f)); + } + + /// + /// set inertial data as a cylinder + /// replaces the automatic calculation of mass, center of mass and inertia + /// + /// + /// total mass of linkset + /// radius of the cylinder + /// lenght of the cylinder + /// location of center of mass relative to root prim in local coords + /// rotation of the cylinder, and so inertia, relative to local axis + /// + /// cylinder axis aligned with Z axis. For other orientations provide the rotation. + /// + public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, LSL_Vector centerOfMass, LSL_Rotation lslrot) + { + CheckThreatLevel(); + m_host.AddScriptLPS(1); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + if(mass < 0) + return; + + // need more checks + + Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); + Vector3 Inertia; + float m = (float)mass; + float r = (float)radius; + r *= r; + Inertia.Z = 0.5f * m * r; + float t = (float)lenght; + t *= t; + t += 3.0f * r; + t *= 8.333333e-2f * m; + + Inertia.X = t; + Inertia.Y = t; + + Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s); + rot.Normalize(); + + sog.SetInertiaData(m, CenterOfMass, Inertia, rot); + } + + /// + /// removes inertial data manual override + /// default automatic calculation is used again + /// + /// + public void osClearInertia() + { + CheckThreatLevel(); + m_host.AddScriptLPS(1); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + sog.SetInertiaData(-1, Vector3.Zero, Vector3.Zero, Vector4.Zero ); + } + + /// + /// teleports a object (full linkset) + /// + /// the id of the linkset to teleport + /// target position + /// a rotation to apply + /// several flags/param> + /// + /// only does teleport local to region + /// if object has scripts, owner must have rights to run scripts on target location + /// object owner must have rights to enter ojects on target location + /// target location parcel must have enought free prims capacity for the linkset prims + /// all avatars siting on the object must have access to target location + /// has a cool down time. retries before expire reset it + /// fail conditions are silent ignored + /// + public LSL_Integer osTeleportObject(LSL_Key objectUUID, LSL_Vector targetPos, LSL_Rotation rotation, LSL_Integer flags) + { + CheckThreatLevel(ThreatLevel.Severe, "osTeleportObject"); + m_host.AddScriptLPS(1); + + UUID objUUID; + if (!UUID.TryParse(objectUUID, out objUUID)) + { + OSSLShoutError("osTeleportObject() invalid object Key"); + return -1; + } + + SceneObjectGroup sog = World.GetSceneObjectGroup(objUUID); + if(sog== null || sog.IsDeleted) + return -1; + + UUID myid = m_host.ParentGroup.UUID; + + return sog.TeleportObject(myid, targetPos, rotation, flags); + // a delay here may break vehicles + } + + public LSL_Integer osGetLinkNumber(LSL_String name) + { + CheckThreatLevel(); + m_host.AddScriptLPS(1); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return -1; + return sog.GetLinkNumber(name); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index cc5240375c..17c977f927 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -434,7 +434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String llXorBase64Strings(string str1, string str2); LSL_String llXorBase64StringsCorrect(string str1, string str2); LSL_Integer llGetLinkNumberOfSides(LSL_Integer link); - void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density); + void llSetPhysicsMaterial(int material_bits, LSL_Float material_gravity_modifier, LSL_Float material_restitution, LSL_Float material_friction, LSL_Float material_density); void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); void llSetKeyframedMotion(LSL_List frames, LSL_List options); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index bee060ad4c..bd5d008d92 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -38,6 +38,7 @@ using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; + namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces { /// @@ -50,7 +51,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces /// public enum ThreatLevel { - // Not documented, presumably means permanently disabled ? NoAccess = -1, /// @@ -486,6 +486,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String osRequestURL(LSL_List options); LSL_String osRequestSecureURL(LSL_List options); void osCollisionSound(string impact_sound, double impact_volume); + void osVolumeDetect(int detect); + + LSL_List osGetInertiaData(); + void osClearInertia(); + void osSetInertiaAsBox(LSL_Float mass, vector boxSize, vector centerOfMass, rotation rot); + void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, vector centerOfMass); + void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, vector centerOfMass,rotation lslrot); + + LSL_Integer osTeleportObject(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer flags); + LSL_Integer osGetLinkNumber(LSL_String name); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 3a90c7704e..ce0fa4824c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -853,5 +853,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase /// process message parameter as regex /// public const int OS_LISTEN_REGEX_MESSAGE = 0x2; + + // for osTeleportObject + public const int OSTPOBJ_NONE = 0x0; + public const int OSTPOBJ_STOPATTARGET = 0x1; // stops at destination + public const int OSTPOBJ_STOPONFAIL = 0x2; // stops at jump point if tp fails + public const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 1a42c3a609..c39248bcd2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -2036,7 +2036,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetKeyframedMotion(frames, options); } - public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density) + public void llSetPhysicsMaterial(int material_bits, LSL_Float material_gravity_modifier, LSL_Float material_restitution, LSL_Float material_friction, LSL_Float material_density) { m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 6164734789..9eac1149da 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1114,5 +1114,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { m_OSSL_Functions.osVolumeDetect(detect); } + + public LSL_List osGetInertiaData() + { + return m_OSSL_Functions.osGetInertiaData(); + } + + public void osSetInertiaAsBox(LSL_Float mass, vector boxSize, vector centerOfMass, rotation rot) + { + m_OSSL_Functions.osSetInertiaAsBox(mass, boxSize, centerOfMass, rot); + } + + public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, vector centerOfMass) + { + m_OSSL_Functions.osSetInertiaAsSphere(mass, radius, centerOfMass); + } + + public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, vector centerOfMass,rotation lslrot) + { + m_OSSL_Functions.osSetInertiaAsCylinder( mass, radius, lenght, centerOfMass, lslrot); + } + + public void osClearInertia() + { + m_OSSL_Functions.osClearInertia(); + } + + public LSL_Integer osTeleportObject(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer flags) + { + return m_OSSL_Functions.osTeleportObject(objectUUID, targetPos, targetrotation, flags); + } + + public LSL_Integer osGetLinkNumber(LSL_String name) + { + return m_OSSL_Functions.osGetLinkNumber(name); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index d652b0d1d2..16b87b3402 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -39,6 +39,7 @@ using OpenSim.Framework; using OpenSim.Region.CoreModules.Avatar.AvatarFactory; using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.CoreModules.World.Permissions; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; using OpenSim.Region.ScriptEngine.Shared.Instance; @@ -63,12 +64,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests base.SetUp(); IConfigSource initConfigSource = new IniConfigSource(); - IConfig config = initConfigSource.AddConfig("XEngine"); + IConfig config = initConfigSource.AddConfig("Startup"); + config.Set("serverside_object_permissions", true); + config =initConfigSource.AddConfig("Permissions"); + config.Set("permissionmodules", "DefaultPermissionsModule"); + config.Set("serverside_object_permissions", true); + config.Set("propagate_permissions", true); + + config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); m_scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(m_scene, initConfigSource); - + SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new object[] { new DefaultPermissionsModule() }); m_engine = new XEngine.XEngine(); m_engine.Initialise(initConfigSource); m_engine.AddRegion(m_scene); diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index f60b5fb6dc..d151de663e 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -61,6 +61,9 @@ namespace OpenSim.Server.Base // private bool m_Running = true; + private static Mono.Unix.UnixSignal[] signals; + + // Handle all the automagical stuff // public ServicesServerBase(string prompt, string[] args) : base() @@ -183,6 +186,39 @@ namespace OpenSim.Server.Base RegisterCommonCommands(); RegisterCommonComponents(Config); + Thread signal_thread = new Thread (delegate () + { + while (true) + { + // Wait for a signal to be delivered + int index = Mono.Unix.UnixSignal.WaitAny (signals, -1); + + //Mono.Unix.Native.Signum signal = signals [index].Signum; + ShutdownSpecific(); + m_Running = false; + Environment.Exit(0); + } + }); + + if(!Util.IsWindows()) + { + try + { + // linux mac os specifics + signals = new Mono.Unix.UnixSignal[] + { + new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM) + }; + signal_thread.Start(); + } + catch (Exception e) + { + m_log.Info("Could not set up UNIX signal handlers. SIGTERM will not"); + m_log.InfoFormat("shut down gracefully: {0}", e.Message); + m_log.Debug("Exception was: ", e); + } + } + // Allow derived classes to perform initialization that // needs to be done after the console has opened Initialise(); diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index 3fa8b54d73..810da2f7cc 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs @@ -243,8 +243,12 @@ namespace OpenSim.Services.Connectors string uri = MapServer(id) + "/assets/" + id; AssetBase asset = null; + if (m_Cache != null) - asset = m_Cache.Get(id); + { + if (!m_Cache.Get(id, out asset)) + return null; + } if (asset == null || asset.Data == null || asset.Data.Length == 0) { @@ -275,17 +279,22 @@ namespace OpenSim.Services.Connectors { // m_log.DebugFormat("[ASSET SERVICE CONNECTOR]: Cache request for {0}", id); + AssetBase asset = null; if (m_Cache != null) - return m_Cache.Get(id); + { + m_Cache.Get(id, out asset); + } - return null; + return asset; } public AssetMetadata GetMetadata(string id) { if (m_Cache != null) { - AssetBase fullAsset = m_Cache.Get(id); + AssetBase fullAsset; + if (!m_Cache.Get(id, out fullAsset)) + return null; if (fullAsset != null) return fullAsset.Metadata; @@ -301,7 +310,9 @@ namespace OpenSim.Services.Connectors { if (m_Cache != null) { - AssetBase fullAsset = m_Cache.Get(id); + AssetBase fullAsset; + if (!m_Cache.Get(id, out fullAsset)) + return null; if (fullAsset != null) return fullAsset.Data; @@ -389,7 +400,10 @@ namespace OpenSim.Services.Connectors AssetBase asset = null; if (m_Cache != null) - asset = m_Cache.Get(id); + { + if (!m_Cache.Get(id, out asset)) + return false; + } if (asset == null || asset.Data == null || asset.Data.Length == 0) { @@ -590,7 +604,7 @@ namespace OpenSim.Services.Connectors AssetBase asset = null; if (m_Cache != null) - asset = m_Cache.Get(id); + m_Cache.Get(id, out asset); if (asset == null) { diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 121e8636e4..953bc2af1b 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -136,7 +136,9 @@ namespace OpenSim.Services.Connectors.SimianGrid // Cache fetch if (m_cache != null) { - AssetBase asset = m_cache.Get(id); + AssetBase asset; + if (!m_cache.Get(id, out asset)) + return null; if (asset != null) return asset; } @@ -147,8 +149,9 @@ namespace OpenSim.Services.Connectors.SimianGrid public AssetBase GetCached(string id) { + AssetBase asset; if (m_cache != null) - return m_cache.Get(id); + m_cache.Get(id, out asset); return null; } @@ -169,7 +172,9 @@ namespace OpenSim.Services.Connectors.SimianGrid // Cache fetch if (m_cache != null) { - AssetBase asset = m_cache.Get(id); + AssetBase asset; + if (!m_cache.Get(id, out asset)) + return null; if (asset != null) return asset.Metadata; } @@ -212,7 +217,10 @@ namespace OpenSim.Services.Connectors.SimianGrid // Cache fetch if (m_cache != null) { - AssetBase asset = m_cache.Get(id); + AssetBase asset; + if (!m_cache.Get(id, out asset)) + return false; + if (asset != null) { handler(id, sender, asset); diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index 5a46201120..e18866598c 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -129,9 +129,9 @@ namespace OpenSim.Tests.Common item.AssetType = asset.Type; item.InvType = (int)itemType; item.BasePermissions = (uint)OpenMetaverse.PermissionMask.All | - (uint)(Framework.PermissionMask.foldedMask | Framework.PermissionMask.foldedCopy | Framework.PermissionMask.foldedModify | Framework.PermissionMask.foldedTransfer); + (uint)(Framework.PermissionMask.FoldedMask | Framework.PermissionMask.FoldedCopy | Framework.PermissionMask.FoldedModify | Framework.PermissionMask.FoldedTransfer); item.CurrentPermissions = (uint)OpenMetaverse.PermissionMask.All | - (uint)(Framework.PermissionMask.foldedMask | Framework.PermissionMask.foldedCopy | Framework.PermissionMask.foldedModify | Framework.PermissionMask.foldedTransfer); + (uint)(Framework.PermissionMask.FoldedMask | Framework.PermissionMask.FoldedCopy | Framework.PermissionMask.FoldedModify | Framework.PermissionMask.FoldedTransfer); InventoryFolderBase folder = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, path)[0]; @@ -371,4 +371,4 @@ namespace OpenSim.Tests.Common return InventoryArchiveUtils.FindItemsByPath(inventoryService, userId, path); } } -} \ No newline at end of file +} diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index e2f57b531b..a8359255ad 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -760,7 +760,11 @@ namespace OpenSim.Tests.Common { } - public void SendAvatarDataImmediate(ISceneEntity avatar) + public void SendEntityFullUpdateImmediate(ISceneEntity ent) + { + } + + public void SendEntityTerseUpdateImmediate(ISceneEntity ent) { } diff --git a/bin/Newtonsoft.Json.dll b/bin/Newtonsoft.Json.dll new file mode 100644 index 0000000000..5931de1693 Binary files /dev/null and b/bin/Newtonsoft.Json.dll differ diff --git a/bin/Newtonsoft.Json.xml b/bin/Newtonsoft.Json.xml new file mode 100644 index 0000000000..2a75b4481a --- /dev/null +++ b/bin/Newtonsoft.Json.xml @@ -0,0 +1,8626 @@ + + + + Newtonsoft.Json + + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Initializes a new instance of the class with the specified . + + + + + Reads the next JSON token from the stream. + + true if the next token was read successfully; false if there are no more tokens to read. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A or a null reference if the next JSON token is null. This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Skips the children of the current token. + + + + + Sets the current token. + + The new token. + + + + Sets the current token and value. + + The new token. + The value. + + + + Sets the state based on current token type. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Releases unmanaged and - optionally - managed resources + + true to release both managed and unmanaged resources; false to release only unmanaged resources. + + + + Changes the to Closed. + + + + + Gets the current reader state. + + The current reader state. + + + + Gets or sets a value indicating whether the underlying stream or + should be closed when the reader is closed. + + + true to close the underlying stream or when + the reader is closed; otherwise false. The default is true. + + + + + Gets or sets a value indicating whether multiple pieces of JSON content can + be read from a continuous stream without erroring. + + + true to support reading multiple pieces of JSON content; otherwise false. The default is false. + + + + + Gets the quotation mark character used to enclose the value of a string. + + + + + Get or set how time zones are handling when reading JSON. + + + + + Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + + + + + Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + + + + + Get or set how custom date formatted strings are parsed when reading JSON. + + + + + Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + + + + + Gets the type of the current JSON token. + + + + + Gets the text value of the current JSON token. + + + + + Gets The Common Language Runtime (CLR) type for the current JSON token. + + + + + Gets the depth of the current token in the JSON document. + + The depth of the current token in the JSON document. + + + + Gets the path of the current JSON token. + + + + + Gets or sets the culture used when reading JSON. Defaults to . + + + + + Specifies the state of the reader. + + + + + The Read method has not been called. + + + + + The end of the file has been reached successfully. + + + + + Reader is at a property. + + + + + Reader is at the start of an object. + + + + + Reader is in an object. + + + + + Reader is at the start of an array. + + + + + Reader is in an array. + + + + + The Close method has been called. + + + + + Reader has just read a value. + + + + + Reader is at the start of a constructor. + + + + + Reader in a constructor. + + + + + An error occurred that prevents the read operation from continuing. + + + + + The end of the file has been reached successfully. + + + + + Initializes a new instance of the class. + + The stream. + + + + Initializes a new instance of the class. + + The reader. + + + + Initializes a new instance of the class. + + The stream. + if set to true the root object will be read as a JSON array. + The used when reading values from BSON. + + + + Initializes a new instance of the class. + + The reader. + if set to true the root object will be read as a JSON array. + The used when reading values from BSON. + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. This method will return null at the end of an array. + + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + + A . This method will return null at the end of an array. + + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Changes the to Closed. + + + + + Gets or sets a value indicating whether binary data reading should compatible with incorrect Json.NET 3.5 written binary. + + + true if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, false. + + + + + Gets or sets a value indicating whether the root object will be read as a JSON array. + + + true if the root object will be read as a JSON array; otherwise, false. + + + + + Gets or sets the used when reading values from BSON. + + The used when reading values from BSON. + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Creates an instance of the JsonWriter class. + + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the end of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the end of an array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the end constructor. + + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + A flag to indicate whether the text should be escaped when it is written as a JSON property name. + + + + Writes the end of the current Json object or array. + + + + + Writes the current token and its children. + + The to read the token from. + + + + Writes the current token. + + The to read the token from. + A flag indicating whether the current token's children should be written. + + + + Writes the specified end token. + + The end token to write. + + + + Writes indent characters. + + + + + Writes the JSON value delimiter. + + + + + Writes an indent space. + + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON without changing the writer's state. + + The raw JSON to write. + + + + Writes raw JSON where a value is expected and updates the writer's state. + + The raw JSON to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes out the given white space. + + The string of white space characters. + + + + Sets the state of the JsonWriter, + + The JsonToken being written. + The value being written. + + + + Gets or sets a value indicating whether the underlying stream or + should be closed when the writer is closed. + + + true to close the underlying stream or when + the writer is closed; otherwise false. The default is true. + + + + + Gets the top. + + The top. + + + + Gets the state of the writer. + + + + + Gets the path of the writer. + + + + + Indicates how JSON text output is formatted. + + + + + Get or set how dates are written to JSON text. + + + + + Get or set how time zones are handling when writing JSON text. + + + + + Get or set how strings are escaped when writing JSON text. + + + + + Get or set how special floating point numbers, e.g. , + and , + are written to JSON text. + + + + + Get or set how and values are formatting when writing JSON text. + + + + + Gets or sets the culture used when writing JSON. Defaults to . + + + + + Initializes a new instance of the class. + + The stream. + + + + Initializes a new instance of the class. + + The writer. + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Writes the end. + + The token. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes raw JSON where a value is expected and updates the writer's state. + + The raw JSON to write. + + + + Writes the beginning of a Json array. + + + + + Writes the beginning of a Json object. + + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Closes this stream and the underlying stream. + + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value that represents a BSON object id. + + The Object ID value to write. + + + + Writes a BSON regex. + + The regex pattern. + The regex options. + + + + Gets or sets the used when writing values to BSON. + When set to no conversion will occur. + + The used when writing values to BSON. + + + + Represents a BSON Oid (object id). + + + + + Initializes a new instance of the class. + + The Oid value. + + + + Gets or sets the value of the Oid. + + The value of the Oid. + + + + Converts a binary value to and from a base 64 string value. + + + + + Converts an object to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Gets the of the JSON produced by the JsonConverter. + + The of the JSON produced by the JsonConverter. + + + + Gets a value indicating whether this can read JSON. + + true if this can read JSON; otherwise, false. + + + + Gets a value indicating whether this can write JSON. + + true if this can write JSON; otherwise, false. + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Create a custom object + + The object type to convert. + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Creates an object which will then be populated by the serializer. + + Type of the object. + The created object. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Gets a value indicating whether this can write JSON. + + + true if this can write JSON; otherwise, false. + + + + + Provides a base class for converting a to and from JSON. + + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a F# discriminated union type to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts an Entity Framework EntityKey to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts an ExpandoObject to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Gets a value indicating whether this can write JSON. + + + true if this can write JSON; otherwise, false. + + + + + Converts a to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from JSON and BSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts a to and from JSON and BSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Converts an to and from its name string value. + + + + + Initializes a new instance of the class. + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Gets or sets a value indicating whether the written enum text should be camel case. + + true if the written enum text will be camel case; otherwise, false. + + + + Gets or sets a value indicating whether integer values are allowed. + + true if integers are allowed; otherwise, false. + + + + Specifies how constructors are used when initializing objects during deserialization by the . + + + + + First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor. + + + + + Json.NET will use a non-public default constructor before falling back to a paramatized constructor. + + + + + Converts a to and from a string (e.g. "1.2.3.4"). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing property value of the JSON that is being converted. + The calling serializer. + The object value. + + + + Determines whether this instance can convert the specified object type. + + Type of the object. + + true if this instance can convert the specified object type; otherwise, false. + + + + + Specifies float format handling options when writing special floating point numbers, e.g. , + and with . + + + + + Write special floating point values as strings in JSON, e.g. "NaN", "Infinity", "-Infinity". + + + + + Write special floating point values as symbols in JSON, e.g. NaN, Infinity, -Infinity. + Note that this will produce non-valid JSON. + + + + + Write special floating point values as the property's default value in JSON, e.g. 0.0 for a property, null for a property. + + + + + Specifies how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + + + + + Floating point numbers are parsed to . + + + + + Floating point numbers are parsed to . + + + + + Instructs the how to serialize the collection. + + + + + Instructs the how to serialize the object. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets the id. + + The id. + + + + Gets or sets the title. + + The title. + + + + Gets or sets the description. + + The description. + + + + Gets the collection's items converter. + + The collection's items converter. + + + + The parameter list to use when constructing the JsonConverter described by ItemConverterType. + If null, the default constructor is used. + When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number, + order, and type of these parameters. + + + [JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })] + + + + + Gets or sets a value that indicates whether to preserve object references. + + + true to keep object reference; otherwise, false. The default is false. + + + + + Gets or sets a value that indicates whether to preserve collection's items references. + + + true to keep collection's items object references; otherwise, false. The default is false. + + + + + Gets or sets the reference loop handling used when serializing the collection's items. + + The reference loop handling. + + + + Gets or sets the type name handling used when serializing the collection's items. + + The type name handling. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + The exception thrown when an error occurs during Json serialization or deserialization. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + Specifies how dates are formatted when writing JSON text. + + + + + Dates are written in the ISO 8601 format, e.g. "2012-03-21T05:40Z". + + + + + Dates are written in the Microsoft JSON format, e.g. "\/Date(1198908717056)\/". + + + + + Specifies how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON text. + + + + + Date formatted strings are not parsed to a date type and are read as strings. + + + + + Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . + + + + + Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . + + + + + Specifies how to treat the time value when converting between string and . + + + + + Treat as local time. If the object represents a Coordinated Universal Time (UTC), it is converted to the local time. + + + + + Treat as a UTC. If the object represents a local time, it is converted to a UTC. + + + + + Treat as a local time if a is being converted to a string. + If a string is being converted to , convert to a local time if a time zone is specified. + + + + + Time zone information should be preserved when converting. + + + + + Specifies formatting options for the . + + + + + No special formatting is applied. This is the default. + + + + + Causes child objects to be indented according to the and settings. + + + + + Instructs the to use the specified constructor when deserializing that object. + + + + + Instructs the to deserialize properties with no matching class member into the specified collection + and write values during serialization. + + + + + Initializes a new instance of the class. + + + + + Gets or sets a value that indicates whether to write extension data when serializing the object. + + + true to write extension data when serializing the object; otherwise, false. The default is true. + + + + + Gets or sets a value that indicates whether to read extension data when deserializing the object. + + + true to read extension data when deserializing the object; otherwise, false. The default is true. + + + + + Specifies the settings used when merging JSON. + + + + + Gets or sets the method used when merging JSON arrays. + + The method used when merging JSON arrays. + + + + Specifies how JSON arrays are merged together. + + + + Concatenate arrays. + + + Union arrays, skipping items that already exist. + + + Replace all array items. + + + Merge array items together, matched by index. + + + + Specifies metadata property handling options for the . + + + + + Read metadata properties located at the start of a JSON object. + + + + + Read metadata properties located anywhere in a JSON object. Note that this setting will impact performance. + + + + + Do not try to read metadata properties. + + + + + Represents a trace writer that writes to the application's instances. + + + + + Represents a trace writer. + + + + + Writes the specified trace level, message and optional exception. + + The at which to write this trace. + The trace message. + The trace exception. This parameter is optional. + + + + Gets the that will be used to filter the trace messages passed to the writer. + For example a filter level of Info will exclude Verbose messages and include Info, + Warning and Error messages. + + The that will be used to filter the trace messages passed to the writer. + + + + Writes the specified trace level, message and optional exception. + + The at which to write this trace. + The trace message. + The trace exception. This parameter is optional. + + + + Gets the that will be used to filter the trace messages passed to the writer. + For example a filter level of Info will exclude Verbose messages and include Info, + Warning and Error messages. + + + The that will be used to filter the trace messages passed to the writer. + + + + + Get and set values for a using dynamic methods. + + + + + Provides methods to get and set values. + + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Contract details for a used by the . + + + + + Contract details for a used by the . + + + + + Gets the underlying type for the contract. + + The underlying type for the contract. + + + + Gets or sets the type created during deserialization. + + The type created during deserialization. + + + + Gets or sets whether this type contract is serialized as a reference. + + Whether this type contract is serialized as a reference. + + + + Gets or sets the default for this contract. + + The converter. + + + + Gets or sets all methods called immediately after deserialization of the object. + + The methods called immediately after deserialization of the object. + + + + Gets or sets all methods called during deserialization of the object. + + The methods called during deserialization of the object. + + + + Gets or sets all methods called after serialization of the object graph. + + The methods called after serialization of the object graph. + + + + Gets or sets all methods called before serialization of the object. + + The methods called before serialization of the object. + + + + Gets or sets all method called when an error is thrown during the serialization of the object. + + The methods called when an error is thrown during the serialization of the object. + + + + Gets or sets the method called immediately after deserialization of the object. + + The method called immediately after deserialization of the object. + + + + Gets or sets the method called during deserialization of the object. + + The method called during deserialization of the object. + + + + Gets or sets the method called after serialization of the object graph. + + The method called after serialization of the object graph. + + + + Gets or sets the method called before serialization of the object. + + The method called before serialization of the object. + + + + Gets or sets the method called when an error is thrown during the serialization of the object. + + The method called when an error is thrown during the serialization of the object. + + + + Gets or sets the default creator method used to create the object. + + The default creator method used to create the object. + + + + Gets or sets a value indicating whether the default creator is non public. + + true if the default object creator is non-public; otherwise, false. + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Gets or sets the default collection items . + + The converter. + + + + Gets or sets a value indicating whether the collection items preserve object references. + + true if collection items preserve object references; otherwise, false. + + + + Gets or sets the collection item reference loop handling. + + The reference loop handling. + + + + Gets or sets the collection item type name handling. + + The type name handling. + + + + Represents a trace writer that writes to memory. When the trace message limit is + reached then old trace messages will be removed as new messages are added. + + + + + Initializes a new instance of the class. + + + + + Writes the specified trace level, message and optional exception. + + The at which to write this trace. + The trace message. + The trace exception. This parameter is optional. + + + + Returns an enumeration of the most recent trace messages. + + An enumeration of the most recent trace messages. + + + + Returns a of the most recent trace messages. + + + A of the most recent trace messages. + + + + + Gets the that will be used to filter the trace messages passed to the writer. + For example a filter level of Info will exclude Verbose messages and include Info, + Warning and Error messages. + + + The that will be used to filter the trace messages passed to the writer. + + + + + Provides an interface to enable a class to return line and position information. + + + + + Gets a value indicating whether the class can return line information. + + + true if LineNumber and LinePosition can be provided; otherwise, false. + + + + + Gets the current line number. + + The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + + + + Gets the current line position. + + The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + + + + Specifies how strings are escaped when writing JSON text. + + + + + Only control characters (e.g. newline) are escaped. + + + + + All non-ASCII and control characters (e.g. newline) are escaped. + + + + + HTML (<, >, &, ', ") and control characters (e.g. newline) are escaped. + + + + + Represents a raw JSON string. + + + + + Represents a value in JSON (string, integer, date, etc). + + + + + Represents an abstract JSON token. + + + + + Represents a collection of objects. + + The type of token + + + + Gets the with the specified key. + + + + + + Compares the values of two tokens, including the values of all descendant tokens. + + The first to compare. + The second to compare. + true if the tokens are equal; otherwise false. + + + + Adds the specified content immediately after this token. + + A content object that contains simple content or a collection of content objects to be added after this token. + + + + Adds the specified content immediately before this token. + + A content object that contains simple content or a collection of content objects to be added before this token. + + + + Returns a collection of the ancestor tokens of this token. + + A collection of the ancestor tokens of this token. + + + + Returns a collection of the sibling tokens after this token, in document order. + + A collection of the sibling tokens after this tokens, in document order. + + + + Returns a collection of the sibling tokens before this token, in document order. + + A collection of the sibling tokens before this token, in document order. + + + + Gets the with the specified key converted to the specified type. + + The type to convert the token to. + The token key. + The converted token value. + + + + Returns a collection of the child tokens of this token, in document order. + + An of containing the child tokens of this , in document order. + + + + Returns a collection of the child tokens of this token, in document order, filtered by the specified type. + + The type to filter the child tokens on. + A containing the child tokens of this , in document order. + + + + Returns a collection of the child values of this token, in document order. + + The type to convert the values to. + A containing the child values of this , in document order. + + + + Removes this token from its parent. + + + + + Replaces this token with the specified token. + + The value. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Returns the indented JSON for this token. + + + The indented JSON for this token. + + + + + Returns the JSON for this token using the given formatting and converters. + + Indicates how the output is formatted. + A collection of which will be used when writing the token. + The JSON for this token using the given formatting and converters. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an explicit conversion from to . + + The value. + The result of the conversion. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Performs an implicit conversion from to . + + The value to create a from. + The initialized with the specified value. + + + + Creates an for this token. + + An that can be used to read this token and its descendants. + + + + Creates a from an object. + + The object that will be used to create . + A with the value of the specified object + + + + Creates a from an object using the specified . + + The object that will be used to create . + The that will be used when reading the object. + A with the value of the specified object + + + + Creates the specified .NET type from the . + + The object type that the token will be deserialized to. + The new object created from the JSON value. + + + + Creates the specified .NET type from the . + + The object type that the token will be deserialized to. + The new object created from the JSON value. + + + + Creates the specified .NET type from the using the specified . + + The object type that the token will be deserialized to. + The that will be used when creating the object. + The new object created from the JSON value. + + + + Creates the specified .NET type from the using the specified . + + The object type that the token will be deserialized to. + The that will be used when creating the object. + The new object created from the JSON value. + + + + Creates a from a . + + An positioned at the token to read into this . + + An that contains the token and its descendant tokens + that were read from the reader. The runtime type of the token is determined + by the token type of the first token encountered in the reader. + + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Creates a from a . + + An positioned at the token to read into this . + + An that contains the token and its descendant tokens + that were read from the reader. The runtime type of the token is determined + by the token type of the first token encountered in the reader. + + + + + Selects a using a JPath expression. Selects the token that matches the object path. + + + A that contains a JPath expression. + + A , or null. + + + + Selects a using a JPath expression. Selects the token that matches the object path. + + + A that contains a JPath expression. + + A flag to indicate whether an error should be thrown if no tokens are found when evaluating part of the expression. + A . + + + + Selects a collection of elements using a JPath expression. + + + A that contains a JPath expression. + + An that contains the selected elements. + + + + Selects a collection of elements using a JPath expression. + + + A that contains a JPath expression. + + A flag to indicate whether an error should be thrown if no tokens are found when evaluating part of the expression. + An that contains the selected elements. + + + + Returns the responsible for binding operations performed on this object. + + The expression tree representation of the runtime value. + + The to bind this object. + + + + + Returns the responsible for binding operations performed on this object. + + The expression tree representation of the runtime value. + + The to bind this object. + + + + + Creates a new instance of the . All child tokens are recursively cloned. + + A new instance of the . + + + + Gets a comparer that can compare two tokens for value equality. + + A that can compare two nodes for value equality. + + + + Gets or sets the parent. + + The parent. + + + + Gets the root of this . + + The root of this . + + + + Gets the node type for this . + + The type. + + + + Gets a value indicating whether this token has child tokens. + + + true if this token has child values; otherwise, false. + + + + + Gets the next sibling token of this node. + + The that contains the next sibling token. + + + + Gets the previous sibling token of this node. + + The that contains the previous sibling token. + + + + Gets the path of the JSON token. + + + + + Gets the with the specified key. + + The with the specified key. + + + + Get the first child token of this token. + + A containing the first child token of the . + + + + Get the last child token of this token. + + A containing the last child token of the . + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Initializes a new instance of the class with the given value. + + The value. + + + + Creates a comment with the given value. + + The value. + A comment with the given value. + + + + Creates a string with the given value. + + The value. + A string with the given value. + + + + Creates a null value. + + A null value. + + + + Creates a null value. + + A null value. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Indicates whether the current object is equal to another object of the same type. + + + true if the current object is equal to the parameter; otherwise, false. + + An object to compare with this object. + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Returns a that represents this instance. + + The format. + + A that represents this instance. + + + + + Returns a that represents this instance. + + The format provider. + + A that represents this instance. + + + + + Returns a that represents this instance. + + The format. + The format provider. + + A that represents this instance. + + + + + Returns the responsible for binding operations performed on this object. + + The expression tree representation of the runtime value. + + The to bind this object. + + + + + Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. + + An object to compare with this instance. + + A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: + Value + Meaning + Less than zero + This instance is less than . + Zero + This instance is equal to . + Greater than zero + This instance is greater than . + + + is not the same type as this instance. + + + + + Gets a value indicating whether this token has child tokens. + + + true if this token has child values; otherwise, false. + + + + + Gets the node type for this . + + The type. + + + + Gets or sets the underlying token value. + + The underlying token value. + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class. + + The raw json. + + + + Creates an instance of with the content of the reader's current token. + + The reader. + An instance of with the content of the reader's current token. + + + + Indicating whether a property is required. + + + + + The property is not required. The default state. + + + + + The property must be defined in JSON but can be a null value. + + + + + The property must be defined in JSON and cannot be a null value. + + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Gets the object's properties. + + The object's properties. + + + + Gets or sets the property name resolver. + + The property name resolver. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Gets or sets the ISerializable object constructor. + + The ISerializable object constructor. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Get and set values for a using dynamic methods. + + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + Provides data for the Error event. + + + + + Initializes a new instance of the class. + + The current object. + The error context. + + + + Gets the current object the error event is being raised against. + + The current object the error event is being raised against. + + + + Gets the error context. + + The error context. + + + + Represents a view of a . + + + + + Initializes a new instance of the class. + + The name. + + + + When overridden in a derived class, returns whether resetting an object changes its value. + + + true if resetting the component changes its value; otherwise, false. + + The component to test for reset capability. + + + + + When overridden in a derived class, gets the current value of the property on a component. + + + The value of a property for a given component. + + The component with the property for which to retrieve the value. + + + + + When overridden in a derived class, resets the value for this property of the component to the default value. + + The component with the property value that is to be reset to the default value. + + + + + When overridden in a derived class, sets the value of the component to a different value. + + The component with the property value that is to be set. + The new value. + + + + + When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted. + + + true if the property should be persisted; otherwise, false. + + The component with the property to be examined for persistence. + + + + + When overridden in a derived class, gets the type of the component this property is bound to. + + + A that represents the type of component this property is bound to. When the or methods are invoked, the object specified might be an instance of this type. + + + + + When overridden in a derived class, gets a value indicating whether this property is read-only. + + + true if the property is read-only; otherwise, false. + + + + + When overridden in a derived class, gets the type of the property. + + + A that represents the type of the property. + + + + + Gets the hash code for the name of the member. + + + + The hash code for the name of the member. + + + + + Used to resolve references when serializing and deserializing JSON by the . + + + + + Resolves a reference to its object. + + The serialization context. + The reference to resolve. + The object that + + + + Gets the reference for the sepecified object. + + The serialization context. + The object to get a reference for. + The reference to the object. + + + + Determines whether the specified object is referenced. + + The serialization context. + The object to test for a reference. + + true if the specified object is referenced; otherwise, false. + + + + + Adds a reference to the specified object. + + The serialization context. + The reference. + The object to reference. + + + + Specifies reference handling options for the . + Note that references cannot be preserved when a value is set via a non-default constructor such as types that implement ISerializable. + + + + + + + + Do not preserve references when serializing types. + + + + + Preserve references when serializing into a JSON object structure. + + + + + Preserve references when serializing into a JSON array structure. + + + + + Preserve references when serializing. + + + + + Instructs the how to serialize the collection. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with a flag indicating whether the array can contain null items + + A flag indicating whether the array can contain null items. + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets a value indicating whether null items are allowed in the collection. + + true if null items are allowed in the collection; otherwise, false. + + + + Specifies default value handling options for the . + + + + + + + + + Include members where the member value is the same as the member's default value when serializing objects. + Included members are written to JSON. Has no effect when deserializing. + + + + + Ignore members where the member value is the same as the member's default value when serializing objects + so that is is not written to JSON. + This option will ignore all default values (e.g. null for objects and nullable types; 0 for integers, + decimals and floating point numbers; and false for booleans). The default value ignored can be changed by + placing the on the property. + + + + + Members with a default value but no JSON will be set to their default value when deserializing. + + + + + Ignore members where the member value is the same as the member's default value when serializing objects + and sets members to their default value when deserializing. + + + + + Instructs the to use the specified when serializing the member or class. + + + + + Initializes a new instance of the class. + + Type of the converter. + + + + Initializes a new instance of the class. + + Type of the converter. + Parameter list to use when constructing the JsonConverter. Can be null. + + + + Gets the type of the converter. + + The type of the converter. + + + + The parameter list to use when constructing the JsonConverter described by ConverterType. + If null, the default constructor is used. + + + + + Instructs the how to serialize the object. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified member serialization. + + The member serialization. + + + + Initializes a new instance of the class with the specified container Id. + + The container Id. + + + + Gets or sets the member serialization. + + The member serialization. + + + + Gets or sets a value that indicates whether the object's properties are required. + + + A value indicating whether the object's properties are required. + + + + + Specifies the settings on a object. + + + + + Initializes a new instance of the class. + + + + + Gets or sets how reference loops (e.g. a class referencing itself) is handled. + + Reference loop handling. + + + + Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + + Missing member handling. + + + + Gets or sets how objects are created during deserialization. + + The object creation handling. + + + + Gets or sets how null values are handled during serialization and deserialization. + + Null value handling. + + + + Gets or sets how null default are handled during serialization and deserialization. + + The default value handling. + + + + Gets or sets a collection that will be used during serialization. + + The converters. + + + + Gets or sets how object references are preserved by the serializer. + + The preserve references handling. + + + + Gets or sets how type name writing and reading is handled by the serializer. + + The type name handling. + + + + Gets or sets how metadata properties are used during deserialization. + + The metadata properties handling. + + + + Gets or sets how a type name assembly is written and resolved by the serializer. + + The type name assembly format. + + + + Gets or sets how constructors are used during deserialization. + + The constructor handling. + + + + Gets or sets the contract resolver used by the serializer when + serializing .NET objects to JSON and vice versa. + + The contract resolver. + + + + Gets or sets the used by the serializer when resolving references. + + The reference resolver. + + + + Gets or sets the used by the serializer when writing trace messages. + + The trace writer. + + + + Gets or sets the used by the serializer when resolving type names. + + The binder. + + + + Gets or sets the error handler called during serialization and deserialization. + + The error handler called during serialization and deserialization. + + + + Gets or sets the used by the serializer when invoking serialization callback methods. + + The context. + + + + Get or set how and values are formatting when writing JSON text. + + + + + Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + + + + + Indicates how JSON text output is formatted. + + + + + Get or set how dates are written to JSON text. + + + + + Get or set how time zones are handling during serialization and deserialization. + + + + + Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + + + + + Get or set how special floating point numbers, e.g. , + and , + are written as JSON. + + + + + Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + + + + + Get or set how strings are escaped when writing JSON text. + + + + + Gets or sets the culture used when reading JSON. Defaults to . + + + + + Gets a value indicating whether there will be a check for additional content after deserializing an object. + + + true if there will be a check for additional content after deserializing an object; otherwise, false. + + + + + Represents a reader that provides validation. + + + + + Initializes a new instance of the class that + validates the content returned from the given . + + The to read from while validating. + + + + Reads the next JSON token from the stream as a . + + A . + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. + + + + + Reads the next JSON token from the stream as a . + + A . + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Sets an event handler for receiving schema validation errors. + + + + + Gets the text value of the current JSON token. + + + + + + Gets the depth of the current token in the JSON document. + + The depth of the current token in the JSON document. + + + + Gets the path of the current JSON token. + + + + + Gets the quotation mark character used to enclose the value of a string. + + + + + + Gets the type of the current JSON token. + + + + + + Gets the Common Language Runtime (CLR) type for the current JSON token. + + + + + + Gets or sets the schema. + + The schema. + + + + Gets the used to construct this . + + The specified in the constructor. + + + + Compares tokens to determine whether they are equal. + + + + + Determines whether the specified objects are equal. + + The first object of type to compare. + The second object of type to compare. + + true if the specified objects are equal; otherwise, false. + + + + + Returns a hash code for the specified object. + + The for which a hash code is to be returned. + A hash code for the specified object. + The type of is a reference type and is null. + + + + Specifies the member serialization options for the . + + + + + All public members are serialized by default. Members can be excluded using or . + This is the default member serialization mode. + + + + + Only members must be marked with or are serialized. + This member serialization mode can also be set by marking the class with . + + + + + All public and private fields are serialized. Members can be excluded using or . + This member serialization mode can also be set by marking the class with + and setting IgnoreSerializableAttribute on to false. + + + + + Specifies how object creation is handled by the . + + + + + Reuse existing objects, create new objects when needed. + + + + + Only reuse existing objects. + + + + + Always create new objects. + + + + + Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Gets or sets the date time styles used when converting a date to and from JSON. + + The date time styles used when converting a date to and from JSON. + + + + Gets or sets the date time format used when converting a date to and from JSON. + + The date time format used when converting a date to and from JSON. + + + + Gets or sets the culture used when converting a date to and from JSON. + + The culture used when converting a date to and from JSON. + + + + Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). + + + + + Writes the JSON representation of the object. + + The to write to. + The value. + The calling serializer. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing property value of the JSON that is being converted. + The calling serializer. + The object value. + + + + Converts XML to and from JSON. + + + + + Writes the JSON representation of the object. + + The to write to. + The calling serializer. + The value. + + + + Reads the JSON representation of the object. + + The to read from. + Type of the object. + The existing value of object being read. + The calling serializer. + The object value. + + + + Checks if the attributeName is a namespace attribute. + + Attribute name to test. + The attribute name prefix if it has one, otherwise an empty string. + True if attribute name is for a namespace attribute, otherwise false. + + + + Determines whether this instance can convert the specified value type. + + Type of the value. + + true if this instance can convert the specified value type; otherwise, false. + + + + + Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements. + + The name of the deserialize root element. + + + + Gets or sets a flag to indicate whether to write the Json.NET array attribute. + This attribute helps preserve arrays when converting the written XML back to JSON. + + true if the array attibute is written to the XML; otherwise, false. + + + + Gets or sets a value indicating whether to write the root JSON object. + + true if the JSON root object is omitted; otherwise, false. + + + + Represents a reader that provides fast, non-cached, forward-only access to JSON text data. + + + + + Initializes a new instance of the class with the specified . + + The TextReader containing the XML data to read. + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. This method will return null at the end of an array. + + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Changes the state to closed. + + + + + Gets a value indicating whether the class can return line information. + + + true if LineNumber and LinePosition can be provided; otherwise, false. + + + + + Gets the current line number. + + + The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + + + + + Gets the current line position. + + + The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + + + + + Instructs the to always serialize the member with the specified name. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified name. + + Name of the property. + + + + Gets or sets the converter used when serializing the property's collection items. + + The collection's items converter. + + + + The parameter list to use when constructing the JsonConverter described by ItemConverterType. + If null, the default constructor is used. + When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number, + order, and type of these parameters. + + + [JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })] + + + + + Gets or sets the null value handling used when serializing this property. + + The null value handling. + + + + Gets or sets the default value handling used when serializing this property. + + The default value handling. + + + + Gets or sets the reference loop handling used when serializing this property. + + The reference loop handling. + + + + Gets or sets the object creation handling used when deserializing this property. + + The object creation handling. + + + + Gets or sets the type name handling used when serializing this property. + + The type name handling. + + + + Gets or sets whether this property's value is serialized as a reference. + + Whether this property's value is serialized as a reference. + + + + Gets or sets the order of serialization and deserialization of a member. + + The numeric order of serialization or deserialization. + + + + Gets or sets a value indicating whether this property is required. + + + A value indicating whether this property is required. + + + + + Gets or sets the name of the property. + + The name of the property. + + + + Gets or sets the the reference loop handling used when serializing the property's collection items. + + The collection's items reference loop handling. + + + + Gets or sets the the type name handling used when serializing the property's collection items. + + The collection's items type name handling. + + + + Gets or sets whether this property's collection items are serialized as a reference. + + Whether this property's collection items are serialized as a reference. + + + + Instructs the not to serialize the public field or public read/write property value. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Creates an instance of the JsonWriter class using the specified . + + The TextWriter to write to. + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the specified end token. + + The end token to write. + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Writes the property name of a name/value pair on a JSON object. + + The name of the property. + A flag to indicate whether the text should be escaped when it is written as a JSON property name. + + + + Writes indent characters. + + + + + Writes the JSON value delimiter. + + + + + Writes an indent space. + + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes out the given white space. + + The string of white space characters. + + + + Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. + + + + + Gets or sets which character to use to quote attribute values. + + + + + Gets or sets which character to use for indenting when is set to Formatting.Indented. + + + + + Gets or sets a value indicating whether object names will be surrounded with quotes. + + + + + The exception thrown when an error occurs while reading Json text. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + Gets the path to the JSON where the error occurred. + + The path to the JSON where the error occurred. + + + + The exception thrown when an error occurs while reading Json text. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + Gets the line number indicating where the error occurred. + + The line number indicating where the error occurred. + + + + Gets the line position indicating where the error occurred. + + The line position indicating where the error occurred. + + + + Gets the path to the JSON where the error occurred. + + The path to the JSON where the error occurred. + + + + Represents a collection of . + + + + + Provides methods for converting between common language runtime types and JSON types. + + + + + + + + Represents JavaScript's boolean value true as a string. This field is read-only. + + + + + Represents JavaScript's boolean value false as a string. This field is read-only. + + + + + Represents JavaScript's null as a string. This field is read-only. + + + + + Represents JavaScript's undefined as a string. This field is read-only. + + + + + Represents JavaScript's positive infinity as a string. This field is read-only. + + + + + Represents JavaScript's negative infinity as a string. This field is read-only. + + + + + Represents JavaScript's NaN as a string. This field is read-only. + + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation using the specified. + + The value to convert. + The format the date will be converted to. + The time zone handling when the date is converted to a string. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation using the specified. + + The value to convert. + The format the date will be converted to. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + The string delimiter character. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + The string delimiter character. + The string escape handling. + A JSON string representation of the . + + + + Converts the to its JSON string representation. + + The value to convert. + A JSON string representation of the . + + + + Serializes the specified object to a JSON string. + + The object to serialize. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using formatting. + + The object to serialize. + Indicates how the output is formatted. + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using a collection of . + + The object to serialize. + A collection converters used while serializing. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using formatting and a collection of . + + The object to serialize. + Indicates how the output is formatted. + A collection converters used while serializing. + A JSON string representation of the object. + + + + Serializes the specified object to a JSON string using . + + The object to serialize. + The used to serialize the object. + If this is null, default serialization settings will be used. + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using a type, formatting and . + + The object to serialize. + The used to serialize the object. + If this is null, default serialization settings will be used. + + The type of the value being serialized. + This parameter is used when is Auto to write out the type name if the type of the value does not match. + Specifing the type is optional. + + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using formatting and . + + The object to serialize. + Indicates how the output is formatted. + The used to serialize the object. + If this is null, default serialization settings will be used. + + A JSON string representation of the object. + + + + + Serializes the specified object to a JSON string using a type, formatting and . + + The object to serialize. + Indicates how the output is formatted. + The used to serialize the object. + If this is null, default serialization settings will be used. + + The type of the value being serialized. + This parameter is used when is Auto to write out the type name if the type of the value does not match. + Specifing the type is optional. + + + A JSON string representation of the object. + + + + + Asynchronously serializes the specified object to a JSON string. + Serialization will happen on a new thread. + + The object to serialize. + + A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + + + + + Asynchronously serializes the specified object to a JSON string using formatting. + Serialization will happen on a new thread. + + The object to serialize. + Indicates how the output is formatted. + + A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + + + + + Asynchronously serializes the specified object to a JSON string using formatting and a collection of . + Serialization will happen on a new thread. + + The object to serialize. + Indicates how the output is formatted. + The used to serialize the object. + If this is null, default serialization settings will be used. + + A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + + + + + Deserializes the JSON to a .NET object. + + The JSON to deserialize. + The deserialized object from the JSON string. + + + + Deserializes the JSON to a .NET object using . + + The JSON to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type. + + The JSON to deserialize. + The of object being deserialized. + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type. + + The type of the object to deserialize to. + The JSON to deserialize. + The deserialized object from the JSON string. + + + + Deserializes the JSON to the given anonymous type. + + + The anonymous type to deserialize to. This can't be specified + traditionally and must be infered from the anonymous type passed + as a parameter. + + The JSON to deserialize. + The anonymous type object. + The deserialized anonymous type from the JSON string. + + + + Deserializes the JSON to the given anonymous type using . + + + The anonymous type to deserialize to. This can't be specified + traditionally and must be infered from the anonymous type passed + as a parameter. + + The JSON to deserialize. + The anonymous type object. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + The deserialized anonymous type from the JSON string. + + + + Deserializes the JSON to the specified .NET type using a collection of . + + The type of the object to deserialize to. + The JSON to deserialize. + Converters to use while deserializing. + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type using . + + The type of the object to deserialize to. + The object to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type using a collection of . + + The JSON to deserialize. + The type of the object to deserialize. + Converters to use while deserializing. + The deserialized object from the JSON string. + + + + Deserializes the JSON to the specified .NET type using . + + The JSON to deserialize. + The type of the object to deserialize to. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + The deserialized object from the JSON string. + + + + Asynchronously deserializes the JSON to the specified .NET type. + Deserialization will happen on a new thread. + + The type of the object to deserialize to. + The JSON to deserialize. + + A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + + + + + Asynchronously deserializes the JSON to the specified .NET type using . + Deserialization will happen on a new thread. + + The type of the object to deserialize to. + The JSON to deserialize. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + + A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + + + + + Asynchronously deserializes the JSON to the specified .NET type. + Deserialization will happen on a new thread. + + The JSON to deserialize. + + A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + + + + + Asynchronously deserializes the JSON to the specified .NET type using . + Deserialization will happen on a new thread. + + The JSON to deserialize. + The type of the object to deserialize to. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + + A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + + + + + Populates the object with values from the JSON string. + + The JSON to populate values from. + The target object to populate values onto. + + + + Populates the object with values from the JSON string using . + + The JSON to populate values from. + The target object to populate values onto. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + + + + Asynchronously populates the object with values from the JSON string using . + + The JSON to populate values from. + The target object to populate values onto. + + The used to deserialize the object. + If this is null, default serialization settings will be used. + + + A task that represents the asynchronous populate operation. + + + + + Serializes the XML node to a JSON string. + + The node to serialize. + A JSON string of the XmlNode. + + + + Serializes the XML node to a JSON string using formatting. + + The node to serialize. + Indicates how the output is formatted. + A JSON string of the XmlNode. + + + + Serializes the XML node to a JSON string using formatting and omits the root object if is true. + + The node to serialize. + Indicates how the output is formatted. + Omits writing the root object. + A JSON string of the XmlNode. + + + + Deserializes the XmlNode from a JSON string. + + The JSON string. + The deserialized XmlNode + + + + Deserializes the XmlNode from a JSON string nested in a root elment specified by . + + The JSON string. + The name of the root element to append when deserializing. + The deserialized XmlNode + + + + Deserializes the XmlNode from a JSON string nested in a root elment specified by + and writes a .NET array attribute for collections. + + The JSON string. + The name of the root element to append when deserializing. + + A flag to indicate whether to write the Json.NET array attribute. + This attribute helps preserve arrays when converting the written XML back to JSON. + + The deserialized XmlNode + + + + Serializes the to a JSON string. + + The node to convert to JSON. + A JSON string of the XNode. + + + + Serializes the to a JSON string using formatting. + + The node to convert to JSON. + Indicates how the output is formatted. + A JSON string of the XNode. + + + + Serializes the to a JSON string using formatting and omits the root object if is true. + + The node to serialize. + Indicates how the output is formatted. + Omits writing the root object. + A JSON string of the XNode. + + + + Deserializes the from a JSON string. + + The JSON string. + The deserialized XNode + + + + Deserializes the from a JSON string nested in a root elment specified by . + + The JSON string. + The name of the root element to append when deserializing. + The deserialized XNode + + + + Deserializes the from a JSON string nested in a root elment specified by + and writes a .NET array attribute for collections. + + The JSON string. + The name of the root element to append when deserializing. + + A flag to indicate whether to write the Json.NET array attribute. + This attribute helps preserve arrays when converting the written XML back to JSON. + + The deserialized XNode + + + + Gets or sets a function that creates default . + Default settings are automatically used by serialization methods on , + and and on . + To serialize without using any default settings create a with + . + + + + + The exception thrown when an error occurs during Json serialization or deserialization. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + Serializes and deserializes objects into and from the JSON format. + The enables you to control how objects are encoded into JSON. + + + + + Initializes a new instance of the class. + + + + + Creates a new instance. + The will not use default settings. + + + A new instance. + The will not use default settings. + + + + + Creates a new instance using the specified . + The will not use default settings. + + The settings to be applied to the . + + A new instance using the specified . + The will not use default settings. + + + + + Creates a new instance. + The will use default settings. + + + A new instance. + The will use default settings. + + + + + Creates a new instance using the specified . + The will use default settings. + + The settings to be applied to the . + + A new instance using the specified . + The will use default settings. + + + + + Populates the JSON values onto the target object. + + The that contains the JSON structure to reader values from. + The target object to populate values onto. + + + + Populates the JSON values onto the target object. + + The that contains the JSON structure to reader values from. + The target object to populate values onto. + + + + Deserializes the Json structure contained by the specified . + + The that contains the JSON structure to deserialize. + The being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The of object being deserialized. + The instance of being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The type of the object to deserialize. + The instance of being deserialized. + + + + Deserializes the Json structure contained by the specified + into an instance of the specified type. + + The containing the object. + The of object being deserialized. + The instance of being deserialized. + + + + Serializes the specified and writes the Json structure + to a Stream using the specified . + + The used to write the Json structure. + The to serialize. + + + + Serializes the specified and writes the Json structure + to a Stream using the specified . + + The used to write the Json structure. + The to serialize. + + The type of the value being serialized. + This parameter is used when is Auto to write out the type name if the type of the value does not match. + Specifing the type is optional. + + + + + Serializes the specified and writes the Json structure + to a Stream using the specified . + + The used to write the Json structure. + The to serialize. + + The type of the value being serialized. + This parameter is used when is Auto to write out the type name if the type of the value does not match. + Specifing the type is optional. + + + + + Serializes the specified and writes the Json structure + to a Stream using the specified . + + The used to write the Json structure. + The to serialize. + + + + Occurs when the errors during serialization and deserialization. + + + + + Gets or sets the used by the serializer when resolving references. + + + + + Gets or sets the used by the serializer when resolving type names. + + + + + Gets or sets the used by the serializer when writing trace messages. + + The trace writer. + + + + Gets or sets how type name writing and reading is handled by the serializer. + + + + + Gets or sets how a type name assembly is written and resolved by the serializer. + + The type name assembly format. + + + + Gets or sets how object references are preserved by the serializer. + + + + + Get or set how reference loops (e.g. a class referencing itself) is handled. + + + + + Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + + + + + Get or set how null values are handled during serialization and deserialization. + + + + + Get or set how null default are handled during serialization and deserialization. + + + + + Gets or sets how objects are created during deserialization. + + The object creation handling. + + + + Gets or sets how constructors are used during deserialization. + + The constructor handling. + + + + Gets or sets how metadata properties are used during deserialization. + + The metadata properties handling. + + + + Gets a collection that will be used during serialization. + + Collection that will be used during serialization. + + + + Gets or sets the contract resolver used by the serializer when + serializing .NET objects to JSON and vice versa. + + + + + Gets or sets the used by the serializer when invoking serialization callback methods. + + The context. + + + + Indicates how JSON text output is formatted. + + + + + Get or set how dates are written to JSON text. + + + + + Get or set how time zones are handling during serialization and deserialization. + + + + + Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + + + + + Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + + + + + Get or set how special floating point numbers, e.g. , + and , + are written as JSON text. + + + + + Get or set how strings are escaped when writing JSON text. + + + + + Get or set how and values are formatting when writing JSON text. + + + + + Gets or sets the culture used when reading JSON. Defaults to . + + + + + Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + + + + + Gets a value indicating whether there will be a check for additional JSON content after deserializing an object. + + + true if there will be a check for additional JSON content after deserializing an object; otherwise, false. + + + + + Contains the LINQ to JSON extension methods. + + + + + Returns a collection of tokens that contains the ancestors of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains the ancestors of every node in the source collection. + + + + Returns a collection of tokens that contains the descendants of every token in the source collection. + + The type of the objects in source, constrained to . + An of that contains the source collection. + An of that contains the descendants of every node in the source collection. + + + + Returns a collection of child properties of every object in the source collection. + + An of that contains the source collection. + An of that contains the properties of every object in the source collection. + + + + Returns a collection of child values of every object in the source collection with the given key. + + An of that contains the source collection. + The token key. + An of that contains the values of every node in the source collection with the given key. + + + + Returns a collection of child values of every object in the source collection. + + An of that contains the source collection. + An of that contains the values of every node in the source collection. + + + + Returns a collection of converted child values of every object in the source collection with the given key. + + The type to convert the values to. + An of that contains the source collection. + The token key. + An that contains the converted values of every node in the source collection with the given key. + + + + Returns a collection of converted child values of every object in the source collection. + + The type to convert the values to. + An of that contains the source collection. + An that contains the converted values of every node in the source collection. + + + + Converts the value. + + The type to convert the value to. + A cast as a of . + A converted value. + + + + Converts the value. + + The source collection type. + The type to convert the value to. + A cast as a of . + A converted value. + + + + Returns a collection of child tokens of every array in the source collection. + + The source collection type. + An of that contains the source collection. + An of that contains the values of every node in the source collection. + + + + Returns a collection of converted child tokens of every array in the source collection. + + An of that contains the source collection. + The type to convert the values to. + The source collection type. + An that contains the converted values of every node in the source collection. + + + + Returns the input typed as . + + An of that contains the source collection. + The input typed as . + + + + Returns the input typed as . + + The source collection type. + An of that contains the source collection. + The input typed as . + + + + Represents a JSON constructor. + + + + + Represents a token that can contain other tokens. + + + + + Raises the event. + + The instance containing the event data. + + + + Raises the event. + + The instance containing the event data. + + + + Raises the event. + + The instance containing the event data. + + + + Returns a collection of the child tokens of this token, in document order. + + + An of containing the child tokens of this , in document order. + + + + + Returns a collection of the child values of this token, in document order. + + The type to convert the values to. + + A containing the child values of this , in document order. + + + + + Returns a collection of the descendant tokens for this token in document order. + + An containing the descendant tokens of the . + + + + Adds the specified content as children of this . + + The content to be added. + + + + Adds the specified content as the first children of this . + + The content to be added. + + + + Creates an that can be used to add tokens to the . + + An that is ready to have content written to it. + + + + Replaces the children nodes of this token with the specified content. + + The content. + + + + Removes the child nodes from this token. + + + + + Merge the specified content into this . + + The content to be merged. + + + + Merge the specified content into this using . + + The content to be merged. + The used to merge the content. + + + + Occurs when the list changes or an item in the list changes. + + + + + Occurs before an item is added to the collection. + + + + + Occurs when the items list of the collection has changed, or the collection is reset. + + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Gets a value indicating whether this token has child tokens. + + + true if this token has child values; otherwise, false. + + + + + Get the first child token of this token. + + + A containing the first child token of the . + + + + + Get the last child token of this token. + + + A containing the last child token of the . + + + + + Gets the count of child JSON tokens. + + The count of child JSON tokens + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified name and content. + + The constructor name. + The contents of the constructor. + + + + Initializes a new instance of the class with the specified name and content. + + The constructor name. + The contents of the constructor. + + + + Initializes a new instance of the class with the specified name. + + The constructor name. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Gets or sets the name of this constructor. + + The constructor name. + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Represents a collection of objects. + + The type of token + + + + An empty collection of objects. + + + + + Initializes a new instance of the struct. + + The enumerable. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; otherwise, false. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + + + + + Gets the with the specified key. + + + + + + Represents a JSON object. + + + + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified content. + + The contents of the object. + + + + Initializes a new instance of the class with the specified content. + + The contents of the object. + + + + Gets an of this object's properties. + + An of this object's properties. + + + + Gets a the specified name. + + The property name. + A with the specified name or null. + + + + Gets an of this object's property values. + + An of this object's property values. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + + + + Creates a from an object. + + The object that will be used to create . + A with the values of the specified object + + + + Creates a from an object. + + The object that will be used to create . + The that will be used to read the object. + A with the values of the specified object + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Gets the with the specified property name. + + Name of the property. + The with the specified property name. + + + + Gets the with the specified property name. + The exact property name will be searched for first and if no matching property is found then + the will be used to match a property. + + Name of the property. + One of the enumeration values that specifies how the strings will be compared. + The with the specified property name. + + + + Tries to get the with the specified property name. + The exact property name will be searched for first and if no matching property is found then + the will be used to match a property. + + Name of the property. + The value. + One of the enumeration values that specifies how the strings will be compared. + true if a value was successfully retrieved; otherwise, false. + + + + Adds the specified property name. + + Name of the property. + The value. + + + + Removes the property with the specified name. + + Name of the property. + true if item was successfully removed; otherwise, false. + + + + Tries the get value. + + Name of the property. + The value. + true if a value was successfully retrieved; otherwise, false. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Raises the event with the provided arguments. + + Name of the property. + + + + Raises the event with the provided arguments. + + Name of the property. + + + + Returns the properties for this instance of a component. + + + A that represents the properties for this component instance. + + + + + Returns the properties for this instance of a component using the attribute array as a filter. + + An array of type that is used as a filter. + + A that represents the filtered properties for this component instance. + + + + + Returns a collection of custom attributes for this instance of a component. + + + An containing the attributes for this object. + + + + + Returns the class name of this instance of a component. + + + The class name of the object, or null if the class does not have a name. + + + + + Returns the name of this instance of a component. + + + The name of the object, or null if the object does not have a name. + + + + + Returns a type converter for this instance of a component. + + + A that is the converter for this object, or null if there is no for this object. + + + + + Returns the default event for this instance of a component. + + + An that represents the default event for this object, or null if this object does not have events. + + + + + Returns the default property for this instance of a component. + + + A that represents the default property for this object, or null if this object does not have properties. + + + + + Returns an editor of the specified type for this instance of a component. + + A that represents the editor for this object. + + An of the specified type that is the editor for this object, or null if the editor cannot be found. + + + + + Returns the events for this instance of a component using the specified attribute array as a filter. + + An array of type that is used as a filter. + + An that represents the filtered events for this component instance. + + + + + Returns the events for this instance of a component. + + + An that represents the events for this component instance. + + + + + Returns an object that contains the property described by the specified property descriptor. + + A that represents the property whose owner is to be found. + + An that represents the owner of the specified property. + + + + + Returns the responsible for binding operations performed on this object. + + The expression tree representation of the runtime value. + + The to bind this object. + + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Occurs when a property value changes. + + + + + Occurs when a property value is changing. + + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets or sets the with the specified property name. + + + + + + Represents a JSON array. + + + + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class with the specified content. + + The contents of the array. + + + + Initializes a new instance of the class with the specified content. + + The contents of the array. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Load a from a string that contains JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + + + + Creates a from an object. + + The object that will be used to create . + A with the values of the specified object + + + + Creates a from an object. + + The object that will be used to create . + The that will be used to read the object. + A with the values of the specified object + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Determines the index of a specific item in the . + + The object to locate in the . + + The index of if found in the list; otherwise, -1. + + + + + Inserts an item to the at the specified index. + + The zero-based index at which should be inserted. + The object to insert into the . + + is not a valid index in the . + The is read-only. + + + + Removes the item at the specified index. + + The zero-based index of the item to remove. + + is not a valid index in the . + The is read-only. + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Adds an item to the . + + The object to add to the . + The is read-only. + + + + Removes all items from the . + + The is read-only. + + + + Determines whether the contains a specific value. + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Copies to. + + The array. + Index of the array. + + + + Removes the first occurrence of a specific object from the . + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + The is read-only. + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Gets the node type for this . + + The type. + + + + Gets the with the specified key. + + The with the specified key. + + + + Gets or sets the at the specified index. + + + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. + + + + + Initializes a new instance of the class. + + The token to read from. + + + + Reads the next JSON token from the stream as a . + + + A or a null reference if the next JSON token is null. This method will return null at the end of an array. + + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream as a . + + A . This method will return null at the end of an array. + + + + Reads the next JSON token from the stream. + + + true if the next token was read successfully; false if there are no more tokens to read. + + + + + Gets the path of the current JSON token. + + + + + Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + + + + + Initializes a new instance of the class writing to the given . + + The container being written to. + + + + Initializes a new instance of the class. + + + + + Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + + + + + Closes this stream and the underlying stream. + + + + + Writes the beginning of a Json object. + + + + + Writes the beginning of a Json array. + + + + + Writes the start of a constructor with the given name. + + The name of the constructor. + + + + Writes the end. + + The token. + + + + Writes the property name of a name/value pair on a Json object. + + The name of the property. + + + + Writes a value. + An error will raised if the value cannot be written as a single JSON token. + + The value to write. + + + + Writes a null value. + + + + + Writes an undefined value. + + + + + Writes raw JSON. + + The raw JSON to write. + + + + Writes out a comment /*...*/ containing the specified text. + + Text to place inside the comment. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Writes a value. + + The value to write. + + + + Gets the token being writen. + + The token being writen. + + + + Represents a JSON property. + + + + + Initializes a new instance of the class from another object. + + A object to copy from. + + + + Initializes a new instance of the class. + + The property name. + The property content. + + + + Initializes a new instance of the class. + + The property name. + The property content. + + + + Writes this token to a . + + A into which this method will write. + A collection of which will be used when writing the token. + + + + Loads an from a . + + A that will be read for the content of the . + A that contains the JSON that was read from the specified . + + + + Gets the container's children tokens. + + The container's children tokens. + + + + Gets the property name. + + The property name. + + + + Gets or sets the property value. + + The property value. + + + + Gets the node type for this . + + The type. + + + + Specifies the type of token. + + + + + No token type has been set. + + + + + A JSON object. + + + + + A JSON array. + + + + + A JSON constructor. + + + + + A JSON object property. + + + + + A comment. + + + + + An integer value. + + + + + A float value. + + + + + A string value. + + + + + A boolean value. + + + + + A null value. + + + + + An undefined value. + + + + + A date value. + + + + + A raw JSON value. + + + + + A collection of bytes value. + + + + + A Guid value. + + + + + A Uri value. + + + + + A TimeSpan value. + + + + + Contains the JSON schema extension methods. + + + + + Determines whether the is valid. + + The source to test. + The schema to test with. + + true if the specified is valid; otherwise, false. + + + + + Determines whether the is valid. + + The source to test. + The schema to test with. + When this method returns, contains any error messages generated while validating. + + true if the specified is valid; otherwise, false. + + + + + Validates the specified . + + The source to test. + The schema to test with. + + + + Validates the specified . + + The source to test. + The schema to test with. + The validation event handler. + + + + Returns detailed information about the schema exception. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class + with a specified error message. + + The error message that explains the reason for the exception. + + + + Initializes a new instance of the class + with a specified error message and a reference to the inner exception that is the cause of this exception. + + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + + + + Initializes a new instance of the class. + + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + The parameter is null. + The class name is null or is zero (0). + + + + Gets the line number indicating where the error occurred. + + The line number indicating where the error occurred. + + + + Gets the line position indicating where the error occurred. + + The line position indicating where the error occurred. + + + + Gets the path to the JSON where the error occurred. + + The path to the JSON where the error occurred. + + + + Resolves from an id. + + + + + Initializes a new instance of the class. + + + + + Gets a for the specified reference. + + The id. + A for the specified reference. + + + + Gets or sets the loaded schemas. + + The loaded schemas. + + + + Specifies undefined schema Id handling options for the . + + + + + Do not infer a schema Id. + + + + + Use the .NET type name as the schema Id. + + + + + Use the assembly qualified .NET type name as the schema Id. + + + + + Returns detailed information related to the . + + + + + Gets the associated with the validation error. + + The JsonSchemaException associated with the validation error. + + + + Gets the path of the JSON location where the validation error occurred. + + The path of the JSON location where the validation error occurred. + + + + Gets the text description corresponding to the validation error. + + The text description. + + + + Represents the callback method that will handle JSON schema validation events and the . + + + + + Resolves member mappings for a type, camel casing property names. + + + + + Used by to resolves a for a given . + + + + + Used by to resolves a for a given . + + + + + + + + + Resolves the contract for a given type. + + The type to resolve a contract for. + The contract for a given type. + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + + If set to true the will use a cached shared with other resolvers of the same type. + Sharing the cache will significantly improve performance with multiple resolver instances because expensive reflection will only + happen once. This setting can cause unexpected behavior if different instances of the resolver are suppose to produce different + results. When set to false it is highly recommended to reuse instances with the . + + + + + Resolves the contract for a given type. + + The type to resolve a contract for. + The contract for a given type. + + + + Gets the serializable members for the type. + + The type to get serializable members for. + The serializable members for the type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates the constructor parameters. + + The constructor to create properties for. + The type's member properties. + Properties for the given . + + + + Creates a for the given . + + The matching member property. + The constructor parameter. + A created for the given . + + + + Resolves the default for the contract. + + Type of the object. + The contract's default . + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Creates a for the given type. + + Type of the object. + A for the given type. + + + + Determines which contract type is created for the given type. + + Type of the object. + A for the given type. + + + + Creates properties for the given . + + The type to create properties for. + /// The member serialization mode for the type. + Properties for the given . + + + + Creates the used by the serializer to get and set values from a member. + + The member. + The used by the serializer to get and set values from a member. + + + + Creates a for the given . + + The member's parent . + The member to create a for. + A created for the given . + + + + Resolves the name of the property. + + Name of the property. + Name of the property. + + + + Gets the resolved name of the property. + + Name of the property. + Name of the property. + + + + Gets a value indicating whether members are being get and set using dynamic code generation. + This value is determined by the runtime permissions available. + + + true if using dynamic code generation; otherwise, false. + + + + + Gets or sets the default members search flags. + + The default members search flags. + + + + Gets or sets a value indicating whether compiler generated members should be serialized. + + + true if serialized compiler generated members; otherwise, false. + + + + + Gets or sets a value indicating whether to ignore the interface when serializing and deserializing types. + + + true if the interface will be ignored when serializing and deserializing types; otherwise, false. + + + + + Gets or sets a value indicating whether to ignore the attribute when serializing and deserializing types. + + + true if the attribute will be ignored when serializing and deserializing types; otherwise, false. + + + + + Initializes a new instance of the class. + + + + + Resolves the name of the property. + + Name of the property. + The property name camel cased. + + + + The default serialization binder used when resolving and loading classes from type names. + + + + + When overridden in a derived class, controls the binding of a serialized object to a type. + + Specifies the name of the serialized object. + Specifies the name of the serialized object. + + The type of the object the formatter creates a new instance of. + + + + + When overridden in a derived class, controls the binding of a serialized object to a type. + + The type of the object the formatter creates a new instance of. + Specifies the name of the serialized object. + Specifies the name of the serialized object. + + + + Provides information surrounding an error. + + + + + Gets the error. + + The error. + + + + Gets the original object that caused the error. + + The original object that caused the error. + + + + Gets the member that caused the error. + + The member that caused the error. + + + + Gets the path of the JSON location where the error occurred. + + The path of the JSON location where the error occurred. + + + + Gets or sets a value indicating whether this is handled. + + true if handled; otherwise, false. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Gets the of the collection items. + + The of the collection items. + + + + Gets a value indicating whether the collection type is a multidimensional array. + + true if the collection type is a multidimensional array; otherwise, false. + + + + Handles serialization callback events. + + The object that raised the callback event. + The streaming context. + + + + Handles serialization error callback events. + + The object that raised the callback event. + The streaming context. + The error context. + + + + Sets extension data for an object during deserialization. + + The object to set extension data on. + The extension data key. + The extension data value. + + + + Gets extension data for an object during serialization. + + The object to set extension data on. + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Gets or sets the property name resolver. + + The property name resolver. + + + + Gets the of the dictionary keys. + + The of the dictionary keys. + + + + Gets the of the dictionary values. + + The of the dictionary values. + + + + Maps a JSON property to a .NET member or constructor parameter. + + + + + Returns a that represents this instance. + + + A that represents this instance. + + + + + Gets or sets the name of the property. + + The name of the property. + + + + Gets or sets the type that declared this property. + + The type that declared this property. + + + + Gets or sets the order of serialization and deserialization of a member. + + The numeric order of serialization or deserialization. + + + + Gets or sets the name of the underlying member or parameter. + + The name of the underlying member or parameter. + + + + Gets the that will get and set the during serialization. + + The that will get and set the during serialization. + + + + Gets or sets the type of the property. + + The type of the property. + + + + Gets or sets the for the property. + If set this converter takes presidence over the contract converter for the property type. + + The converter. + + + + Gets or sets the member converter. + + The member converter. + + + + Gets or sets a value indicating whether this is ignored. + + true if ignored; otherwise, false. + + + + Gets or sets a value indicating whether this is readable. + + true if readable; otherwise, false. + + + + Gets or sets a value indicating whether this is writable. + + true if writable; otherwise, false. + + + + Gets or sets a value indicating whether this has a member attribute. + + true if has a member attribute; otherwise, false. + + + + Gets the default value. + + The default value. + + + + Gets or sets a value indicating whether this is required. + + A value indicating whether this is required. + + + + Gets or sets a value indicating whether this property preserves object references. + + + true if this instance is reference; otherwise, false. + + + + + Gets or sets the property null value handling. + + The null value handling. + + + + Gets or sets the property default value handling. + + The default value handling. + + + + Gets or sets the property reference loop handling. + + The reference loop handling. + + + + Gets or sets the property object creation handling. + + The object creation handling. + + + + Gets or sets or sets the type name handling. + + The type name handling. + + + + Gets or sets a predicate used to determine whether the property should be serialize. + + A predicate used to determine whether the property should be serialize. + + + + Gets or sets a predicate used to determine whether the property should be serialized. + + A predicate used to determine whether the property should be serialized. + + + + Gets or sets an action used to set whether the property has been deserialized. + + An action used to set whether the property has been deserialized. + + + + Gets or sets the converter used when serializing the property's collection items. + + The collection's items converter. + + + + Gets or sets whether this property's collection items are serialized as a reference. + + Whether this property's collection items are serialized as a reference. + + + + Gets or sets the the type name handling used when serializing the property's collection items. + + The collection's items type name handling. + + + + Gets or sets the the reference loop handling used when serializing the property's collection items. + + The collection's items reference loop handling. + + + + A collection of objects. + + + + + Initializes a new instance of the class. + + The type. + + + + When implemented in a derived class, extracts the key from the specified element. + + The element from which to extract the key. + The key for the specified element. + + + + Adds a object. + + The property to add to the collection. + + + + Gets the closest matching object. + First attempts to get an exact case match of propertyName and then + a case insensitive match. + + Name of the property. + A matching property if found. + + + + Gets a property by property name. + + The name of the property to get. + Type property name string comparison. + A matching property if found. + + + + Specifies missing member handling options for the . + + + + + Ignore a missing member and do not attempt to deserialize it. + + + + + Throw a when a missing member is encountered during deserialization. + + + + + Specifies null value handling options for the . + + + + + + + + + Include null values when serializing and deserializing objects. + + + + + Ignore null values when serializing and deserializing objects. + + + + + Specifies reference loop handling options for the . + + + + + Throw a when a loop is encountered. + + + + + Ignore loop references and do not serialize. + + + + + Serialize loop references. + + + + + An in-memory representation of a JSON Schema. + + + + + Initializes a new instance of the class. + + + + + Reads a from the specified . + + The containing the JSON Schema to read. + The object representing the JSON Schema. + + + + Reads a from the specified . + + The containing the JSON Schema to read. + The to use when resolving schema references. + The object representing the JSON Schema. + + + + Load a from a string that contains schema JSON. + + A that contains JSON. + A populated from the string that contains JSON. + + + + Parses the specified json. + + The json. + The resolver. + A populated from the string that contains JSON. + + + + Writes this schema to a . + + A into which this method will write. + + + + Writes this schema to a using the specified . + + A into which this method will write. + The resolver used. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets or sets the id. + + + + + Gets or sets the title. + + + + + Gets or sets whether the object is required. + + + + + Gets or sets whether the object is read only. + + + + + Gets or sets whether the object is visible to users. + + + + + Gets or sets whether the object is transient. + + + + + Gets or sets the description of the object. + + + + + Gets or sets the types of values allowed by the object. + + The type. + + + + Gets or sets the pattern. + + The pattern. + + + + Gets or sets the minimum length. + + The minimum length. + + + + Gets or sets the maximum length. + + The maximum length. + + + + Gets or sets a number that the value should be divisble by. + + A number that the value should be divisble by. + + + + Gets or sets the minimum. + + The minimum. + + + + Gets or sets the maximum. + + The maximum. + + + + Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute. + + A flag indicating whether the value can not equal the number defined by the "minimum" attribute. + + + + Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute. + + A flag indicating whether the value can not equal the number defined by the "maximum" attribute. + + + + Gets or sets the minimum number of items. + + The minimum number of items. + + + + Gets or sets the maximum number of items. + + The maximum number of items. + + + + Gets or sets the of items. + + The of items. + + + + Gets or sets a value indicating whether items in an array are validated using the instance at their array position from . + + + true if items are validated using their array position; otherwise, false. + + + + + Gets or sets the of additional items. + + The of additional items. + + + + Gets or sets a value indicating whether additional items are allowed. + + + true if additional items are allowed; otherwise, false. + + + + + Gets or sets whether the array items must be unique. + + + + + Gets or sets the of properties. + + The of properties. + + + + Gets or sets the of additional properties. + + The of additional properties. + + + + Gets or sets the pattern properties. + + The pattern properties. + + + + Gets or sets a value indicating whether additional properties are allowed. + + + true if additional properties are allowed; otherwise, false. + + + + + Gets or sets the required property if this property is present. + + The required property if this property is present. + + + + Gets or sets the a collection of valid enum values allowed. + + A collection of valid enum values allowed. + + + + Gets or sets disallowed types. + + The disallow types. + + + + Gets or sets the default value. + + The default value. + + + + Gets or sets the collection of that this schema extends. + + The collection of that this schema extends. + + + + Gets or sets the format. + + The format. + + + + Generates a from a specified . + + + + + Generate a from the specified type. + + The type to generate a from. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + The used to resolve schema references. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + Specify whether the generated root will be nullable. + A generated from the specified type. + + + + Generate a from the specified type. + + The type to generate a from. + The used to resolve schema references. + Specify whether the generated root will be nullable. + A generated from the specified type. + + + + Gets or sets how undefined schemas are handled by the serializer. + + + + + Gets or sets the contract resolver. + + The contract resolver. + + + + The value types allowed by the . + + + + + No type specified. + + + + + String type. + + + + + Float type. + + + + + Integer type. + + + + + Boolean type. + + + + + Object type. + + + + + Array type. + + + + + Null type. + + + + + Any type. + + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Gets or sets the object member serialization. + + The member object serialization. + + + + Gets or sets a value that indicates whether the object's properties are required. + + + A value indicating whether the object's properties are required. + + + + + Gets the object's properties. + + The object's properties. + + + + Gets the constructor parameters required for any non-default constructor + + + + + Gets a collection of instances that define the parameters used with . + + + + + Gets or sets the override constructor used to create the object. + This is set when a constructor is marked up using the + JsonConstructor attribute. + + The override constructor. + + + + Gets or sets the parametrized constructor used to create the object. + + The parametrized constructor. + + + + Gets or sets the function used to create the object. When set this function will override . + This function is called with a collection of arguments which are defined by the collection. + + The function used to create the object. + + + + Gets or sets the extension data setter. + + + + + Gets or sets the extension data getter. + + + + + Contract details for a used by the . + + + + + Initializes a new instance of the class. + + The underlying type for the contract. + + + + Lookup and create an instance of the JsonConverter type described by the argument. + + The JsonConverter type to create. + Optional arguments to pass to an initializing constructor of the JsonConverter. + If null, the default constructor is used. + + + + Create a factory function that can be used to create instances of a JsonConverter described by the + argument type. The returned function can then be used to either invoke the converter's default ctor, or any + parameterized constructors by way of an object array. + + + + + Get and set values for a using reflection. + + + + + Initializes a new instance of the class. + + The member info. + + + + Sets the value. + + The target to set the value on. + The value to set on the target. + + + + Gets the value. + + The target to get the value from. + The value. + + + + When applied to a method, specifies that the method is called when an error occurs serializing an object. + + + + + Helper method for generating a MetaObject which calls a + specific method on Dynamic that returns a result + + + + + Helper method for generating a MetaObject which calls a + specific method on Dynamic, but uses one of the arguments for + the result. + + + + + Helper method for generating a MetaObject which calls a + specific method on Dynamic, but uses one of the arguments for + the result. + + + + + Returns a Restrictions object which includes our current restrictions merged + with a restriction limiting our type + + + + + Represents a method that constructs an object. + + The object type to create. + + + + Specifies type name handling options for the . + + + + + Do not include the .NET type name when serializing types. + + + + + Include the .NET type name when serializing into a JSON object structure. + + + + + Include the .NET type name when serializing into a JSON array structure. + + + + + Always include the .NET type name when serializing. + + + + + Include the .NET type name when the type of the object being serialized is not the same as its declared type. + + + + + Converts the value to the specified type. If the value is unable to be converted, the + value is checked whether it assignable to the specified type. + + The value to convert. + The culture to use when converting. + The type to convert or cast the value to. + + The converted type. If conversion was unsuccessful, the initial value + is returned if assignable to the target type. + + + + + Gets a dictionary of the names and values of an Enum type. + + + + + + Gets a dictionary of the names and values of an Enum type. + + The enum type to get names and values for. + + + + + Specifies the type of Json token. + + + + + This is returned by the if a method has not been called. + + + + + An object start token. + + + + + An array start token. + + + + + A constructor start token. + + + + + An object property name. + + + + + A comment. + + + + + Raw JSON. + + + + + An integer. + + + + + A float. + + + + + A string. + + + + + A boolean. + + + + + A null token. + + + + + An undefined token. + + + + + An object end token. + + + + + An array end token. + + + + + A constructor end token. + + + + + A Date. + + + + + Byte data. + + + + + Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. + + + + + Determines whether the collection is null or empty. + + The collection. + + true if the collection is null or empty; otherwise, false. + + + + + Adds the elements of the specified collection to the specified generic IList. + + The list to add to. + The collection of elements to add. + + + + Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer. + + The type of the elements of source. + A sequence in which to locate a value. + The object to locate in the sequence + An equality comparer to compare values. + The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1. + + + + Gets the type of the typed collection's items. + + The type. + The type of the typed collection's items. + + + + Gets the member's underlying type. + + The member. + The underlying type of the member. + + + + Determines whether the member is an indexed property. + + The member. + + true if the member is an indexed property; otherwise, false. + + + + + Determines whether the property is an indexed property. + + The property. + + true if the property is an indexed property; otherwise, false. + + + + + Gets the member's value on the object. + + The member. + The target object. + The member's value on the object. + + + + Sets the member's value on the target object. + + The member. + The target. + The value. + + + + Determines whether the specified MemberInfo can be read. + + The MemberInfo to determine whether can be read. + /// if set to true then allow the member to be gotten non-publicly. + + true if the specified MemberInfo can be read; otherwise, false. + + + + + Determines whether the specified MemberInfo can be set. + + The MemberInfo to determine whether can be set. + if set to true then allow the member to be set non-publicly. + if set to true then allow the member to be set if read-only. + + true if the specified MemberInfo can be set; otherwise, false. + + + + + Determines whether the string is all white space. Empty string will return false. + + The string to test whether it is all white space. + + true if the string is all white space; otherwise, false. + + + + + Nulls an empty string. + + The string. + Null if the string was null, otherwise the string unchanged. + + + + Specifies the state of the . + + + + + An exception has been thrown, which has left the in an invalid state. + You may call the method to put the in the Closed state. + Any other method calls results in an being thrown. + + + + + The method has been called. + + + + + An object is being written. + + + + + A array is being written. + + + + + A constructor is being written. + + + + + A property is being written. + + + + + A write method has not been called. + + + + diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index b01191e140..f1bf8a050a 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -39,7 +39,8 @@ - + + diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 0544f369fb..a9e368ad8d 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -66,6 +66,9 @@ ;grid default private port 8003, not used in standalone ;# {PrivatePort} {} {PrivatePort} {8003} "8003" + ; port to access private grid services. + ; grids that run all their regions should deny access to this port + ; from outside their networks, using firewalls PrivatePort = "8003" [Startup] diff --git a/bin/RestSharp.dll b/bin/RestSharp.dll new file mode 100644 index 0000000000..ea01262bdb Binary files /dev/null and b/bin/RestSharp.dll differ diff --git a/bin/RestSharp.xml b/bin/RestSharp.xml new file mode 100644 index 0000000000..27a71c7e4e --- /dev/null +++ b/bin/RestSharp.xml @@ -0,0 +1,3024 @@ + + + + RestSharp + + + + + Tries to Authenticate with the credentials of the currently logged in user, or impersonate a user + + + + + Authenticate with the credentials of the currently logged in user + + + + + Authenticate by impersonation + + + + + + + Authenticate by impersonation, using an existing ICredentials instance + + + + + + + + + Base class for OAuth 2 Authenticators. + + + Since there are many ways to authenticate in OAuth2, + this is used as a base class to differentiate between + other authenticators. + + Any other OAuth2 authenticators must derive from this + abstract class. + + + + + Access token to be used when authenticating. + + + + + Initializes a new instance of the class. + + + The access token. + + + + + Gets the access token. + + + + + The OAuth 2 authenticator using URI query parameter. + + + Based on http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-5.1.2 + + + + + Initializes a new instance of the class. + + + The access token. + + + + + The OAuth 2 authenticator using the authorization request header field. + + + Based on http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-5.1.1 + + + + + Stores the Authorization header value as "[tokenType] accessToken". used for performance. + + + + + Initializes a new instance of the class. + + + The access token. + + + + + Initializes a new instance of the class. + + + The access token. + + + The token type. + + + + + All text parameters are UTF-8 encoded (per section 5.1). + + + + + + Generates a random 16-byte lowercase alphanumeric string. + + + + + + + Generates a timestamp based on the current elapsed seconds since '01/01/1970 0000 GMT" + + + + + + + Generates a timestamp based on the elapsed seconds of a given time since '01/01/1970 0000 GMT" + + + A specified point in time. + + + + + The set of characters that are unreserved in RFC 2396 but are NOT unreserved in RFC 3986. + + + + + + URL encodes a string based on section 5.1 of the OAuth spec. + Namely, percent encoding with [RFC3986], avoiding unreserved characters, + upper-casing hexadecimal characters, and UTF-8 encoding for text value pairs. + + The value to escape. + The escaped value. + + The method is supposed to take on + RFC 3986 behavior if certain elements are present in a .config file. Even if this + actually worked (which in my experiments it doesn't), we can't rely on every + host actually having this configuration element present. + + + + + + + URL encodes a string based on section 5.1 of the OAuth spec. + Namely, percent encoding with [RFC3986], avoiding unreserved characters, + upper-casing hexadecimal characters, and UTF-8 encoding for text value pairs. + + + + + + + Sorts a collection of key-value pairs by name, and then value if equal, + concatenating them into a single string. This string should be encoded + prior to, or after normalization is run. + + + + + + + + Sorts a by name, and then value if equal. + + A collection of parameters to sort + A sorted parameter collection + + + + Creates a request URL suitable for making OAuth requests. + Resulting URLs must exclude port 80 or port 443 when accompanied by HTTP and HTTPS, respectively. + Resulting URLs must be lower case. + + + The original request URL + + + + + Creates a request elements concatentation value to send with a request. + This is also known as the signature base. + + + + The request's HTTP method type + The request URL + The request's parameters + A signature base string + + + + Creates a signature value given a signature base and the consumer secret. + This method is used when the token secret is currently unknown. + + + The hashing method + The signature base + The consumer key + + + + + Creates a signature value given a signature base and the consumer secret. + This method is used when the token secret is currently unknown. + + + The hashing method + The treatment to use on a signature value + The signature base + The consumer key + + + + + Creates a signature value given a signature base and the consumer secret and a known token secret. + + + The hashing method + The signature base + The consumer secret + The token secret + + + + + Creates a signature value given a signature base and the consumer secret and a known token secret. + + + The hashing method + The treatment to use on a signature value + The signature base + The consumer secret + The token secret + + + + + A class to encapsulate OAuth authentication flow. + + + + + + Generates a instance to pass to an + for the purpose of requesting an + unauthorized request token. + + The HTTP method for the intended request + + + + + + Generates a instance to pass to an + for the purpose of requesting an + unauthorized request token. + + The HTTP method for the intended request + Any existing, non-OAuth query parameters desired in the request + + + + + + Generates a instance to pass to an + for the purpose of exchanging a request token + for an access token authorized by the user at the Service Provider site. + + The HTTP method for the intended request + + + + + Generates a instance to pass to an + for the purpose of exchanging a request token + for an access token authorized by the user at the Service Provider site. + + The HTTP method for the intended request + + Any existing, non-OAuth query parameters desired in the request + + + + Generates a instance to pass to an + for the purpose of exchanging user credentials + for an access token authorized by the user at the Service Provider site. + + The HTTP method for the intended request + + Any existing, non-OAuth query parameters desired in the request + + + + + + + + + + + + + Allows control how class and property names and values are deserialized by XmlAttributeDeserializer + + + + + The name to use for the serialized element + + + + + Sets if the property to Deserialize is an Attribute or Element (Default: false) + + + + + Wrapper for System.Xml.Serialization.XmlSerializer. + + + + + Types of parameters that can be added to requests + + + + + Data formats + + + + + HTTP method to use when making requests + + + + + Format strings for commonly-used date formats + + + + + .NET format string for ISO 8601 date format + + + + + .NET format string for roundtrip date format + + + + + Status for responses (surprised?) + + + + + Extension method overload! + + + + + Save a byte array to a file + + Bytes to save + Full path to save file to + + + + Read a stream into a byte array + + Stream to read + byte[] + + + + Copies bytes from one stream to another + + The input stream. + The output stream. + + + + Converts a byte array to a string, using its byte order mark to convert it to the right encoding. + http://www.shrinkrays.net/code-snippets/csharp/an-extension-method-for-converting-a-byte-array-to-a-string.aspx + + An array of bytes to convert + The byte as a string. + + + + Decodes an HTML-encoded string and returns the decoded string. + + The HTML string to decode. + The decoded text. + + + + Decodes an HTML-encoded string and sends the resulting output to a TextWriter output stream. + + The HTML string to decode + The TextWriter output stream containing the decoded string. + + + + HTML-encodes a string and sends the resulting output to a TextWriter output stream. + + The string to encode. + The TextWriter output stream containing the encoded string. + + + + Reflection extensions + + + + + Retrieve an attribute from a member (property) + + Type of attribute to retrieve + Member to retrieve attribute from + + + + + Retrieve an attribute from a type + + Type of attribute to retrieve + Type to retrieve attribute from + + + + + Checks a type to see if it derives from a raw generic (e.g. List[[]]) + + + + + + + + Find a value from a System.Enum by trying several possible variants + of the string value of the enum. + + Type of enum + Value for which to search + The culture used to calculate the name variants + + + + + Convert a to a instance. + + The response status. + + responseStatus + + + + Uses Uri.EscapeDataString() based on recommendations on MSDN + http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx + + + + + Check that a string is not null or empty + + String to check + bool + + + + Remove underscores from a string + + String to process + string + + + + Parses most common JSON date formats + + JSON value to parse + + DateTime + + + + Remove leading and trailing " from a string + + String to parse + String + + + + Checks a string to see if it matches a regex + + String to check + Pattern to match + bool + + + + Converts a string to pascal case + + String to convert + + string + + + + Converts a string to pascal case with the option to remove underscores + + String to convert + Option to remove underscores + + + + + + Converts a string to camel case + + String to convert + + String + + + + Convert the first letter of a string to lower case + + String to convert + string + + + + Checks to see if a string is all uppper case + + String to check + bool + + + + Add underscores to a pascal-cased string + + String to convert + string + + + + Add dashes to a pascal-cased string + + String to convert + string + + + + Add an undescore prefix to a pascasl-cased string + + + + + + + Add spaces to a pascal-cased string + + String to convert + string + + + + Return possible variants of a name for name matching. + + String to convert + The culture to use for conversion + IEnumerable<string> + + + + XML Extension Methods + + + + + Returns the name of an element with the namespace if specified + + Element name + XML Namespace + + + + + Container for files to be uploaded with requests + + + + + Creates a file parameter from an array of bytes. + + The parameter name to use in the request. + The data to use as the file's contents. + The filename to use in the request. + The content type to use in the request. + The + + + + Creates a file parameter from an array of bytes. + + The parameter name to use in the request. + The data to use as the file's contents. + The filename to use in the request. + The using the default content type. + + + + The length of data to be sent + + + + + Provides raw data for file + + + + + Name of the file to use when uploading + + + + + MIME content type of file + + + + + Name of the parameter + + + + + HttpWebRequest wrapper (async methods) + + + HttpWebRequest wrapper + + + HttpWebRequest wrapper (sync methods) + + + + + Always send a multipart/form-data request - even when no Files are present. + + + + + An alternative to RequestBody, for when the caller already has the byte array. + + + + + Execute an async POST-style request with the specified HTTP Method. + + + The HTTP method to execute. + + + + + Execute an async GET-style request with the specified HTTP Method. + + + The HTTP method to execute. + + + + + Creates an IHttp + + + + + + Default constructor + + + + + Execute a POST request + + + + + Execute a PUT request + + + + + Execute a GET request + + + + + Execute a HEAD request + + + + + Execute an OPTIONS request + + + + + Execute a DELETE request + + + + + Execute a PATCH request + + + + + Execute a MERGE request + + + + + Execute a GET-style request with the specified HTTP Method. + + The HTTP method to execute. + + + + + Execute a POST-style request with the specified HTTP Method. + + The HTTP method to execute. + + + + + True if this HTTP request has any HTTP parameters + + + + + True if this HTTP request has any HTTP cookies + + + + + True if a request body has been specified + + + + + True if files have been set to be uploaded + + + + + Always send a multipart/form-data request - even when no Files are present. + + + + + UserAgent to be sent with request + + + + + Timeout in milliseconds to be used for the request + + + + + The number of milliseconds before the writing or reading times out. + + + + + System.Net.ICredentials to be sent with request + + + + + The System.Net.CookieContainer to be used for the request + + + + + The method to use to write the response instead of reading into RawBytes + + + + + Collection of files to be sent with request + + + + + Whether or not HTTP 3xx response redirects should be automatically followed + + + + + X509CertificateCollection to be sent with request + + + + + Maximum number of automatic redirects to follow if FollowRedirects is true + + + + + Determine whether or not the "default credentials" (e.g. the user account under which the current process is running) + will be sent along to the server. + + + + + HTTP headers to be sent with request + + + + + HTTP parameters (QueryString or Form values) to be sent with request + + + + + HTTP cookies to be sent with request + + + + + Request body to be sent with request + + + + + Content type of the request body. + + + + + An alternative to RequestBody, for when the caller already has the byte array. + + + + + URL to call for this request + + + + + Flag to send authorisation header with the HttpWebRequest + + + + + Proxy info to be sent with request + + + + + Representation of an HTTP cookie + + + + + Comment of the cookie + + + + + Comment of the cookie + + + + + Indicates whether the cookie should be discarded at the end of the session + + + + + Domain of the cookie + + + + + Indicates whether the cookie is expired + + + + + Date and time that the cookie expires + + + + + Indicates that this cookie should only be accessed by the server + + + + + Name of the cookie + + + + + Path of the cookie + + + + + Port of the cookie + + + + + Indicates that the cookie should only be sent over secure channels + + + + + Date and time the cookie was created + + + + + Value of the cookie + + + + + Version of the cookie + + + + + Container for HTTP file + + + + + The length of data to be sent + + + + + Provides raw data for file + + + + + Name of the file to use when uploading + + + + + MIME content type of file + + + + + Name of the parameter + + + + + Representation of an HTTP header + + + + + Name of the header + + + + + Value of the header + + + + + Representation of an HTTP parameter (QueryString or Form value) + + + + + Name of the parameter + + + + + Value of the parameter + + + + + HTTP response data + + + + + HTTP response data + + + + + MIME content type of response + + + + + Length in bytes of the response content + + + + + Encoding of the response content + + + + + String representation of response content + + + + + HTTP response status code + + + + + Description of HTTP status returned + + + + + Response content + + + + + The URL that actually responded to the content (different from request if redirected) + + + + + HttpWebResponse.Server + + + + + Headers returned by server with the response + + + + + Cookies returned by server with the response + + + + + Status of the request. Will return Error for transport errors. + HTTP errors will still return ResponseStatus.Completed, check StatusCode instead + + + + + Transport or other non-HTTP error generated while attempting request + + + + + Exception thrown when error is encountered. + + + + + Default constructor + + + + + MIME content type of response + + + + + Length in bytes of the response content + + + + + Encoding of the response content + + + + + Lazy-loaded string representation of response content + + + + + HTTP response status code + + + + + Description of HTTP status returned + + + + + Response content + + + + + The URL that actually responded to the content (different from request if redirected) + + + + + HttpWebResponse.Server + + + + + Headers returned by server with the response + + + + + Cookies returned by server with the response + + + + + Status of the request. Will return Error for transport errors. + HTTP errors will still return ResponseStatus.Completed, check StatusCode instead + + + + + Transport or other non-HTTP error generated while attempting request + + + + + Exception thrown when error is encountered. + + + + + + + + + + + + + + + + + + + + + + + + Executes a GET-style request and callback asynchronously, authenticating if needed + + Request to be executed + Callback function to be executed upon completion providing access to the async handle. + The HTTP method to execute + + + + Executes a POST-style request and callback asynchronously, authenticating if needed + + Request to be executed + Callback function to be executed upon completion providing access to the async handle. + The HTTP method to execute + + + + Executes a GET-style request and callback asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + Callback function to be executed upon completion + The HTTP method to execute + + + + Executes a GET-style request and callback asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + Callback function to be executed upon completion + The HTTP method to execute + + + + Executes the request and callback asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + The cancellation token + + + + Executes the request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + + + + Executes a GET-style request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + + + + Executes a GET-style request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + The cancellation token + + + + Executes a POST-style request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + + + + Executes a POST-style request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + The cancellation token + + + + Executes the request and callback asynchronously, authenticating if needed + + Request to be executed + The cancellation token + + + + Executes the request asynchronously, authenticating if needed + + Request to be executed + + + + Executes a GET-style asynchronously, authenticating if needed + + Request to be executed + + + + Executes a GET-style asynchronously, authenticating if needed + + Request to be executed + The cancellation token + + + + Executes a POST-style asynchronously, authenticating if needed + + Request to be executed + + + + Executes a POST-style asynchronously, authenticating if needed + + Request to be executed + The cancellation token + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X509CertificateCollection to be sent with request + + + + + Adds a file to the Files collection to be included with a POST or PUT request + (other methods do not support file uploads). + + The parameter name to use in the request + Full path to file to upload + This request + + + + Adds the bytes to the Files collection with the specified file name + + The parameter name to use in the request + The file data + The file name to use for the uploaded file + This request + + + + Adds the bytes to the Files collection with the specified file name and content type + + The parameter name to use in the request + The file data + The file name to use for the uploaded file + The MIME type of the file to upload + This request + + + + Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer + The default format is XML. Change RequestFormat if you wish to use a different serialization format. + + The object to serialize + The XML namespace to use when serializing + This request + + + + Serializes obj to data format specified by RequestFormat and adds it to the request body. + The default format is XML. Change RequestFormat if you wish to use a different serialization format. + + The object to serialize + This request + + + + Serializes obj to JSON format and adds it to the request body. + + The object to serialize + This request + + + + Serializes obj to XML format and adds it to the request body. + + The object to serialize + This request + + + + Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer + Serializes obj to XML format and passes xmlNamespace then adds it to the request body. + + The object to serialize + The XML namespace to use when serializing + This request + + + + Calls AddParameter() for all public, readable properties specified in the includedProperties list + + + request.AddObject(product, "ProductId", "Price", ...); + + The object with properties to add as parameters + The names of the properties to include + This request + + + + Calls AddParameter() for all public, readable properties of obj + + The object with properties to add as parameters + This request + + + + Add the parameter to the request + + Parameter to add + + + + + Adds a HTTP parameter to the request (QueryString for GET, DELETE, OPTIONS and HEAD; Encoded form for POST and PUT) + + Name of the parameter + Value of the parameter + This request + + + + Adds a parameter to the request. There are five types of parameters: + - GetOrPost: Either a QueryString value or encoded form value based on method + - HttpHeader: Adds the name/value pair to the HTTP request's Headers collection + - UrlSegment: Inserted into URL if there is a matching url token e.g. {AccountId} + - Cookie: Adds the name/value pair to the HTTP request's Cookies collection + - RequestBody: Used by AddBody() (not recommended to use directly) + + Name of the parameter + Value of the parameter + The type of parameter to add + This request + + + + Shortcut to AddParameter(name, value, HttpHeader) overload + + Name of the header to add + Value of the header to add + + + + + Shortcut to AddParameter(name, value, Cookie) overload + + Name of the cookie to add + Value of the cookie to add + + + + + Shortcut to AddParameter(name, value, UrlSegment) overload + + Name of the segment to add + Value of the segment to add + + + + + Shortcut to AddParameter(name, value, QueryString) overload + + Name of the parameter to add + Value of the parameter to add + + + + + Always send a multipart/form-data request - even when no Files are present. + + + + + Serializer to use when writing JSON request bodies. Used if RequestFormat is Json. + By default the included JsonSerializer is used (currently using JSON.NET default serialization). + + + + + Serializer to use when writing XML request bodies. Used if RequestFormat is Xml. + By default the included XmlSerializer is used. + + + + + Set this to write response to Stream rather than reading into memory. + + + + + Container of all HTTP parameters to be passed with the request. + See AddParameter() for explanation of the types of parameters that can be passed + + + + + Container of all the files to be uploaded with the request. + + + + + Determines what HTTP method to use for this request. Supported methods: GET, POST, PUT, DELETE, HEAD, OPTIONS + Default is GET + + + + + The Resource URL to make the request against. + Tokens are substituted with UrlSegment parameters and match by name. + Should not include the scheme or domain. Do not include leading slash. + Combined with RestClient.BaseUrl to assemble final URL: + {BaseUrl}/{Resource} (BaseUrl is scheme + domain, e.g. http://example.com) + + + // example for url token replacement + request.Resource = "Products/{ProductId}"; + request.AddParameter("ProductId", 123, ParameterType.UrlSegment); + + + + + Serializer to use when writing XML request bodies. Used if RequestFormat is Xml. + By default XmlSerializer is used. + + + + + Used by the default deserializers to determine where to start deserializing from. + Can be used to skip container or root elements that do not have corresponding deserialzation targets. + + + + + Used by the default deserializers to explicitly set which date format string to use when parsing dates. + + + + + Used by XmlDeserializer. If not specified, XmlDeserializer will flatten response by removing namespaces from element names. + + + + + In general you would not need to set this directly. Used by the NtlmAuthenticator. + + + + + Timeout in milliseconds to be used for the request. This timeout value overrides a timeout set on the RestClient. + + + + + The number of milliseconds before the writing or reading times out. This timeout value overrides a timeout set on the RestClient. + + + + + How many attempts were made to send this Request? + + + This Number is incremented each time the RestClient sends the request. + Useful when using Asynchronous Execution with Callbacks + + + + + Determine whether or not the "default credentials" (e.g. the user account under which the current process is running) + will be sent along to the server. The default is false. + + + + + Container for data sent back from API + + + + + The RestRequest that was made to get this RestResponse + + + Mainly for debugging if ResponseStatus is not OK + + + + + MIME content type of response + + + + + Length in bytes of the response content + + + + + Encoding of the response content + + + + + String representation of response content + + + + + HTTP response status code + + + + + Description of HTTP status returned + + + + + Response content + + + + + The URL that actually responded to the content (different from request if redirected) + + + + + HttpWebResponse.Server + + + + + Cookies returned by server with the response + + + + + Headers returned by server with the response + + + + + Status of the request. Will return Error for transport errors. + HTTP errors will still return ResponseStatus.Completed, check StatusCode instead + + + + + Transport or other non-HTTP error generated while attempting request + + + + + Exceptions thrown during the request, if any. + + Will contain only network transport or framework exceptions thrown during the request. + HTTP protocol errors are handled by RestSharp and will not appear here. + + + + Container for data sent back from API including deserialized data + + Type of data to deserialize to + + + + Deserialized entity data + + + + + Parameter container for REST requests + + + + + Return a human-readable representation of this parameter + + String + + + + Name of the parameter + + + + + Value of the parameter + + + + + Type of the parameter + + + + + Client to translate RestRequests into Http requests and process response result + + + + + Executes the request and callback asynchronously, authenticating if needed + + Request to be executed + Callback function to be executed upon completion providing access to the async handle. + + + + Executes a GET-style request and callback asynchronously, authenticating if needed + + Request to be executed + Callback function to be executed upon completion providing access to the async handle. + The HTTP method to execute + + + + Executes a POST-style request and callback asynchronously, authenticating if needed + + Request to be executed + Callback function to be executed upon completion providing access to the async handle. + The HTTP method to execute + + + + Executes the request and callback asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + Callback function to be executed upon completion + + + + Executes a GET-style request and callback asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + Callback function to be executed upon completion + The HTTP method to execute + + + + Executes a POST-style request and callback asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + Callback function to be executed upon completion + The HTTP method to execute + + + + Executes a GET-style request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + + + + Executes a GET-style request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + The cancellation token + + + + Executes a POST-style request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + + + + Executes a POST-style request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + The cancellation token + + + + Executes the request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + + + + Executes the request asynchronously, authenticating if needed + + Target deserialization type + Request to be executed + The cancellation token + + + + Executes the request asynchronously, authenticating if needed + + Request to be executed + + + + Executes a GET-style asynchronously, authenticating if needed + + Request to be executed + + + + Executes a GET-style asynchronously, authenticating if needed + + Request to be executed + The cancellation token + + + + Executes a POST-style asynchronously, authenticating if needed + + Request to be executed + + + + Executes a POST-style asynchronously, authenticating if needed + + Request to be executed + The cancellation token + + + + Executes the request asynchronously, authenticating if needed + + Request to be executed + The cancellation token + + + + Default constructor that registers default content handlers + + + + + Sets the BaseUrl property for requests made by this client instance + + + + + + Sets the BaseUrl property for requests made by this client instance + + + + + + Registers a content handler to process response content + + MIME content type of the response content + Deserializer to use to process content + + + + Remove a content handler for the specified MIME content type + + MIME content type to remove + + + + Remove all content handlers + + + + + Retrieve the handler for the specified MIME content type + + MIME content type to retrieve + IDeserializer instance + + + + Assembles URL to call based on parameters, method and resource + + RestRequest to execute + Assembled System.Uri + + + + Executes the specified request and downloads the response data + + Request to execute + Response data + + + + Executes the request and returns a response, authenticating if needed + + Request to be executed + RestResponse + + + + Executes the specified request and deserializes the response content using the appropriate content handler + + Target deserialization type + Request to execute + RestResponse[[T]] with deserialized data in Data property + + + + Parameters included with every request made with this instance of RestClient + If specified in both client and request, the request wins + + + + + Maximum number of redirects to follow if FollowRedirects is true + + + + + X509CertificateCollection to be sent with request + + + + + Proxy to use for requests made by this client instance. + Passed on to underlying WebRequest if set. + + + + + Default is true. Determine whether or not requests that result in + HTTP status codes of 3xx should follow returned redirect + + + + + The CookieContainer used for requests made by this client instance + + + + + UserAgent to use for requests made by this client instance + + + + + Timeout in milliseconds to use for requests made by this client instance + + + + + The number of milliseconds before the writing or reading times out. + + + + + Whether to invoke async callbacks using the SynchronizationContext.Current captured when invoked + + + + + Authenticator to use for requests made by this client instance + + + + + Combined with Request.Resource to construct URL for request + Should include scheme and domain without trailing slash. + + + client.BaseUrl = new Uri("http://example.com"); + + + + + Executes the request and callback asynchronously, authenticating if needed + + The IRestClient this method extends + Request to be executed + Callback function to be executed upon completion + + + + Executes the request and callback asynchronously, authenticating if needed + + The IRestClient this method extends + Target deserialization type + Request to be executed + Callback function to be executed upon completion providing access to the async handle + + + + Add a parameter to use on every request made with this client instance + + The IRestClient instance + Parameter to add + + + + + Removes a parameter from the default parameters that are used on every request made with this client instance + + The IRestClient instance + The name of the parameter that needs to be removed + + + + + Adds a HTTP parameter (QueryString for GET, DELETE, OPTIONS and HEAD; Encoded form for POST and PUT) + Used on every request made by this client instance + + The IRestClient instance + Name of the parameter + Value of the parameter + This request + + + + Adds a parameter to the request. There are four types of parameters: + - GetOrPost: Either a QueryString value or encoded form value based on method + - HttpHeader: Adds the name/value pair to the HTTP request's Headers collection + - UrlSegment: Inserted into URL if there is a matching url token e.g. {AccountId} + - RequestBody: Used by AddBody() (not recommended to use directly) + + The IRestClient instance + Name of the parameter + Value of the parameter + The type of parameter to add + This request + + + + Shortcut to AddDefaultParameter(name, value, HttpHeader) overload + + The IRestClient instance + Name of the header to add + Value of the header to add + + + + + Shortcut to AddDefaultParameter(name, value, UrlSegment) overload + + The IRestClient instance + Name of the segment to add + Value of the segment to add + + + + + Container for data used to make requests + + + + + Default constructor + + + + + Sets Method property to value of method + + Method to use for this request + + + + Sets Resource property + + Resource to use for this request + + + + Sets Resource and Method properties + + Resource to use for this request + Method to use for this request + + + + Sets Resource property + + Resource to use for this request + + + + Sets Resource and Method properties + + Resource to use for this request + Method to use for this request + + + + Adds a file to the Files collection to be included with a POST or PUT request + (other methods do not support file uploads). + + The parameter name to use in the request + Full path to file to upload + This request + + + + Adds the bytes to the Files collection with the specified file name + + The parameter name to use in the request + The file data + The file name to use for the uploaded file + This request + + + + Adds the bytes to the Files collection with the specified file name and content type + + The parameter name to use in the request + The file data + The file name to use for the uploaded file + The MIME type of the file to upload + This request + + + + Adds the bytes to the Files collection with the specified file name and content type + + The parameter name to use in the request + A function that writes directly to the stream. Should NOT close the stream. + The file name to use for the uploaded file + This request + + + + Adds the bytes to the Files collection with the specified file name and content type + + The parameter name to use in the request + A function that writes directly to the stream. Should NOT close the stream. + The file name to use for the uploaded file + The MIME type of the file to upload + This request + + + + Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer + The default format is XML. Change RequestFormat if you wish to use a different serialization format. + + The object to serialize + The XML namespace to use when serializing + This request + + + + Serializes obj to data format specified by RequestFormat and adds it to the request body. + The default format is XML. Change RequestFormat if you wish to use a different serialization format. + + The object to serialize + This request + + + + Serializes obj to JSON format and adds it to the request body. + + The object to serialize + This request + + + + Serializes obj to XML format and adds it to the request body. + + The object to serialize + This request + + + + Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer + Serializes obj to XML format and passes xmlNamespace then adds it to the request body. + + The object to serialize + The XML namespace to use when serializing + This request + + + + Calls AddParameter() for all public, readable properties specified in the includedProperties list + + + request.AddObject(product, "ProductId", "Price", ...); + + The object with properties to add as parameters + The names of the properties to include + This request + + + + Calls AddParameter() for all public, readable properties of obj + + The object with properties to add as parameters + This request + + + + Add the parameter to the request + + Parameter to add + + + + + Adds a HTTP parameter to the request (QueryString for GET, DELETE, OPTIONS and HEAD; Encoded form for POST and PUT) + + Name of the parameter + Value of the parameter + This request + + + + Adds a parameter to the request. There are four types of parameters: + - GetOrPost: Either a QueryString value or encoded form value based on method + - HttpHeader: Adds the name/value pair to the HTTP request's Headers collection + - UrlSegment: Inserted into URL if there is a matching url token e.g. {AccountId} + - RequestBody: Used by AddBody() (not recommended to use directly) + + Name of the parameter + Value of the parameter + The type of parameter to add + This request + + + + Shortcut to AddParameter(name, value, HttpHeader) overload + + Name of the header to add + Value of the header to add + + + + + Shortcut to AddParameter(name, value, Cookie) overload + + Name of the cookie to add + Value of the cookie to add + + + + + Shortcut to AddParameter(name, value, UrlSegment) overload + + Name of the segment to add + Value of the segment to add + + + + + Shortcut to AddParameter(name, value, QueryString) overload + + Name of the parameter to add + Value of the parameter to add + + + + + Internal Method so that RestClient can increase the number of attempts + + + + + Always send a multipart/form-data request - even when no Files are present. + + + + + Serializer to use when writing JSON request bodies. Used if RequestFormat is Json. + By default the included JsonSerializer is used (currently using JSON.NET default serialization). + + + + + Serializer to use when writing XML request bodies. Used if RequestFormat is Xml. + By default the included XmlSerializer is used. + + + + + Set this to write response to Stream rather than reading into memory. + + + + + Determine whether or not the "default credentials" (e.g. the user account under which the current process is running) + will be sent along to the server. The default is false. + + + + + Container of all HTTP parameters to be passed with the request. + See AddParameter() for explanation of the types of parameters that can be passed + + + + + Container of all the files to be uploaded with the request. + + + + + Determines what HTTP method to use for this request. Supported methods: GET, POST, PUT, DELETE, HEAD, OPTIONS + Default is GET + + + + + The Resource URL to make the request against. + Tokens are substituted with UrlSegment parameters and match by name. + Should not include the scheme or domain. Do not include leading slash. + Combined with RestClient.BaseUrl to assemble final URL: + {BaseUrl}/{Resource} (BaseUrl is scheme + domain, e.g. http://example.com) + + + // example for url token replacement + request.Resource = "Products/{ProductId}"; + request.AddParameter("ProductId", 123, ParameterType.UrlSegment); + + + + + Serializer to use when writing XML request bodies. Used if RequestFormat is Xml. + By default XmlSerializer is used. + + + + + Used by the default deserializers to determine where to start deserializing from. + Can be used to skip container or root elements that do not have corresponding deserialzation targets. + + + + + A function to run prior to deserializing starting (e.g. change settings if error encountered) + + + + + Used by the default deserializers to explicitly set which date format string to use when parsing dates. + + + + + Used by XmlDeserializer. If not specified, XmlDeserializer will flatten response by removing namespaces from element names. + + + + + In general you would not need to set this directly. Used by the NtlmAuthenticator. + + + + + Gets or sets a user-defined state object that contains information about a request and which can be later + retrieved when the request completes. + + + + + Timeout in milliseconds to be used for the request. This timeout value overrides a timeout set on the RestClient. + + + + + The number of milliseconds before the writing or reading times out. This timeout value overrides a timeout set on the RestClient. + + + + + How many attempts were made to send this Request? + + + This Number is incremented each time the RestClient sends the request. + Useful when using Asynchronous Execution with Callbacks + + + + + Base class for common properties shared by RestResponse and RestResponse[[T]] + + + + + Default constructor + + + + + The RestRequest that was made to get this RestResponse + + + Mainly for debugging if ResponseStatus is not OK + + + + + MIME content type of response + + + + + Length in bytes of the response content + + + + + Encoding of the response content + + + + + String representation of response content + + + + + HTTP response status code + + + + + Description of HTTP status returned + + + + + Response content + + + + + The URL that actually responded to the content (different from request if redirected) + + + + + HttpWebResponse.Server + + + + + Cookies returned by server with the response + + + + + Headers returned by server with the response + + + + + Status of the request. Will return Error for transport errors. + HTTP errors will still return ResponseStatus.Completed, check StatusCode instead + + + + + Transport or other non-HTTP error generated while attempting request + + + + + The exception thrown during the request, if any + + + + + Container for data sent back from API including deserialized data + + Type of data to deserialize to + + + + Deserialized entity data + + + + + Container for data sent back from API + + + + + Comment of the cookie + + + + + Comment of the cookie + + + + + Indicates whether the cookie should be discarded at the end of the session + + + + + Domain of the cookie + + + + + Indicates whether the cookie is expired + + + + + Date and time that the cookie expires + + + + + Indicates that this cookie should only be accessed by the server + + + + + Name of the cookie + + + + + Path of the cookie + + + + + Port of the cookie + + + + + Indicates that the cookie should only be sent over secure channels + + + + + Date and time the cookie was created + + + + + Value of the cookie + + + + + Version of the cookie + + + + + Wrapper for System.Xml.Serialization.XmlSerializer. + + + + + Default constructor, does not specify namespace + + + + + Specify the namespaced to be used when serializing + + XML namespace + + + + Serialize the object as XML + + Object to serialize + XML as string + + + + Name of the root element to use when serializing + + + + + XML namespace to use when serializing + + + + + Format string to use when serializing dates + + + + + Content type for serialized content + + + + + Encoding for serialized content + + + + + Need to subclass StringWriter in order to override Encoding + + + + + Default JSON serializer for request bodies + Doesn't currently use the SerializeAs attribute, defers to Newtonsoft's attributes + + + + + Default serializer + + + + + Serialize the object as JSON + + Object to serialize + JSON as String + + + + Unused for JSON Serialization + + + + + Unused for JSON Serialization + + + + + Unused for JSON Serialization + + + + + Content type for serialized content + + + + + Allows control how class and property names and values are serialized by XmlSerializer + Currently not supported with the JsonSerializer + When specified at the property level the class-level specification is overridden + + + + + Called by the attribute when NameStyle is speficied + + The string to transform + String + + + + The name to use for the serialized element + + + + + Sets the value to be serialized as an Attribute instead of an Element + + + + + The culture to use when serializing + + + + + Transforms the casing of the name based on the selected value. + + + + + The order to serialize the element. Default is int.MaxValue. + + + + + Options for transforming casing of element names + + + + + Default XML Serializer + + + + + Default constructor, does not specify namespace + + + + + Specify the namespaced to be used when serializing + + XML namespace + + + + Serialize the object as XML + + Object to serialize + XML as string + + + + Determines if a given object is numeric in any way + (can be integer, double, null, etc). + + + + + Name of the root element to use when serializing + + + + + XML namespace to use when serializing + + + + + Format string to use when serializing dates + + + + + Content type for serialized content + + + + + Helper methods for validating required values + + + + + Require a parameter to not be null + + Name of the parameter + Value of the parameter + + + + Represents the json array. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + The capacity of the json array. + + + + The json representation of the array. + + The json representation of the array. + + + + Represents the json object. + + + + + The internal member dictionary. + + + + + Initializes a new instance of . + + + + + Initializes a new instance of . + + The implementation to use when comparing keys, or null to use the default for the type of the key. + + + + Adds the specified key. + + The key. + The value. + + + + Determines whether the specified key contains key. + + The key. + + true if the specified key contains key; otherwise, false. + + + + + Removes the specified key. + + The key. + + + + + Tries the get value. + + The key. + The value. + + + + + Adds the specified item. + + The item. + + + + Clears this instance. + + + + + Determines whether [contains] [the specified item]. + + The item. + + true if [contains] [the specified item]; otherwise, false. + + + + + Copies to. + + The array. + Index of the array. + + + + Removes the specified item. + + The item. + + + + + Gets the enumerator. + + + + + + Returns an enumerator that iterates through a collection. + + + An object that can be used to iterate through the collection. + + + + + Returns a json that represents the current . + + + A json that represents the current . + + + + + Gets the at the specified index. + + + + + + Gets the keys. + + The keys. + + + + Gets the values. + + The values. + + + + Gets or sets the with the specified key. + + + + + + Gets the count. + + The count. + + + + Gets a value indicating whether this instance is read only. + + + true if this instance is read only; otherwise, false. + + + + + This class encodes and decodes JSON strings. + Spec. details, see http://www.json.org/ + + JSON uses Arrays and Objects. These correspond here to the datatypes JsonArray(IList<object>) and JsonObject(IDictionary<string,object>). + All numbers are parsed to doubles. + + + + + Parses the string json into a value + + A JSON string. + An IList<object>, a IDictionary<string,object>, a double, a string, null, true, or false + + + + Try parsing the json string into a value. + + + A JSON string. + + + The object. + + + Returns true if successfull otherwise false. + + + + + Converts a IDictionary<string,object> / IList<object> object into a JSON string + + A IDictionary<string,object> / IList<object> + Serializer strategy to use + A JSON encoded string, or null if object 'json' is not serializable + + + + Determines if a given object is numeric in any way + (can be integer, double, null, etc). + + + + + Helper methods for validating values + + + + + Validate an integer value is between the specified values (exclusive of min/max) + + Value to validate + Exclusive minimum value + Exclusive maximum value + + + + Validate a string length + + String to be validated + Maximum length of the string + + + diff --git a/bin/config-include/osslEnable.ini b/bin/config-include/osslEnable.ini index 45eddf748e..dca1c0cdaf 100644 --- a/bin/config-include/osslEnable.ini +++ b/bin/config-include/osslEnable.ini @@ -236,4 +236,5 @@ Allow_osKickAvatar = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osRevokeScriptPermissions = false Allow_osTeleportAgent = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osTeleportObject = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER diff --git a/bin/lib32/libode.so b/bin/lib32/libode.so index daf6a4d1b0..3e08c42d89 100755 Binary files a/bin/lib32/libode.so and b/bin/lib32/libode.so differ diff --git a/bin/lib32/ode.dll b/bin/lib32/ode.dll index 62aa4df9c4..ddffcb3561 100755 Binary files a/bin/lib32/ode.dll and b/bin/lib32/ode.dll differ diff --git a/bin/lib64/libode-x86_64.so b/bin/lib64/libode-x86_64.so index d8f3c20ec4..2f616dde65 100755 Binary files a/bin/lib64/libode-x86_64.so and b/bin/lib64/libode-x86_64.so differ diff --git a/bin/lib64/ode.dll b/bin/lib64/ode.dll index 543b900026..0d6edbee13 100755 Binary files a/bin/lib64/ode.dll and b/bin/lib64/ode.dll differ diff --git a/bin/netcd.dll b/bin/netcd.dll new file mode 100644 index 0000000000..d1f7330d9e Binary files /dev/null and b/bin/netcd.dll differ diff --git a/prebuild.xml b/prebuild.xml index cb39e18e16..c087def826 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -497,6 +497,7 @@ + @@ -1464,6 +1465,7 @@ +