diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index f4e1db4cdb..3c7727f738 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -360,7 +360,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController && ((string) requestData["shutdown"] == "delayed") && requestData.ContainsKey("milliseconds")) { - timeout = (Int32) requestData["milliseconds"]; + timeout = Int32.Parse(requestData["milliseconds"].ToString()); message = "Region is going down in " + ((int) (timeout/1000)).ToString() diff --git a/OpenSim/Client/Linden/LLStandaloneLoginModule.cs b/OpenSim/Client/Linden/LLStandaloneLoginModule.cs index bb9b62315e..8739ce5e52 100644 --- a/OpenSim/Client/Linden/LLStandaloneLoginModule.cs +++ b/OpenSim/Client/Linden/LLStandaloneLoginModule.cs @@ -231,6 +231,10 @@ namespace OpenSim.Client.Linden { return scene.RegionInfo; } + else if (m_scenes.Count > 0) + { + return m_scenes[0].RegionInfo; + } return null; } diff --git a/OpenSim/Client/MXP/MXPModule.cs b/OpenSim/Client/MXP/MXPModule.cs index a6b039656c..0b442cca15 100644 --- a/OpenSim/Client/MXP/MXPModule.cs +++ b/OpenSim/Client/MXP/MXPModule.cs @@ -110,8 +110,11 @@ namespace OpenSim.Client.MXP public void Close() { m_shutdown = true; - lock (m_ticker) - m_ticker.Stop(); + if (m_ticker != null) + { + lock (m_ticker) + m_ticker.Stop(); + } } public string Name diff --git a/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs b/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs index 0e21880abd..93e48cd8ce 100644 --- a/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs +++ b/OpenSim/Data/MSSQL/AutoClosingSqlCommand.cs @@ -197,11 +197,20 @@ namespace OpenSim.Data.MSSQL public void Dispose() { SqlConnection conn = realCommand.Connection; - try { realCommand.Dispose(); } + try + { + realCommand.Dispose(); + } finally { - try { conn.Dispose(); } - finally { } + try + { + conn.Close(); + } + finally + { + conn.Dispose(); + } } } diff --git a/OpenSim/Data/MSSQL/MSSQLInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLInventoryData.cs index d49c2b304e..1482184402 100644 --- a/OpenSim/Data/MSSQL/MSSQLInventoryData.cs +++ b/OpenSim/Data/MSSQL/MSSQLInventoryData.cs @@ -348,6 +348,8 @@ namespace OpenSim.Data.MSSQL //Delete the actual row DeleteOneFolder(folderID, connection); DeleteItemsInFolder(folderID, connection); + + connection.Close(); } } diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index cff6b00042..6371307fa2 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -1049,7 +1049,7 @@ VALUES if (!(primRow["ParticleSystem"] is DBNull)) prim.ParticleSystem = (Byte[])primRow["ParticleSystem"]; - prim.RotationalVelocity = new Vector3( + prim.AngularVelocity = new Vector3( Convert.ToSingle(primRow["OmegaX"]), Convert.ToSingle(primRow["OmegaY"]), Convert.ToSingle(primRow["OmegaZ"])); @@ -1429,9 +1429,9 @@ VALUES parameters.Add(_Database.CreateParameter("TextureAnimation", prim.TextureAnimation)); parameters.Add(_Database.CreateParameter("ParticleSystem", prim.ParticleSystem)); - parameters.Add(_Database.CreateParameter("OmegaX", prim.RotationalVelocity.X)); - parameters.Add(_Database.CreateParameter("OmegaY", prim.RotationalVelocity.Y)); - parameters.Add(_Database.CreateParameter("OmegaZ", prim.RotationalVelocity.Z)); + parameters.Add(_Database.CreateParameter("OmegaX", prim.AngularVelocity.X)); + parameters.Add(_Database.CreateParameter("OmegaY", prim.AngularVelocity.Y)); + parameters.Add(_Database.CreateParameter("OmegaZ", prim.AngularVelocity.Z)); parameters.Add(_Database.CreateParameter("CameraEyeOffsetX", prim.GetCameraEyeOffset().X)); parameters.Add(_Database.CreateParameter("CameraEyeOffsetY", prim.GetCameraEyeOffset().Y)); diff --git a/OpenSim/Data/MSSQL/MSSQLManager.cs b/OpenSim/Data/MSSQL/MSSQLManager.cs index 992ce023d6..3d7a76882f 100644 --- a/OpenSim/Data/MSSQL/MSSQLManager.cs +++ b/OpenSim/Data/MSSQL/MSSQLManager.cs @@ -340,6 +340,8 @@ namespace OpenSim.Data.MSSQL MSSQLMigration migration = new MSSQLMigration(connection, assem, migrationStore); migration.Update(); + + connection.Close(); } } @@ -383,7 +385,9 @@ namespace OpenSim.Data.MSSQL m_log.Error(e.ToString()); } } + tables.Close(); } + } /// diff --git a/OpenSim/Data/MSSQL/MSSQLMigration.cs b/OpenSim/Data/MSSQL/MSSQLMigration.cs index 549bcb33bb..aea31c9eaa 100644 --- a/OpenSim/Data/MSSQL/MSSQLMigration.cs +++ b/OpenSim/Data/MSSQL/MSSQLMigration.cs @@ -56,6 +56,7 @@ namespace OpenSim.Data.MSSQL { version = Convert.ToInt32(reader["version"]); } + reader.Close(); } } catch diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs index 7a99d4a827..e51dc22d94 100644 --- a/OpenSim/Data/Migration.cs +++ b/OpenSim/Data/Migration.cs @@ -131,26 +131,25 @@ namespace OpenSim.Data m_log.InfoFormat("[MIGRATIONS] Upgrading {0} to latest revision.", _type); m_log.Info("[MIGRATIONS] NOTE: this may take a while, don't interupt this process!"); - using (DbCommand cmd = _conn.CreateCommand()) + DbCommand cmd = _conn.CreateCommand(); + foreach (KeyValuePair kvp in migrations) { - foreach (KeyValuePair kvp in migrations) - { - int newversion = kvp.Key; - cmd.CommandText = kvp.Value; - // we need to up the command timeout to infinite as we might be doing long migrations. - cmd.CommandTimeout = 0; - cmd.ExecuteNonQuery(); + int newversion = kvp.Key; + cmd.CommandText = kvp.Value; + // we need to up the command timeout to infinite as we might be doing long migrations. + cmd.CommandTimeout = 0; + cmd.ExecuteNonQuery(); - if (version == 0) - { - InsertVersion(_type, newversion); - } - else - { - UpdateVersion(_type, newversion); - } - version = newversion; + if (version == 0) + { + InsertVersion(_type, newversion); } + else + { + UpdateVersion(_type, newversion); + } + version = newversion; + cmd.Dispose(); } } @@ -190,45 +189,43 @@ namespace OpenSim.Data protected virtual int FindVersion(DbConnection conn, string type) { int version = 0; - - using (DbCommand cmd = conn.CreateCommand()) + DbCommand cmd = conn.CreateCommand(); + try { - try + cmd.CommandText = "select version from migrations where name='" + type +"' order by version desc"; + using (IDataReader reader = cmd.ExecuteReader()) { - cmd.CommandText = "select version from migrations where name='" + type + "' order by version desc"; - using (IDataReader reader = cmd.ExecuteReader()) + if (reader.Read()) { - if (reader.Read()) - version = Convert.ToInt32(reader["version"]); + version = Convert.ToInt32(reader["version"]); } - } - catch - { - // Something went wrong, so we're version 0 + reader.Close(); } } - + catch + { + // Something went wrong, so we're version 0 + } + cmd.Dispose(); return version; } private void InsertVersion(string type, int version) { - using (DbCommand cmd = _conn.CreateCommand()) - { - cmd.CommandText = "insert into migrations(name, version) values('" + type + "', " + version + ")"; - m_log.InfoFormat("[MIGRATIONS]: Creating {0} at version {1}", type, version); - cmd.ExecuteNonQuery(); - } + DbCommand cmd = _conn.CreateCommand(); + cmd.CommandText = "insert into migrations(name, version) values('" + type + "', " + version + ")"; + m_log.InfoFormat("[MIGRATIONS]: Creating {0} at version {1}", type, version); + cmd.ExecuteNonQuery(); + cmd.Dispose(); } private void UpdateVersion(string type, int version) { - using (DbCommand cmd = _conn.CreateCommand()) - { - cmd.CommandText = "update migrations set version=" + version + " where name='" + type + "'"; - m_log.InfoFormat("[MIGRATIONS]: Updating {0} to version {1}", type, version); - cmd.ExecuteNonQuery(); - } + DbCommand cmd = _conn.CreateCommand(); + cmd.CommandText = "update migrations set version=" + version + " where name='" + type + "'"; + m_log.InfoFormat("[MIGRATIONS]: Updating {0} to version {1}", type, version); + cmd.ExecuteNonQuery(); + cmd.Dispose(); } // private SortedList GetAllMigrations() diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index 4d49733350..1fe6d2953d 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -139,42 +139,45 @@ namespace OpenSim.Data.MySQL { _dbConnection.CheckConnection(); - using (MySqlCommand cmd = new MySqlCommand( - "SELECT name, description, assetType, local, temporary, data FROM assets WHERE id=?id", - _dbConnection.Connection)) + MySqlCommand cmd = + new MySqlCommand( + "SELECT name, description, assetType, local, temporary, data FROM assets WHERE id=?id", + _dbConnection.Connection); + cmd.Parameters.AddWithValue("?id", assetID.ToString()); + + try { - cmd.Parameters.AddWithValue("?id", assetID.ToString()); - - try + using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { - using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + if (dbReader.Read()) { - if (dbReader.Read()) - { - asset = new AssetBase(); - asset.Data = (byte[])dbReader["data"]; - asset.Description = (string)dbReader["description"]; - asset.FullID = assetID; + asset = new AssetBase(); + asset.Data = (byte[]) dbReader["data"]; + asset.Description = (string) dbReader["description"]; + asset.FullID = assetID; - string local = dbReader["local"].ToString(); - if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) - asset.Local = true; - else - asset.Local = false; + string local = dbReader["local"].ToString(); + if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) + asset.Local = true; + else + asset.Local = false; - asset.Name = (string)dbReader["name"]; - asset.Type = (sbyte)dbReader["assetType"]; - asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); - } + asset.Name = (string) dbReader["name"]; + asset.Type = (sbyte) dbReader["assetType"]; + asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); } + dbReader.Close(); + cmd.Dispose(); } - catch (Exception e) - { - m_log.ErrorFormat( - "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString() - + Environment.NewLine + "Reconnecting", assetID); - _dbConnection.Reconnect(); - } + if (asset != null) + UpdateAccessTime(asset); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString() + + Environment.NewLine + "Reconnecting", assetID); + _dbConnection.Reconnect(); } } return asset; @@ -291,27 +294,32 @@ namespace OpenSim.Data.MySQL { _dbConnection.CheckConnection(); - using (MySqlCommand cmd = new MySqlCommand( - "SELECT id FROM assets WHERE id=?id", - _dbConnection.Connection)) - { - cmd.Parameters.AddWithValue("?id", uuid.ToString()); + MySqlCommand cmd = + new MySqlCommand( + "SELECT id FROM assets WHERE id=?id", + _dbConnection.Connection); - try + cmd.Parameters.AddWithValue("?id", uuid.ToString()); + + try + { + using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { - using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + if (dbReader.Read()) { - if (dbReader.Read()) - assetExists = true; + assetExists = true; } + + dbReader.Close(); + cmd.Dispose(); } - catch (Exception e) - { - m_log.ErrorFormat( - "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString() - + Environment.NewLine + "Attempting reconnection", uuid); - _dbConnection.Reconnect(); - } + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString() + + Environment.NewLine + "Attempting reconnection", uuid); + _dbConnection.Reconnect(); } } diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index 0780936d9c..e508b5285b 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -55,7 +55,9 @@ namespace OpenSim.Data.MySQL AuthenticationData ret = new AuthenticationData(); ret.Data = new Dictionary(); - MySqlCommand cmd = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID"); + MySqlCommand cmd = new MySqlCommand( + "select * from `"+m_Realm+"` where UUID = ?principalID" + ); cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); @@ -82,14 +84,16 @@ namespace OpenSim.Data.MySQL ret.Data[s] = result[s].ToString(); } - CloseDBConnection(result, cmd); + result.Close(); + CloseReaderCommand(cmd); + return ret; } - else - { - CloseDBConnection(result, cmd); - return null; - } + + result.Close(); + CloseReaderCommand(cmd); + + return null; } public bool Store(AuthenticationData data) diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs index 7166b29e8f..e8694fcd50 100644 --- a/OpenSim/Data/MySQL/MySQLEstateData.cs +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs @@ -95,17 +95,21 @@ namespace OpenSim.Data.MySQL protected void GetWaitTimeout() { - using (MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, m_connection)) + MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, + m_connection); + + using (MySqlDataReader dbReader = + cmd.ExecuteReader(CommandBehavior.SingleRow)) { - using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + if (dbReader.Read()) { - if (dbReader.Read()) - { - m_waitTimeout - = Convert.ToInt32(dbReader["@@wait_timeout"]) * - TimeSpan.TicksPerSecond + m_waitTimeoutLeeway; - } + m_waitTimeout + = Convert.ToInt32(dbReader["@@wait_timeout"]) * + TimeSpan.TicksPerSecond + m_waitTimeoutLeeway; } + + dbReader.Close(); + cmd.Dispose(); } m_lastConnectionUse = DateTime.Now.Ticks; @@ -143,122 +147,53 @@ namespace OpenSim.Data.MySQL CheckConnection(); - bool migration = true; + MySqlCommand cmd = m_connection.CreateCommand(); - using (MySqlCommand cmd = m_connection.CreateCommand()) + cmd.CommandText = sql; + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); + + IDataReader r = cmd.ExecuteReader(); + + if (r.Read()) { - cmd.CommandText = sql; - cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); - - using (IDataReader r = cmd.ExecuteReader()) + foreach (string name in FieldList) { - if (r.Read()) + if (m_FieldMap[name].GetValue(es) is bool) { - migration = false; + int v = Convert.ToInt32(r[name]); + if (v != 0) + m_FieldMap[name].SetValue(es, true); + else + m_FieldMap[name].SetValue(es, false); + } + else if (m_FieldMap[name].GetValue(es) is UUID) + { + UUID uuid = UUID.Zero; - foreach (string name in FieldList) - { - if (m_FieldMap[name].GetValue(es) is bool) - { - int v = Convert.ToInt32(r[name]); - if (v != 0) - m_FieldMap[name].SetValue(es, true); - else - m_FieldMap[name].SetValue(es, false); - } - else if (m_FieldMap[name].GetValue(es) is UUID) - { - UUID uuid = UUID.Zero; - - UUID.TryParse(r[name].ToString(), out uuid); - m_FieldMap[name].SetValue(es, uuid); - } - else - { - m_FieldMap[name].SetValue(es, r[name]); - } - } + UUID.TryParse(r[name].ToString(), out uuid); + m_FieldMap[name].SetValue(es, uuid); + } + else + { + m_FieldMap[name].SetValue(es, r[name]); } } + r.Close(); } - - if (migration) + else { // Migration case + // + r.Close(); + List names = new List(FieldList); names.Remove("EstateID"); sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")"; - using (MySqlCommand cmd = m_connection.CreateCommand()) - { - cmd.CommandText = sql; - cmd.Parameters.Clear(); - - foreach (string name in FieldList) - { - if (m_FieldMap[name].GetValue(es) is bool) - { - if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.AddWithValue("?" + name, "1"); - else - cmd.Parameters.AddWithValue("?" + name, "0"); - } - else - { - cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); - } - } - - cmd.ExecuteNonQuery(); - - cmd.CommandText = "select LAST_INSERT_ID() as id"; - cmd.Parameters.Clear(); - - using (IDataReader r = cmd.ExecuteReader()) - { - r.Read(); - es.EstateID = Convert.ToUInt32(r["id"]); - } - - cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; - cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); - cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); - - // This will throw on dupe key - try { cmd.ExecuteNonQuery(); } - catch (Exception) { } - - // Munge and transfer the ban list - cmd.Parameters.Clear(); - cmd.CommandText = "insert into estateban select " + es.EstateID.ToString() + ", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = ?UUID"; - cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); - - try { cmd.ExecuteNonQuery(); } - catch (Exception) { } - - es.Save(); - } - } - - LoadBanList(es); - - es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); - es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); - es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); - return es; - } - - public void StoreEstateSettings(EstateSettings es) - { - string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")"; - - CheckConnection(); - - using (MySqlCommand cmd = m_connection.CreateCommand()) - { cmd.CommandText = sql; + cmd.Parameters.Clear(); foreach (string name in FieldList) { @@ -276,8 +211,83 @@ namespace OpenSim.Data.MySQL } cmd.ExecuteNonQuery(); + + cmd.CommandText = "select LAST_INSERT_ID() as id"; + cmd.Parameters.Clear(); + + r = cmd.ExecuteReader(); + + r.Read(); + + es.EstateID = Convert.ToUInt32(r["id"]); + + r.Close(); + + cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); + + // This will throw on dupe key + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception) + { + } + + // Munge and transfer the ban list + // + cmd.Parameters.Clear(); + cmd.CommandText = "insert into estateban select " + es.EstateID.ToString() + ", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = ?UUID"; + cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); + + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception) + { + } + + es.Save(); } + LoadBanList(es); + + es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); + es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); + es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); + return es; + } + + public void StoreEstateSettings(EstateSettings es) + { + string sql = "replace into estate_settings (" + String.Join(",", FieldList) + ") values ( ?" + String.Join(", ?", FieldList) + ")"; + + CheckConnection(); + + MySqlCommand cmd = m_connection.CreateCommand(); + + cmd.CommandText = sql; + + foreach (string name in FieldList) + { + if (m_FieldMap[name].GetValue(es) is bool) + { + if ((bool)m_FieldMap[name].GetValue(es)) + cmd.Parameters.AddWithValue("?" + name, "1"); + else + cmd.Parameters.AddWithValue("?" + name, "0"); + } + else + { + cmd.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString()); + } + } + + cmd.ExecuteNonQuery(); + SaveBanList(es); SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers); SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess); @@ -290,52 +300,50 @@ namespace OpenSim.Data.MySQL CheckConnection(); - using (MySqlCommand cmd = m_connection.CreateCommand()) + MySqlCommand cmd = m_connection.CreateCommand(); + + cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", es.EstateID); + + IDataReader r = cmd.ExecuteReader(); + + while (r.Read()) { - cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID"; - cmd.Parameters.AddWithValue("?EstateID", es.EstateID); + EstateBan eb = new EstateBan(); - using (IDataReader r = cmd.ExecuteReader()) - { - while (r.Read()) - { - EstateBan eb = new EstateBan(); + UUID uuid = new UUID(); + UUID.TryParse(r["bannedUUID"].ToString(), out uuid); - UUID uuid = new UUID(); - UUID.TryParse(r["bannedUUID"].ToString(), out uuid); - - eb.BannedUserID = uuid; - eb.BannedHostAddress = "0.0.0.0"; - eb.BannedHostIPMask = "0.0.0.0"; - es.AddBan(eb); - } - } + eb.BannedUserID = uuid; + eb.BannedHostAddress = "0.0.0.0"; + eb.BannedHostIPMask = "0.0.0.0"; + es.AddBan(eb); } + r.Close(); } private void SaveBanList(EstateSettings es) { CheckConnection(); - using (MySqlCommand cmd = m_connection.CreateCommand()) + MySqlCommand cmd = m_connection.CreateCommand(); + + cmd.CommandText = "delete from estateban where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); + + cmd.ExecuteNonQuery(); + + cmd.Parameters.Clear(); + + cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )"; + + foreach (EstateBan b in es.EstateBans) { - cmd.CommandText = "delete from estateban where EstateID = ?EstateID"; cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString()); cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); - - cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )"; - - foreach (EstateBan b in es.EstateBans) - { - cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString()); - cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString()); - - cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); - } } } @@ -343,25 +351,24 @@ namespace OpenSim.Data.MySQL { CheckConnection(); - using (MySqlCommand cmd = m_connection.CreateCommand()) + MySqlCommand cmd = m_connection.CreateCommand(); + + cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); + + cmd.ExecuteNonQuery(); + + cmd.Parameters.Clear(); + + cmd.CommandText = "insert into " + table + " (EstateID, uuid) values ( ?EstateID, ?uuid )"; + + foreach (UUID uuid in data) { - cmd.CommandText = "delete from " + table + " where EstateID = ?EstateID"; cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); + cmd.Parameters.AddWithValue("?uuid", uuid.ToString()); cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); - - cmd.CommandText = "insert into " + table + " (EstateID, uuid) values ( ?EstateID, ?uuid )"; - - foreach (UUID uuid in data) - { - cmd.Parameters.AddWithValue("?EstateID", EstateID.ToString()); - cmd.Parameters.AddWithValue("?uuid", uuid.ToString()); - - cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); - } } } @@ -371,24 +378,23 @@ namespace OpenSim.Data.MySQL CheckConnection(); - using (MySqlCommand cmd = m_connection.CreateCommand()) + MySqlCommand cmd = m_connection.CreateCommand(); + + cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", EstateID); + + IDataReader r = cmd.ExecuteReader(); + + while (r.Read()) { - cmd.CommandText = "select uuid from " + table + " where EstateID = ?EstateID"; - cmd.Parameters.AddWithValue("?EstateID", EstateID); + // EstateBan eb = new EstateBan(); - using (IDataReader r = cmd.ExecuteReader()) - { - while (r.Read()) - { - // EstateBan eb = new EstateBan(); + UUID uuid = new UUID(); + UUID.TryParse(r["uuid"].ToString(), out uuid); - UUID uuid = new UUID(); - UUID.TryParse(r["uuid"].ToString(), out uuid); - - uuids.Add(uuid); - } - } + uuids.Add(uuid); } + r.Close(); return uuids.ToArray(); } diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index ccd1ab0ed9..fca0ca5e8a 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -40,10 +40,6 @@ namespace OpenSim.Data.MySQL /// public class MySqlFramework { - private static readonly log4net.ILog m_log = - log4net.LogManager.GetLogger( - System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - protected MySqlConnection m_Connection; protected MySqlFramework(string connectionString) @@ -73,11 +69,11 @@ namespace OpenSim.Data.MySQL } catch (MySqlException e) { - m_log.Error(e.Message, e); if (errorSeen) throw; // This is "Server has gone away" and "Server lost" + // if (e.Number == 2006 || e.Number == 2013) { errorSeen = true; @@ -96,7 +92,6 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.Error(e.Message, e); return 0; } } @@ -113,11 +108,11 @@ namespace OpenSim.Data.MySQL return cmd.ExecuteReader(); } - protected void CloseDBConnection(IDataReader reader, MySqlCommand cmd) + protected void CloseReaderCommand(MySqlCommand cmd) { - reader.Close(); cmd.Connection.Close(); cmd.Connection.Dispose(); + cmd.Dispose(); } } } diff --git a/OpenSim/Data/MySQL/MySQLGridData.cs b/OpenSim/Data/MySQL/MySQLGridData.cs index 38cb3b75b3..1ec26090b1 100644 --- a/OpenSim/Data/MySQL/MySQLGridData.cs +++ b/OpenSim/Data/MySQL/MySQLGridData.cs @@ -197,27 +197,29 @@ namespace OpenSim.Data.MySQL param["?xmax"] = xmax.ToString(); param["?ymax"] = ymax.ToString(); - using (IDbCommand result = dbm.Manager.Query( + IDbCommand result = + dbm.Manager.Query( "SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax", - param)) + param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row; + + List rows = new List(); + + while ((row = dbm.Manager.readSimRow(reader)) != null) { - using (IDataReader reader = result.ExecuteReader()) - { - RegionProfileData row; - - List rows = new List(); - - while ((row = dbm.Manager.readSimRow(reader)) != null) - rows.Add(row); - - return rows.ToArray(); - } + rows.Add(row); } + reader.Close(); + result.Dispose(); + + return rows.ToArray(); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -241,27 +243,29 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?name"] = namePrefix + "%"; - using (IDbCommand result = dbm.Manager.Query( - "SELECT * FROM regions WHERE regionName LIKE ?name", - param)) + IDbCommand result = + dbm.Manager.Query( + "SELECT * FROM regions WHERE regionName LIKE ?name", + param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row; + + List rows = new List(); + + while (rows.Count < maxNum && (row = dbm.Manager.readSimRow(reader)) != null) { - using (IDataReader reader = result.ExecuteReader()) - { - RegionProfileData row; - - List rows = new List(); - - while (rows.Count < maxNum && (row = dbm.Manager.readSimRow(reader)) != null) - rows.Add(row); - - return rows; - } + rows.Add(row); } + reader.Close(); + result.Dispose(); + + return rows; } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -282,21 +286,21 @@ namespace OpenSim.Data.MySQL try { Dictionary param = new Dictionary(); - param["?handle"] = handle.ToString(); + param["?handle"] = handle.ToString(); - using (IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - RegionProfileData row = dbm.Manager.readSimRow(reader); - return row; - } + IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row = dbm.Manager.readSimRow(reader); + reader.Close(); + result.Dispose(); + + return row; } - } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -317,24 +321,23 @@ namespace OpenSim.Data.MySQL try { Dictionary param = new Dictionary(); - param["?uuid"] = uuid.ToString(); + param["?uuid"] = uuid.ToString(); - using (IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE uuid = ?uuid", param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - RegionProfileData row = dbm.Manager.readSimRow(reader); - return row; - } + IDbCommand result = dbm.Manager.Query("SELECT * FROM regions WHERE uuid = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row = dbm.Manager.readSimRow(reader); + reader.Close(); + result.Dispose(); + + return row; } - } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; - } - finally + } finally { dbm.Release(); } @@ -356,21 +359,22 @@ namespace OpenSim.Data.MySQL // Add % because this is a like query. param["?regionName"] = regionName + "%"; // Order by statement will return shorter matches first. Only returns one record or no record. - using (IDbCommand result = dbm.Manager.Query( - "SELECT * FROM regions WHERE regionName like ?regionName order by LENGTH(regionName) asc LIMIT 1", - param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - RegionProfileData row = dbm.Manager.readSimRow(reader); - return row; - } - } + IDbCommand result = + dbm.Manager.Query( + "SELECT * FROM regions WHERE regionName like ?regionName order by LENGTH(regionName) asc LIMIT 1", + param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row = dbm.Manager.readSimRow(reader); + reader.Close(); + result.Dispose(); + + return row; } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -378,7 +382,6 @@ namespace OpenSim.Data.MySQL dbm.Release(); } } - m_log.Error("[GRID DB]: Searched for a Region Name shorter then 3 characters"); return null; } @@ -391,12 +394,12 @@ namespace OpenSim.Data.MySQL override public DataResponse StoreProfile(RegionProfileData profile) { MySQLSuperManager dbm = GetLockedConnection(); - try - { + try { if (dbm.Manager.insertRegion(profile)) + { return DataResponse.RESPONSE_OK; - else - return DataResponse.RESPONSE_ERROR; + } + return DataResponse.RESPONSE_ERROR; } finally { @@ -414,14 +417,14 @@ namespace OpenSim.Data.MySQL { MySQLSuperManager dbm = GetLockedConnection(); - try - { + + try { if (dbm.Manager.deleteRegion(uuid)) + { return DataResponse.RESPONSE_OK; - else - return DataResponse.RESPONSE_ERROR; - } - finally + } + return DataResponse.RESPONSE_ERROR; + } finally { dbm.Release(); } @@ -479,26 +482,26 @@ namespace OpenSim.Data.MySQL try { Dictionary param = new Dictionary(); - param["?x"] = x.ToString(); - param["?y"] = y.ToString(); - using (IDbCommand result = dbm.Manager.Query( - "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y", - param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - ReservationData row = dbm.Manager.readReservationRow(reader); - return row; - } - } + param["?x"] = x.ToString(); + param["?y"] = y.ToString(); + IDbCommand result = + dbm.Manager.Query( + "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y", + param); + IDataReader reader = result.ExecuteReader(); + + ReservationData row = dbm.Manager.readReservationRow(reader); + reader.Close(); + result.Dispose(); + + return row; } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; - } - finally + } finally { dbm.Release(); } diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index 598971d680..0eecf06642 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -135,30 +135,30 @@ namespace OpenSim.Data.MySQL database.CheckConnection(); - using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", - database.Connection)) + MySqlCommand result = + new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", folderID.ToString()); + MySqlDataReader reader = result.ExecuteReader(); + + while (reader.Read()) { - result.Parameters.AddWithValue("?uuid", folderID.ToString()); - - using (MySqlDataReader reader = result.ExecuteReader()) - { - while (reader.Read()) - { - // A null item (because something went wrong) breaks everything in the folder - InventoryItemBase item = readInventoryItem(reader); - if (item != null) - items.Add(item); - } - - return items; - } + // A null item (because something went wrong) breaks everything in the folder + InventoryItemBase item = readInventoryItem(reader); + if (item != null) + items.Add(item); } + + reader.Close(); + result.Dispose(); + + return items; } } catch (Exception e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } } @@ -176,28 +176,29 @@ namespace OpenSim.Data.MySQL { database.CheckConnection(); - using (MySqlCommand result = new MySqlCommand( - "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", - database.Connection)) - { - result.Parameters.AddWithValue("?uuid", user.ToString()); - result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); + MySqlCommand result = + new MySqlCommand( + "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", user.ToString()); + result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); + MySqlDataReader reader = result.ExecuteReader(); - using (MySqlDataReader reader = result.ExecuteReader()) - { - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); + List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); - return items; - } - } + + reader.Close(); + result.Dispose(); + + return items; } } catch (Exception e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } } @@ -216,38 +217,41 @@ namespace OpenSim.Data.MySQL { database.CheckConnection(); - using (MySqlCommand result = new MySqlCommand( - "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", - database.Connection)) + MySqlCommand result = + new MySqlCommand( + "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", user.ToString()); + result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); + + MySqlDataReader reader = result.ExecuteReader(); + + List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + InventoryFolderBase rootFolder = null; + + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. + if (items.Count > 0) { - result.Parameters.AddWithValue("?uuid", user.ToString()); - result.Parameters.AddWithValue("?zero", UUID.Zero.ToString()); - - using (MySqlDataReader reader = result.ExecuteReader()) - { - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - InventoryFolderBase rootFolder = null; - - // There should only ever be one root folder for a user. However, if there's more - // than one we'll simply use the first one rather than failing. It would be even - // nicer to print some message to this effect, but this feels like it's too low a - // to put such a message out, and it's too minor right now to spare the time to - // suitably refactor. - if (items.Count > 0) - rootFolder = items[0]; - - return rootFolder; - } + rootFolder = items[0]; } + + reader.Close(); + result.Dispose(); + + return rootFolder; } } catch (Exception e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } } @@ -267,26 +271,27 @@ namespace OpenSim.Data.MySQL { database.CheckConnection(); - using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", - database.Connection)) - { - result.Parameters.AddWithValue("?uuid", parentID.ToString()); - using (MySqlDataReader reader = result.ExecuteReader()) - { - List items = new List(); + MySqlCommand result = + new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", parentID.ToString()); + MySqlDataReader reader = result.ExecuteReader(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); + List items = new List(); - return items; - } - } + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + reader.Close(); + result.Dispose(); + + return items; } } catch (Exception e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } } @@ -365,25 +370,25 @@ namespace OpenSim.Data.MySQL { database.CheckConnection(); - using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection)) - { - result.Parameters.AddWithValue("?uuid", itemID.ToString()); + MySqlCommand result = + new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection); + result.Parameters.AddWithValue("?uuid", itemID.ToString()); + MySqlDataReader reader = result.ExecuteReader(); - using (MySqlDataReader reader = result.ExecuteReader()) - { - InventoryItemBase item = null; - if (reader.Read()) - item = readInventoryItem(reader); + InventoryItemBase item = null; + if (reader.Read()) + item = readInventoryItem(reader); - return item; - } - } + reader.Close(); + result.Dispose(); + + return item; } } catch (Exception e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); } return null; } @@ -408,7 +413,7 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); } return null; @@ -428,25 +433,24 @@ namespace OpenSim.Data.MySQL { database.CheckConnection(); - using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection)) - { - result.Parameters.AddWithValue("?uuid", folderID.ToString()); + MySqlCommand result = + new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection); + result.Parameters.AddWithValue("?uuid", folderID.ToString()); + MySqlDataReader reader = result.ExecuteReader(); - using (MySqlDataReader reader = result.ExecuteReader()) - { - InventoryFolderBase folder = null; - if (reader.Read()) - folder = readInventoryFolder(reader); + InventoryFolderBase folder = null; + if (reader.Read()) + folder = readInventoryFolder(reader); + reader.Close(); + result.Dispose(); - return folder; - } - } + return folder; } } catch (Exception e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } } @@ -694,73 +698,69 @@ namespace OpenSim.Data.MySQL try { List folders = new List(); - Dictionary> hashtable = new Dictionary>(); ; + Dictionary> hashtable + = new Dictionary>(); ; List parentFolder = new List(); - bool buildResultsFromHashTable = false; - lock (database) { + MySqlCommand result; + MySqlDataReader reader; + bool buildResultsFromHashTable = false; + database.CheckConnection(); /* Fetch the parent folder from the database to determine the agent ID, and if * we're querying the root of the inventory folder tree */ - using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection)) - { - result.Parameters.AddWithValue("?uuid", parentID.ToString()); - - using (MySqlDataReader reader = result.ExecuteReader()) - { - // Should be at most 1 result - while (reader.Read()) - parentFolder.Add(readInventoryFolder(reader)); - } - } + result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", parentID.ToString()); + reader = result.ExecuteReader(); + while (reader.Read()) // Should be at most 1 result + parentFolder.Add(readInventoryFolder(reader)); + reader.Close(); + result.Dispose(); if (parentFolder.Count >= 1) // No result means parent folder does not exist { if (parentFolder[0].ParentID == UUID.Zero) // We are querying the root folder { /* Get all of the agent's folders from the database, put them in a list and return it */ - using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", database.Connection)) + result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); + reader = result.ExecuteReader(); + while (reader.Read()) { - result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); - - using (MySqlDataReader reader = result.ExecuteReader()) - { - while (reader.Read()) - { - InventoryFolderBase curFolder = readInventoryFolder(reader); - if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list - folders.Add(curFolder); - } - } + InventoryFolderBase curFolder = readInventoryFolder(reader); + if (curFolder.ID != parentID) // Do not need to add the root node of the tree to the list + folders.Add(curFolder); } + reader.Close(); + result.Dispose(); } // if we are querying the root folder else // else we are querying a subtree of the inventory folder tree { /* Get all of the agent's folders from the database, put them all in a hash table * indexed by their parent ID */ - using (MySqlCommand result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", database.Connection)) + result = new MySqlCommand("SELECT * FROM inventoryfolders WHERE agentID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); + reader = result.ExecuteReader(); + while (reader.Read()) { - result.Parameters.AddWithValue("?uuid", parentFolder[0].Owner.ToString()); - - using (MySqlDataReader reader = result.ExecuteReader()) + InventoryFolderBase curFolder = readInventoryFolder(reader); + if (hashtable.ContainsKey(curFolder.ParentID)) // Current folder already has a sibling + hashtable[curFolder.ParentID].Add(curFolder); // append to sibling list + else // else current folder has no known (yet) siblings { - while (reader.Read()) - { - InventoryFolderBase curFolder = readInventoryFolder(reader); - if (hashtable.ContainsKey(curFolder.ParentID)) // Current folder already has a sibling - hashtable[curFolder.ParentID].Add(curFolder); // append to sibling list - else // else current folder has no known (yet) siblings - { - List siblingList = new List(); - siblingList.Add(curFolder); - // Current folder has no known (yet) siblings - hashtable.Add(curFolder.ParentID, siblingList); - } - } // while more items to read from the database + List siblingList = new List(); + siblingList.Add(curFolder); + // Current folder has no known (yet) siblings + hashtable.Add(curFolder.ParentID, siblingList); } - } + } // while more items to read from the database + reader.Close(); + result.Dispose(); // Set flag so we know we need to build the results from the hash table after // we unlock the database @@ -781,13 +781,12 @@ namespace OpenSim.Data.MySQL folders.AddRange(hashtable[folders[i].ID]); } } // lock (database) - return folders; } catch (Exception e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } } @@ -802,18 +801,19 @@ namespace OpenSim.Data.MySQL { database.CheckConnection(); - using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection)) - { - cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); + MySqlCommand cmd = + new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection); + cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); - lock (database) - cmd.ExecuteNonQuery(); + lock (database) + { + cmd.ExecuteNonQuery(); } } catch (MySqlException e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); } } @@ -827,12 +827,13 @@ namespace OpenSim.Data.MySQL { database.CheckConnection(); - using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection)) - { - cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); + MySqlCommand cmd = + new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection); + cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); - lock (database) - cmd.ExecuteNonQuery(); + lock (database) + { + cmd.ExecuteNonQuery(); } } catch (MySqlException e) @@ -864,38 +865,40 @@ namespace OpenSim.Data.MySQL public List fetchActiveGestures(UUID avatarID) { + MySqlDataReader result = null; + MySqlCommand sqlCmd = null; lock (database) { try { database.CheckConnection(); - - using (MySqlCommand sqlCmd = new MySqlCommand( + sqlCmd = new MySqlCommand( "SELECT * FROM inventoryitems WHERE avatarId = ?uuid AND assetType = ?type and flags = 1", - database.Connection)) - { - sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString()); - sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); + database.Connection); + sqlCmd.Parameters.AddWithValue("?uuid", avatarID.ToString()); + sqlCmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); + result = sqlCmd.ExecuteReader(); - using (MySqlDataReader result = sqlCmd.ExecuteReader()) - { - List list = new List(); - while (result.Read()) - { - InventoryItemBase item = readInventoryItem(result); - if (item != null) - list.Add(item); - } - return list; - } + List list = new List(); + while (result.Read()) + { + InventoryItemBase item = readInventoryItem(result); + if (item != null) + list.Add(item); } + return list; } catch (Exception e) { database.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } + finally + { + if (result != null) result.Close(); + if (sqlCmd != null) sqlCmd.Dispose(); + } } } } diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index a807948bde..c49153f8f2 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -908,7 +908,7 @@ namespace OpenSim.Data.MySQL if (!(row["ParticleSystem"] is DBNull)) prim.ParticleSystem = (byte[])row["ParticleSystem"]; - prim.RotationalVelocity = new Vector3( + prim.AngularVelocity = new Vector3( (float)(double)row["OmegaX"], (float)(double)row["OmegaY"], (float)(double)row["OmegaZ"] @@ -1240,9 +1240,9 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("TextureAnimation", prim.TextureAnimation); cmd.Parameters.AddWithValue("ParticleSystem", prim.ParticleSystem); - cmd.Parameters.AddWithValue("OmegaX", (double)prim.RotationalVelocity.X); - cmd.Parameters.AddWithValue("OmegaY", (double)prim.RotationalVelocity.Y); - cmd.Parameters.AddWithValue("OmegaZ", (double)prim.RotationalVelocity.Z); + cmd.Parameters.AddWithValue("OmegaX", (double)prim.AngularVelocity.X); + cmd.Parameters.AddWithValue("OmegaY", (double)prim.AngularVelocity.Y); + cmd.Parameters.AddWithValue("OmegaZ", (double)prim.AngularVelocity.Z); cmd.Parameters.AddWithValue("CameraEyeOffsetX", (double)prim.GetCameraEyeOffset().X); cmd.Parameters.AddWithValue("CameraEyeOffsetY", (double)prim.GetCameraEyeOffset().Y); diff --git a/OpenSim/Data/MySQL/MySQLManager.cs b/OpenSim/Data/MySQL/MySQLManager.cs index a724a504a9..a6cce57819 100644 --- a/OpenSim/Data/MySQL/MySQLManager.cs +++ b/OpenSim/Data/MySQL/MySQLManager.cs @@ -134,16 +134,18 @@ namespace OpenSim.Data.MySQL /// protected void GetWaitTimeout() { - using (MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon)) + MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon); + + using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { - using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + if (dbReader.Read()) { - if (dbReader.Read()) - { - m_waitTimeout - = Convert.ToInt32(dbReader["@@wait_timeout"]) * TimeSpan.TicksPerSecond + m_waitTimeoutLeeway; - } + m_waitTimeout + = Convert.ToInt32(dbReader["@@wait_timeout"]) * TimeSpan.TicksPerSecond + m_waitTimeoutLeeway; } + + dbReader.Close(); + cmd.Dispose(); } m_lastConnectionUse = DateTime.Now.Ticks; @@ -301,31 +303,31 @@ namespace OpenSim.Data.MySQL { CheckConnection(); - using (MySqlCommand tablesCmd = new MySqlCommand( - "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname", - dbcon)) - { - tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database); + MySqlCommand tablesCmd = + new MySqlCommand( + "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname", + dbcon); + tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database); - using (MySqlDataReader tables = tablesCmd.ExecuteReader()) + using (MySqlDataReader tables = tablesCmd.ExecuteReader()) + { + while (tables.Read()) { - while (tables.Read()) + try { - try + string tableName = (string) tables["TABLE_NAME"]; + string comment = (string) tables["TABLE_COMMENT"]; + if (tableList.ContainsKey(tableName)) { - string tableName = (string)tables["TABLE_NAME"]; - string comment = (string)tables["TABLE_COMMENT"]; - if (tableList.ContainsKey(tableName)) - { - tableList[tableName] = comment; - } - } - catch (Exception e) - { - m_log.Error(e.Message, e); + tableList[tableName] = comment; } } + catch (Exception e) + { + m_log.Error(e.ToString()); + } } + tables.Close(); } } } @@ -344,19 +346,19 @@ namespace OpenSim.Data.MySQL { CheckConnection(); // Not sure if this one is necessary - MySqlCommand dbcommand = (MySqlCommand)dbcon.CreateCommand(); + MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand(); dbcommand.CommandText = sql; foreach (KeyValuePair param in parameters) { dbcommand.Parameters.AddWithValue(param.Key, param.Value); } - return (IDbCommand)dbcommand; + return (IDbCommand) dbcommand; } catch (Exception e) { // Return null if it fails. - m_log.Error("Failed during Query generation: " + e.Message, e); + m_log.Error("Failed during Query generation: " + e.ToString()); return null; } } @@ -692,6 +694,8 @@ namespace OpenSim.Data.MySQL ret.Add(attachpoint, item); } + r.Close(); + return ret; } diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index f5140761ea..b0075e8528 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -56,13 +56,12 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - using (MySqlCommand cmd = new MySqlCommand(command)) - { - cmd.Parameters.AddWithValue("?regionName", regionName); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + MySqlCommand cmd = new MySqlCommand(command); - return RunCommand(cmd); - } + cmd.Parameters.AddWithValue("?regionName", regionName); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + return RunCommand(cmd); } public RegionData Get(int posX, int posY, UUID scopeID) @@ -71,18 +70,17 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - using (MySqlCommand cmd = new MySqlCommand(command)) - { - cmd.Parameters.AddWithValue("?posX", posX.ToString()); - cmd.Parameters.AddWithValue("?posY", posY.ToString()); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + MySqlCommand cmd = new MySqlCommand(command); - List ret = RunCommand(cmd); - if (ret.Count == 0) - return null; + cmd.Parameters.AddWithValue("?posX", posX.ToString()); + cmd.Parameters.AddWithValue("?posY", posY.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - return ret[0]; - } + List ret = RunCommand(cmd); + if (ret.Count == 0) + return null; + + return ret[0]; } public RegionData Get(UUID regionID, UUID scopeID) @@ -91,17 +89,16 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - using (MySqlCommand cmd = new MySqlCommand(command)) - { - cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + MySqlCommand cmd = new MySqlCommand(command); - List ret = RunCommand(cmd); - if (ret.Count == 0) - return null; + cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); - return ret[0]; - } + List ret = RunCommand(cmd); + if (ret.Count == 0) + return null; + + return ret[0]; } public List Get(int startX, int startY, int endX, int endY, UUID scopeID) @@ -110,44 +107,43 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; - using (MySqlCommand cmd = new MySqlCommand(command)) - { - cmd.Parameters.AddWithValue("?startX", startX.ToString()); - cmd.Parameters.AddWithValue("?startY", startY.ToString()); - cmd.Parameters.AddWithValue("?endX", endX.ToString()); - cmd.Parameters.AddWithValue("?endY", endY.ToString()); - cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + MySqlCommand cmd = new MySqlCommand(command); - return RunCommand(cmd); - } + cmd.Parameters.AddWithValue("?startX", startX.ToString()); + cmd.Parameters.AddWithValue("?startY", startY.ToString()); + cmd.Parameters.AddWithValue("?endX", endX.ToString()); + cmd.Parameters.AddWithValue("?endY", endY.ToString()); + cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); + + return RunCommand(cmd); } public List RunCommand(MySqlCommand cmd) { List retList = new List(); - using (IDataReader result = ExecuteReader(cmd)) + IDataReader result = ExecuteReader(cmd); + + while (result.Read()) { - while (result.Read()) + RegionData ret = new RegionData(); + ret.Data = new Dictionary(); + + UUID regionID; + UUID.TryParse(result["uuid"].ToString(), out regionID); + ret.RegionID = regionID; + UUID scope; + UUID.TryParse(result["ScopeID"].ToString(), out scope); + ret.ScopeID = scope; + ret.RegionName = result["regionName"].ToString(); + ret.posX = Convert.ToInt32(result["locX"]); + ret.posY = Convert.ToInt32(result["locY"]); + ret.sizeX = Convert.ToInt32(result["sizeX"]); + ret.sizeY = Convert.ToInt32(result["sizeY"]); + + if (m_ColumnNames == null) { - RegionData ret = new RegionData(); - ret.Data = new Dictionary(); - - UUID regionID; - UUID.TryParse(result["uuid"].ToString(), out regionID); - ret.RegionID = regionID; - UUID scope; - UUID.TryParse(result["ScopeID"].ToString(), out scope); - ret.ScopeID = scope; - ret.RegionName = result["regionName"].ToString(); - ret.posX = Convert.ToInt32(result["locX"]); - ret.posY = Convert.ToInt32(result["locY"]); - ret.sizeX = Convert.ToInt32(result["sizeX"]); - ret.sizeY = Convert.ToInt32(result["sizeY"]); - - if (m_ColumnNames == null) - { - m_ColumnNames = new List(); + m_ColumnNames = new List(); DataTable schemaTable = result.GetSchemaTable(); foreach (DataRow row in schemaTable.Rows) @@ -157,28 +153,28 @@ namespace OpenSim.Data.MySQL } } - foreach (string s in m_ColumnNames) - { - if (s == "uuid") - continue; - if (s == "ScopeID") - continue; - if (s == "regionName") - continue; - if (s == "locX") - continue; - if (s == "locY") - continue; + foreach (string s in m_ColumnNames) + { + if (s == "uuid") + continue; + if (s == "ScopeID") + continue; + if (s == "regionName") + continue; + if (s == "locX") + continue; + if (s == "locY") + continue; - ret.Data[s] = result[s].ToString(); - } - - retList.Add(ret); + ret.Data[s] = result[s].ToString(); } - CloseDBConnection(result, cmd); + retList.Add(ret); } + result.Close(); + CloseReaderCommand(cmd); + return retList; } @@ -205,72 +201,76 @@ namespace OpenSim.Data.MySQL string[] fields = new List(data.Data.Keys).ToArray(); - using (MySqlCommand cmd = new MySqlCommand()) + MySqlCommand cmd = new MySqlCommand(); + + string update = "update `"+m_Realm+"` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY"; + foreach (string field in fields) { - string update = "update `" + m_Realm + "` set locX=?posX, locY=?posY, sizeX=?sizeX, sizeY=?sizeY"; - foreach (string field in fields) - { - update += ", "; - update += "`" + field + "` = ?" + field; + update += ", "; + update += "`" + field + "` = ?"+field; - cmd.Parameters.AddWithValue("?" + field, data.Data[field]); - } + cmd.Parameters.AddWithValue("?"+field, data.Data[field]); + } - update += " where uuid = ?regionID"; + update += " where uuid = ?regionID"; - if (data.ScopeID != UUID.Zero) - update += " and ScopeID = ?scopeID"; + if (data.ScopeID != UUID.Zero) + update += " and ScopeID = ?scopeID"; - cmd.CommandText = update; - cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString()); - cmd.Parameters.AddWithValue("?regionName", data.RegionName); - cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); - cmd.Parameters.AddWithValue("?posX", data.posX.ToString()); - cmd.Parameters.AddWithValue("?posY", data.posY.ToString()); - cmd.Parameters.AddWithValue("?sizeX", data.sizeX.ToString()); - cmd.Parameters.AddWithValue("?sizeY", data.sizeY.ToString()); + cmd.CommandText = update; + cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString()); + cmd.Parameters.AddWithValue("?regionName", data.RegionName); + cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); + cmd.Parameters.AddWithValue("?posX", data.posX.ToString()); + cmd.Parameters.AddWithValue("?posY", data.posY.ToString()); + cmd.Parameters.AddWithValue("?sizeX", data.sizeX.ToString()); + cmd.Parameters.AddWithValue("?sizeY", data.sizeY.ToString()); + + if (ExecuteNonQuery(cmd) < 1) + { + string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `locX`, `locY`, `sizeX`, `sizeY`, `regionName`, `" + + String.Join("`, `", fields) + + "`) values ( ?regionID, ?scopeID, ?posX, ?posY, ?sizeX, ?sizeY, ?regionName, ?" + String.Join(", ?", fields) + ")"; + + cmd.CommandText = insert; if (ExecuteNonQuery(cmd) < 1) { - string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `locX`, `locY`, `sizeX`, `sizeY`, `regionName`, `" + - String.Join("`, `", fields) + - "`) values ( ?regionID, ?scopeID, ?posX, ?posY, ?sizeX, ?sizeY, ?regionName, ?" + String.Join(", ?", fields) + ")"; - - cmd.CommandText = insert; - - if (ExecuteNonQuery(cmd) < 1) - { - return false; - } + cmd.Dispose(); + return false; } } + cmd.Dispose(); + return true; } public bool SetDataItem(UUID regionID, string item, string value) { - using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where uuid = ?UUID")) - { - cmd.Parameters.AddWithValue("?" + item, value); - cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); + MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + + "` set `" + item + "` = ?" + item + " where uuid = ?UUID"); - if (ExecuteNonQuery(cmd) > 0) - return true; - } + + cmd.Parameters.AddWithValue("?"+item, value); + cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); + + if (ExecuteNonQuery(cmd) > 0) + return true; return false; } public bool Delete(UUID regionID) { - using (MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + "` where uuid = ?UUID")) - { - cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); + MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + + "` where uuid = ?UUID"); - if (ExecuteNonQuery(cmd) > 0) - return true; - } + + cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); + + if (ExecuteNonQuery(cmd) > 0) + return true; return false; } diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs index 0bbc3f5645..d48144d2e8 100644 --- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs @@ -97,14 +97,16 @@ namespace OpenSim.Data.MySQL ret.Data[s] = result[s].ToString(); } - CloseDBConnection(result, cmd); + result.Close(); + CloseReaderCommand(cmd); + return ret; } - else - { - CloseDBConnection(result, cmd); - return null; - } + + result.Close(); + CloseReaderCommand(cmd); + + return null; } public bool Store(UserAccountData data) @@ -116,60 +118,61 @@ namespace OpenSim.Data.MySQL string[] fields = new List(data.Data.Keys).ToArray(); - using (MySqlCommand cmd = new MySqlCommand()) + MySqlCommand cmd = new MySqlCommand(); + + string update = "update `"+m_Realm+"` set "; + bool first = true; + foreach (string field in fields) { - string update = "update `" + m_Realm + "` set "; - bool first = true; - foreach (string field in fields) - { - if (!first) - update += ", "; - update += "`" + field + "` = ?" + field; + if (!first) + update += ", "; + update += "`" + field + "` = ?"+field; - first = false; + first = false; - cmd.Parameters.AddWithValue("?" + field, data.Data[field]); - } + cmd.Parameters.AddWithValue("?"+field, data.Data[field]); + } - update += " where UUID = ?principalID"; + update += " where UUID = ?principalID"; - if (data.ScopeID != UUID.Zero) - update += " and ScopeID = ?scopeID"; + if (data.ScopeID != UUID.Zero) + update += " and ScopeID = ?scopeID"; - cmd.CommandText = update; - cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); - cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); + cmd.CommandText = update; + cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); + cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); + + if (ExecuteNonQuery(cmd) < 1) + { + string insert = "insert into `" + m_Realm + "` (`UUID`, `ScopeID`, `" + + String.Join("`, `", fields) + + "`) values (?principalID, ?scopeID, ?" + String.Join(", ?", fields) + ")"; + + cmd.CommandText = insert; if (ExecuteNonQuery(cmd) < 1) { - string insert = "insert into `" + m_Realm + "` (`UUID`, `ScopeID`, `" + - String.Join("`, `", fields) + - "`) values (?principalID, ?scopeID, ?" + String.Join(", ?", fields) + ")"; - - cmd.CommandText = insert; - - if (ExecuteNonQuery(cmd) < 1) - { - cmd.Dispose(); - return false; - } + cmd.Dispose(); + return false; } } + cmd.Dispose(); + return true; } public bool SetDataItem(UUID principalID, string item, string value) { - using (MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + "` set `" + - item + "` = ?" + item + " where UUID = ?UUID")) - { - cmd.Parameters.AddWithValue("?" + item, value); - cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); + MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + + "` set `" + item + "` = ?" + item + " where UUID = ?UUID"); - if (ExecuteNonQuery(cmd) > 0) - return true; - } + + cmd.Parameters.AddWithValue("?"+item, value); + cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); + + if (ExecuteNonQuery(cmd) > 0) + return true; return false; } diff --git a/OpenSim/Data/MySQL/MySQLUserData.cs b/OpenSim/Data/MySQL/MySQLUserData.cs index bd46dfc00b..04f872f249 100644 --- a/OpenSim/Data/MySQL/MySQLUserData.cs +++ b/OpenSim/Data/MySQL/MySQLUserData.cs @@ -181,20 +181,21 @@ namespace OpenSim.Data.MySQL param["?first"] = user; param["?second"] = last; - using (IDbCommand result = dbm.Manager.Query( - "SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - UserProfileData row = dbm.Manager.readUserRow(reader); - return row; - } - } + IDbCommand result = + dbm.Manager.Query( + "SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = dbm.Manager.readUserRow(reader); + + reader.Dispose(); + result.Dispose(); + return row; } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -219,30 +220,28 @@ namespace OpenSim.Data.MySQL try { - using (IDbCommand adder = dbm.Manager.Query( - "INSERT INTO `" + m_userFriendsTableName + "` " + - "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + - "VALUES " + - "(?ownerID,?friendID,?friendPerms,?datetimestamp)", - param)) - { - adder.ExecuteNonQuery(); - } + IDbCommand adder = + dbm.Manager.Query( + "INSERT INTO `" + m_userFriendsTableName + "` " + + "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + + "VALUES " + + "(?ownerID,?friendID,?friendPerms,?datetimestamp)", + param); + adder.ExecuteNonQuery(); - using (IDbCommand adder = dbm.Manager.Query( - "INSERT INTO `" + m_userFriendsTableName + "` " + - "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + - "VALUES " + - "(?friendID,?ownerID,?friendPerms,?datetimestamp)", - param)) - { - adder.ExecuteNonQuery(); - } + adder = + dbm.Manager.Query( + "INSERT INTO `" + m_userFriendsTableName + "` " + + "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + + "VALUES " + + "(?friendID,?ownerID,?friendPerms,?datetimestamp)", + param); + adder.ExecuteNonQuery(); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return; } finally @@ -261,24 +260,22 @@ namespace OpenSim.Data.MySQL try { - using (IDbCommand updater = dbm.Manager.Query( + IDbCommand updater = + dbm.Manager.Query( "delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID", - param)) - { - updater.ExecuteNonQuery(); - } + param); + updater.ExecuteNonQuery(); - using (IDbCommand updater = dbm.Manager.Query( + updater = + dbm.Manager.Query( "delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID", - param)) - { - updater.ExecuteNonQuery(); - } + param); + updater.ExecuteNonQuery(); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return; } finally @@ -298,19 +295,18 @@ namespace OpenSim.Data.MySQL try { - using (IDbCommand updater = dbm.Manager.Query( + IDbCommand updater = + dbm.Manager.Query( "update " + m_userFriendsTableName + " SET friendPerms = ?friendPerms " + "where ownerID = ?ownerID and friendID = ?friendID", - param)) - { - updater.ExecuteNonQuery(); - } + param); + updater.ExecuteNonQuery(); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return; } finally @@ -331,33 +327,34 @@ namespace OpenSim.Data.MySQL try { //Left Join userfriends to itself - using (IDbCommand result = dbm.Manager.Query( - "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " + - m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" + - " where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID", - param)) + IDbCommand result = + dbm.Manager.Query( + "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " + + m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" + + " where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID", + param); + IDataReader reader = result.ExecuteReader(); + + while (reader.Read()) { - using (IDataReader reader = result.ExecuteReader()) - { - while (reader.Read()) - { - FriendListItem fli = new FriendListItem(); - fli.FriendListOwner = new UUID((string)reader["ownerID"]); - fli.Friend = new UUID((string)reader["friendID"]); - fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]); + FriendListItem fli = new FriendListItem(); + fli.FriendListOwner = new UUID((string) reader["ownerID"]); + fli.Friend = new UUID((string) reader["friendID"]); + fli.FriendPerms = (uint) Convert.ToInt32(reader["friendPerms"]); - // This is not a real column in the database table, it's a joined column from the opposite record - fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]); + // This is not a real column in the database table, it's a joined column from the opposite record + fli.FriendListOwnerPerms = (uint) Convert.ToInt32(reader["ownerperms"]); - Lfli.Add(fli); - } - } + Lfli.Add(fli); } + + reader.Dispose(); + result.Dispose(); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return Lfli; } finally @@ -379,29 +376,29 @@ namespace OpenSim.Data.MySQL { Dictionary param = new Dictionary(); param["?uuid"] = uuid.ToString(); + IDbCommand result = + dbm.Manager.Query("select agentOnline,currentHandle from " + m_agentsTableName + + " where UUID = ?uuid", param); - using (IDbCommand result = dbm.Manager.Query("select agentOnline,currentHandle from " + m_agentsTableName + - " where UUID = ?uuid", param)) + IDataReader reader = result.ExecuteReader(); + while (reader.Read()) { - using (IDataReader reader = result.ExecuteReader()) - { - while (reader.Read()) - { - FriendRegionInfo fri = new FriendRegionInfo(); - fri.isOnline = (sbyte)reader["agentOnline"] != 0; - fri.regionHandle = (ulong)reader["currentHandle"]; + FriendRegionInfo fri = new FriendRegionInfo(); + fri.isOnline = (sbyte)reader["agentOnline"] != 0; + fri.regionHandle = (ulong)reader["currentHandle"]; - infos[uuid] = fri; - } - } + infos[uuid] = fri; } + + reader.Dispose(); + result.Dispose(); } } catch (Exception e) { m_log.Warn("[MYSQL]: Got exception on trying to find friends regions:", e); dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); } finally { @@ -430,28 +427,28 @@ namespace OpenSim.Data.MySQL try { - using (IDbCommand result = dbm.Manager.Query( - "SELECT UUID,username,lastname FROM " + m_usersTableName + - " WHERE username like ?first AND lastname like ?second LIMIT 100", - param)) + IDbCommand result = + dbm.Manager.Query( + "SELECT UUID,username,lastname FROM " + m_usersTableName + + " WHERE username like ?first AND lastname like ?second LIMIT 100", + param); + IDataReader reader = result.ExecuteReader(); + + while (reader.Read()) { - using (IDataReader reader = result.ExecuteReader()) - { - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new UUID((string)reader["UUID"]); - user.firstName = (string)reader["username"]; - user.lastName = (string)reader["lastname"]; - returnlist.Add(user); - } - } + AvatarPickerAvatar user = new AvatarPickerAvatar(); + user.AvatarID = new UUID((string) reader["UUID"]); + user.firstName = (string) reader["username"]; + user.lastName = (string) reader["lastname"]; + returnlist.Add(user); } + reader.Dispose(); + result.Dispose(); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return returnlist; } finally @@ -468,28 +465,28 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%"; - using (IDbCommand result = dbm.Manager.Query( - "SELECT UUID,username,lastname FROM " + m_usersTableName + - " WHERE username like ?first OR lastname like ?first LIMIT 100", - param)) + IDbCommand result = + dbm.Manager.Query( + "SELECT UUID,username,lastname FROM " + m_usersTableName + + " WHERE username like ?first OR lastname like ?first LIMIT 100", + param); + IDataReader reader = result.ExecuteReader(); + + while (reader.Read()) { - using (IDataReader reader = result.ExecuteReader()) - { - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new UUID((string)reader["UUID"]); - user.firstName = (string)reader["username"]; - user.lastName = (string)reader["lastname"]; - returnlist.Add(user); - } - } + AvatarPickerAvatar user = new AvatarPickerAvatar(); + user.AvatarID = new UUID((string) reader["UUID"]); + user.firstName = (string) reader["username"]; + user.lastName = (string) reader["lastname"]; + returnlist.Add(user); } + reader.Dispose(); + result.Dispose(); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return returnlist; } finally @@ -513,19 +510,20 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?uuid"] = uuid.ToString(); - using (IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - UserProfileData row = dbm.Manager.readUserRow(reader); - return row; - } - } + IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = dbm.Manager.readUserRow(reader); + + reader.Dispose(); + result.Dispose(); + + return row; } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -571,15 +569,15 @@ namespace OpenSim.Data.MySQL try { - dbm.Manager.ExecuteParameterizedSql( - "update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " + - "where UUID = ?UUID", - param); + dbm.Manager.ExecuteParameterizedSql( + "update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " + + "where UUID = ?UUID", + param); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return; } finally @@ -602,19 +600,21 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?uuid"] = uuid.ToString(); - using (IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - UserAgentData row = dbm.Manager.readAgentRow(reader); - return row; - } - } + IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", + param); + IDataReader reader = result.ExecuteReader(); + + UserAgentData row = dbm.Manager.readAgentRow(reader); + + reader.Dispose(); + result.Dispose(); + + return row; } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -638,20 +638,19 @@ namespace OpenSim.Data.MySQL try { - dbm.Manager.insertUserRow( - user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt, - user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y, - user.HomeLocation.Z, - user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, - user.LastLogin, user.UserInventoryURI, user.UserAssetURI, - user.CanDoMask, user.WantDoMask, - user.AboutText, user.FirstLifeAboutText, user.Image, - user.FirstLifeImage, user.WebLoginKey, user.UserFlags, user.GodLevel, user.CustomType, user.Partner); + dbm.Manager.insertUserRow(user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt, + user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y, + user.HomeLocation.Z, + user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, + user.LastLogin, user.UserInventoryURI, user.UserAssetURI, + user.CanDoMask, user.WantDoMask, + user.AboutText, user.FirstLifeAboutText, user.Image, + user.FirstLifeImage, user.WebLoginKey, user.UserFlags, user.GodLevel, user.CustomType, user.Partner); } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); } finally { @@ -677,7 +676,7 @@ namespace OpenSim.Data.MySQL catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); } finally { @@ -694,15 +693,14 @@ namespace OpenSim.Data.MySQL MySQLSuperManager dbm = GetLockedConnection("UpdateUserProfile"); try { - dbm.Manager.updateUserRow( - user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt, - user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y, - user.HomeLocation.Z, user.HomeLookAt.X, - user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, user.LastLogin, - user.UserInventoryURI, - user.UserAssetURI, user.CanDoMask, user.WantDoMask, user.AboutText, - user.FirstLifeAboutText, user.Image, user.FirstLifeImage, user.WebLoginKey, - user.UserFlags, user.GodLevel, user.CustomType, user.Partner); + dbm.Manager.updateUserRow(user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt, + user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y, + user.HomeLocation.Z, user.HomeLookAt.X, + user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, user.LastLogin, + user.UserInventoryURI, + user.UserAssetURI, user.CanDoMask, user.WantDoMask, user.AboutText, + user.FirstLifeAboutText, user.Image, user.FirstLifeImage, user.WebLoginKey, + user.UserFlags, user.GodLevel, user.CustomType, user.Partner); } finally { @@ -750,29 +748,29 @@ namespace OpenSim.Data.MySQL Dictionary param = new Dictionary(); param["?owner"] = user.ToString(); - using (IDbCommand result = dbm.Manager.Query("SELECT * FROM " + m_appearanceTableName + " WHERE owner = ?owner", param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - AvatarAppearance appearance = dbm.Manager.readAppearanceRow(reader); + IDbCommand result = dbm.Manager.Query( + "SELECT * FROM " + m_appearanceTableName + " WHERE owner = ?owner", param); + IDataReader reader = result.ExecuteReader(); - if (appearance == null) - { - m_log.WarnFormat("[USER DB] No appearance found for user {0}", user.ToString()); - return null; - } - else - { - appearance.SetAttachments(GetUserAttachments(user)); - return appearance; - } - } + AvatarAppearance appearance = dbm.Manager.readAppearanceRow(reader); + + reader.Dispose(); + result.Dispose(); + + if (null == appearance) + { + m_log.WarnFormat("[USER DB] No appearance found for user {0}", user.ToString()); + return null; } + + appearance.SetAttachments(GetUserAttachments(user)); + + return appearance; } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -800,7 +798,7 @@ namespace OpenSim.Data.MySQL catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); } finally { @@ -835,20 +833,20 @@ namespace OpenSim.Data.MySQL try { - using (IDbCommand result = dbm.Manager.Query( - "SELECT attachpoint, item, asset from " + m_attachmentsTableName + " WHERE UUID = ?uuid", param)) - { - using (IDataReader reader = result.ExecuteReader()) - { - Hashtable ret = dbm.Manager.readAttachments(reader); - return ret; - } - } + IDbCommand result = dbm.Manager.Query( + "SELECT attachpoint, item, asset from " + m_attachmentsTableName + " WHERE UUID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + Hashtable ret = dbm.Manager.readAttachments(reader); + + reader.Dispose(); + result.Dispose(); + return ret; } catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return null; } finally @@ -907,7 +905,7 @@ namespace OpenSim.Data.MySQL catch (Exception e) { dbm.Manager.Reconnect(); - m_log.Error(e.Message, e); + m_log.Error(e.ToString()); return; } finally diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 08af7c3eb0..b68de1a87b 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -1213,7 +1213,7 @@ namespace OpenSim.Data.SQLite if (!row.IsNull("ParticleSystem")) prim.ParticleSystem = Convert.FromBase64String(row["ParticleSystem"].ToString()); - prim.RotationalVelocity = new Vector3( + prim.AngularVelocity = new Vector3( Convert.ToSingle(row["OmegaX"]), Convert.ToSingle(row["OmegaY"]), Convert.ToSingle(row["OmegaZ"]) @@ -1530,9 +1530,9 @@ namespace OpenSim.Data.SQLite row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation); row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem); - row["OmegaX"] = prim.RotationalVelocity.X; - row["OmegaY"] = prim.RotationalVelocity.Y; - row["OmegaZ"] = prim.RotationalVelocity.Z; + row["OmegaX"] = prim.AngularVelocity.X; + row["OmegaY"] = prim.AngularVelocity.Y; + row["OmegaZ"] = prim.AngularVelocity.Z; row["CameraEyeOffsetX"] = prim.GetCameraEyeOffset().X; row["CameraEyeOffsetY"] = prim.GetCameraEyeOffset().Y; diff --git a/OpenSim/Framework/ACL.cs b/OpenSim/Framework/ACL.cs index 3b1c0f0f63..f76e8b7288 100644 --- a/OpenSim/Framework/ACL.cs +++ b/OpenSim/Framework/ACL.cs @@ -248,35 +248,5 @@ namespace OpenSim.Framework #endregion - #region Tests - - /// - /// ACL Test class - /// - internal class ACLTester - { - public ACLTester() - { - ACL acl = new ACL(); - - Role Guests = new Role("Guests"); - acl.AddRole(Guests); - - Role[] parents = new Role[0]; - parents[0] = Guests; - - Role JoeGuest = new Role("JoeGuest", parents); - acl.AddRole(JoeGuest); - - Resource CanBuild = new Resource("CanBuild"); - acl.AddResource(CanBuild); - - - acl.GrantPermission("Guests", "CanBuild"); - - acl.HasPermission("JoeGuest", "CanBuild"); - } - } - - #endregion + } \ No newline at end of file diff --git a/OpenSim/Framework/Communications/Services/LoginService.cs b/OpenSim/Framework/Communications/Services/LoginService.cs index 922cd4942f..b6522992b7 100644 --- a/OpenSim/Framework/Communications/Services/LoginService.cs +++ b/OpenSim/Framework/Communications/Services/LoginService.cs @@ -1031,30 +1031,26 @@ namespace OpenSim.Framework.Communications.Services return true; } - // StartLocation not available, send him to a nearby region instead - // regionInfo = m_gridService.RequestClosestRegion(""); - //m_log.InfoFormat("[LOGIN]: StartLocation not available sending to region {0}", regionInfo.regionName); + // Get the default region handle + ulong defaultHandle = Utils.UIntsToLong(m_defaultHomeX * Constants.RegionSize, m_defaultHomeY * Constants.RegionSize); - // Send him to default region instead - ulong defaultHandle = (((ulong)m_defaultHomeX * Constants.RegionSize) << 32) | - ((ulong)m_defaultHomeY * Constants.RegionSize); - - if ((regionInfo != null) && (defaultHandle == regionInfo.RegionHandle)) - { - m_log.ErrorFormat("[LOGIN]: Not trying the default region since this is the same as the selected region"); - return false; - } - - m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead"); - regionInfo = GetRegionInfo(defaultHandle); + // If we haven't already tried the default region, reset regionInfo + if (regionInfo != null && defaultHandle != regionInfo.RegionHandle) + regionInfo = null; if (regionInfo == null) { - m_log.ErrorFormat("[LOGIN]: No default region available. Aborting."); - return false; + m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead"); + regionInfo = GetRegionInfo(defaultHandle); } - theUser.CurrentAgent.Position = new Vector3(128, 128, 0); + if (regionInfo == null) + { + m_log.ErrorFormat("[LOGIN]: Sending user to any region"); + regionInfo = RequestClosestRegion(String.Empty); + } + + theUser.CurrentAgent.Position = new Vector3(128f, 128f, 0f); response.StartLocation = "safe"; return PrepareLoginToRegion(regionInfo, theUser, response, client); diff --git a/OpenSim/Framework/Tests/ACLTest.cs b/OpenSim/Framework/Tests/ACLTest.cs new file mode 100644 index 0000000000..d11f307a89 --- /dev/null +++ b/OpenSim/Framework/Tests/ACLTest.cs @@ -0,0 +1,98 @@ +using System; +using NUnit.Framework; +using System.Collections.Generic; + + +namespace OpenSim.Framework.Tests +{ + [TestFixture] + public class ACLTest + { + #region Tests + + /// + /// ACL Test class + /// + [Test] + public void ACLTest01() + { + ACL acl = new ACL(); + + Role Guests = new Role("Guests"); + acl.AddRole(Guests); + + Role[] parents = new Role[1]; + parents[0] = Guests; + + Role JoeGuest = new Role("JoeGuest", parents); + acl.AddRole(JoeGuest); + + Resource CanBuild = new Resource("CanBuild"); + acl.AddResource(CanBuild); + + + acl.GrantPermission("Guests", "CanBuild"); + + Permission perm = acl.HasPermission("JoeGuest", "CanBuild"); + Assert.That(perm == Permission.Allow, "JoeGuest should have permission to build"); + perm = Permission.None; + try + { + perm = acl.HasPermission("unknownGuest", "CanBuild"); + + } + catch (KeyNotFoundException) + { + + + } + catch (Exception) + { + Assert.That(false,"Exception thrown should have been KeyNotFoundException"); + } + Assert.That(perm == Permission.None,"Permission None should be set because exception should have been thrown"); + + } + + [Test] + public void KnownButPermissionDenyAndPermissionNoneUserTest() + { + ACL acl = new ACL(); + + Role Guests = new Role("Guests"); + acl.AddRole(Guests); + Role Administrators = new Role("Administrators"); + acl.AddRole(Administrators); + Role[] Guestparents = new Role[1]; + Role[] Adminparents = new Role[1]; + + Guestparents[0] = Guests; + Adminparents[0] = Administrators; + + Role JoeGuest = new Role("JoeGuest", Guestparents); + acl.AddRole(JoeGuest); + + Resource CanBuild = new Resource("CanBuild"); + acl.AddResource(CanBuild); + + Resource CanScript = new Resource("CanScript"); + acl.AddResource(CanScript); + + Resource CanRestart = new Resource("CanRestart"); + acl.AddResource(CanRestart); + + acl.GrantPermission("Guests", "CanBuild"); + acl.DenyPermission("Guests", "CanRestart"); + + acl.GrantPermission("Administrators", "CanScript"); + + acl.GrantPermission("Administrators", "CanRestart"); + Permission setPermission = acl.HasPermission("JoeGuest", "CanRestart"); + Assert.That(setPermission == Permission.Deny, "Guests Should not be able to restart"); + Assert.That(acl.HasPermission("JoeGuest", "CanScript") == Permission.None, + "No Explicit Permissions set so should be Permission.None"); + } + + #endregion + } +} diff --git a/OpenSim/Framework/Tests/CacheTests.cs b/OpenSim/Framework/Tests/CacheTests.cs new file mode 100644 index 0000000000..8e97232f10 --- /dev/null +++ b/OpenSim/Framework/Tests/CacheTests.cs @@ -0,0 +1,75 @@ +using System; +using NUnit.Framework; +using OpenMetaverse; + +namespace OpenSim.Framework.Tests +{ + [TestFixture] + public class CacheTests + { + private Cache cache; + private UUID cacheItemUUID; + [SetUp] + public void Build() + { + cache = new Cache(); + cacheItemUUID = UUID.Random(); + MemoryCacheItem cachedItem = new MemoryCacheItem(cacheItemUUID.ToString(),DateTime.Now + TimeSpan.FromDays(1)); + byte[] foo = new byte[1]; + foo[0] = 255; + cachedItem.Store(foo); + cache.Store(cacheItemUUID.ToString(), cachedItem); + } + [Test] + public void TestRetreive() + { + CacheItemBase citem = (CacheItemBase)cache.Get(cacheItemUUID.ToString()); + byte[] data = (byte[]) citem.Retrieve(); + Assert.That(data.Length == 1, "Cached Item should have one byte element"); + Assert.That(data[0] == 255, "Cached Item element should be 255"); + } + + [Test] + public void TestNotInCache() + { + UUID randomNotIn = UUID.Random(); + while (randomNotIn == cacheItemUUID) + { + randomNotIn = UUID.Random(); + } + object citem = cache.Get(randomNotIn.ToString()); + Assert.That(citem == null, "Item should not be in Cache" ); + } + + //NOTE: Test Case disabled until Cache is fixed + [Test] + public void TestTTLExpiredEntry() + { + UUID ImmediateExpiryUUID = UUID.Random(); + MemoryCacheItem cachedItem = new MemoryCacheItem(ImmediateExpiryUUID.ToString(), TimeSpan.FromDays(-1)); + byte[] foo = new byte[1]; + foo[0] = 1; + cachedItem.Store(foo); + cache.Store(cacheItemUUID.ToString(), cachedItem); + + object citem = cache.Get(cacheItemUUID.ToString()); + //Assert.That(citem == null, "Item should not be in Cache because the expiry time was before now"); + } + + //NOTE: Test Case disabled until Cache is fixed + [Test] + public void ExpireItemManually() + { + UUID ImmediateExpiryUUID = UUID.Random(); + MemoryCacheItem cachedItem = new MemoryCacheItem(ImmediateExpiryUUID.ToString(), TimeSpan.FromDays(1)); + byte[] foo = new byte[1]; + foo[0] = 1; + cachedItem.Store(foo); + cache.Store(cacheItemUUID.ToString(), cachedItem); + cache.Invalidate(ImmediateExpiryUUID.ToString()); + object citem = cache.Get(cacheItemUUID.ToString()); + //Assert.That(citem == null, "Item should not be in Cache because we manually invalidated it"); + } + + } +} diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index b44818266a..60c34df8bd 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -343,6 +343,10 @@ namespace OpenSim "Add-InventoryHost ", String.Empty, RunCommand); + m_console.Commands.AddCommand("region", false, "kill uuid", + "kill uuid ", + "Kill an object by UUID", KillUUID); + if (ConfigurationSettings.Standalone) { m_console.Commands.AddCommand("region", false, "create user", @@ -1332,6 +1336,58 @@ namespace OpenSim return result; } + /// + /// Kill an object given its UUID. + /// + /// + protected void KillUUID(string module, string[] cmdparams) + { + if (cmdparams.Length > 2) + { + UUID id = UUID.Zero; + SceneObjectGroup grp = null; + Scene sc = null; + + if (!UUID.TryParse(cmdparams[2], out id)) + { + MainConsole.Instance.Output("[KillUUID]: Error bad UUID format!"); + return; + } + + m_sceneManager.ForEachScene( + delegate(Scene scene) + { + SceneObjectPart part = scene.GetSceneObjectPart(id); + if (part == null) + return; + + grp = part.ParentGroup; + sc = scene; + }); + + if (grp == null) + { + MainConsole.Instance.Output(String.Format("[KillUUID]: Given UUID {0} not found!", id)); + } + else + { + MainConsole.Instance.Output(String.Format("[KillUUID]: Found UUID {0} in scene {1}", id, sc.RegionInfo.RegionName)); + try + { + sc.DeleteSceneObject(grp, false); + } + catch (Exception e) + { + m_log.ErrorFormat("[KillUUID]: Error while removing objects from scene: " + e); + } + } + } + else + { + MainConsole.Instance.Output("[KillUUID]: Usage: kill uuid "); + } + } + #endregion } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index f6a7a0ce54..db0c3b8692 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -37,6 +37,7 @@ using System.Xml; using log4net; using OpenMetaverse; using OpenMetaverse.Packets; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Client; using OpenSim.Framework.Communications.Cache; @@ -314,14 +315,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP private readonly LLUDPClient m_udpClient; private readonly UUID m_sessionId; private readonly UUID m_secureSessionId; - private readonly UUID m_agentId; + protected readonly UUID m_agentId; private readonly uint m_circuitCode; private readonly byte[] m_channelVersion = Utils.EmptyBytes; private readonly Dictionary m_defaultAnimations = new Dictionary(); private readonly IGroupsModule m_GroupsModule; private int m_cachedTextureSerial; - private PriorityQueue m_avatarTerseUpdates; + protected PriorityQueue m_avatarTerseUpdates; private PriorityQueue m_primTerseUpdates; private PriorityQueue m_primFullUpdates; private int m_moneyBalance; @@ -1856,7 +1857,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP economyData.Info.TeleportMinPrice = TeleportMinPrice; economyData.Info.TeleportPriceExponent = TeleportPriceExponent; economyData.Header.Reliable = true; - OutPacket(economyData, ThrottleOutPacketType.Unknown); + OutPacket(economyData, ThrottleOutPacketType.Task); } public void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List Data) @@ -2786,30 +2787,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) { - AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); - - p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - p.AgentData.AvatarID = avatarID; - - p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; - int i = 0; - foreach (GroupMembershipData m in data) - { - p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); - p.GroupData[i].GroupPowers = m.GroupPowers; - p.GroupData[i].AcceptNotices = m.AcceptNotices; - p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); - p.GroupData[i].GroupID = m.GroupID; - p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); - p.GroupData[i].GroupInsigniaID = m.GroupPicture; - i++; - } - - p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); - p.NewGroupData.ListInProfile = true; - - OutPacket(p, ThrottleOutPacketType.Task); + OSDMap llsd = new OSDMap(3); + OSDArray AgentData = new OSDArray(1); + OSDMap AgentDataMap = new OSDMap(1); + AgentDataMap.Add("AgentID", OSD.FromUUID(this.AgentId)); + AgentDataMap.Add("AvatarID", OSD.FromUUID(avatarID)); + AgentData.Add(AgentDataMap); + llsd.Add("AgentData", AgentData); + OSDArray GroupData = new OSDArray(data.Length); + OSDArray NewGroupData = new OSDArray(data.Length); + foreach (GroupMembershipData m in data) + { + OSDMap GroupDataMap = new OSDMap(6); + OSDMap NewGroupDataMap = new OSDMap(1); + GroupDataMap.Add("GroupPowers", OSD.FromBinary(m.GroupPowers)); + GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(m.AcceptNotices)); + GroupDataMap.Add("GroupTitle", OSD.FromString(m.GroupTitle)); + GroupDataMap.Add("GroupID", OSD.FromUUID(m.GroupID)); + GroupDataMap.Add("GroupName", OSD.FromString(m.GroupName)); + GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(m.GroupPicture)); + NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(m.ListInProfile)); + GroupData.Add(GroupDataMap); + NewGroupData.Add(NewGroupDataMap); + } + llsd.Add("GroupData", GroupData); + llsd.Add("NewGroupData", NewGroupData); + + IEventQueue eq = this.Scene.RequestModuleInterface(); + if (eq != null) + { + eq.Enqueue(BuildEvent("AvatarGroupsReply", llsd), this.AgentId); + } } public void SendJoinGroupReply(UUID groupID, bool success) @@ -3168,107 +3176,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion - #region Prim/Avatar Updates - - /*void SendObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) - { - bool canUseCompressed, canUseImproved; - UpdateFlagsToPacketType(creatorFlags, updateFlags, out canUseCompressed, out canUseImproved); - - if (!canUseImproved && !canUseCompressed) - SendFullObjectUpdate(obj, creatorFlags, updateFlags); - else if (!canUseImproved) - SendObjectUpdateCompressed(obj, creatorFlags, updateFlags); - else - SendImprovedTerseObjectUpdate(obj, creatorFlags, updateFlags); - } - - void SendFullObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) - { - IClientAPI owner; - if (m_scene.ClientManager.TryGetValue(obj.OwnerID, out owner) && owner is LLClientView) - { - LLClientView llOwner = (LLClientView)owner; - - // Send an update out to the owner - ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket(); - updateToOwner.RegionData.RegionHandle = obj.RegionHandle; - //updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); - updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - updateToOwner.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags | creatorFlags | PrimFlags.ObjectYouOwner, 0); - - m_udpServer.SendPacket(llOwner.UDPClient, updateToOwner, ThrottleOutPacketType.State, true); - } - - // Send an update out to everyone else - ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket(); - updateToOthers.RegionData.RegionHandle = obj.RegionHandle; - //updateToOthers.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); - updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - updateToOthers.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags, 0); - - m_scene.ClientManager.ForEach( - delegate(IClientAPI client) - { - if (client.AgentId != obj.OwnerID && client is LLClientView) - { - LLClientView llClient = (LLClientView)client; - m_udpServer.SendPacket(llClient.UDPClient, updateToOthers, ThrottleOutPacketType.State, true); - } - } - ); - } - - void SendObjectUpdateCompressed(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) - { - } - - void SendImprovedTerseObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) - { - } - - void UpdateFlagsToPacketType(PrimFlags creatorFlags, PrimUpdateFlags updateFlags, out bool canUseCompressed, out bool canUseImproved) - { - canUseCompressed = true; - canUseImproved = true; - - if ((updateFlags & PrimUpdateFlags.FullUpdate) == PrimUpdateFlags.FullUpdate || creatorFlags != PrimFlags.None) - { - canUseCompressed = false; - canUseImproved = false; - } - else - { - if ((updateFlags & PrimUpdateFlags.Velocity) != 0 || - (updateFlags & PrimUpdateFlags.Acceleration) != 0 || - (updateFlags & PrimUpdateFlags.CollisionPlane) != 0 || - (updateFlags & PrimUpdateFlags.Joint) != 0) - { - canUseCompressed = false; - } - - if ((updateFlags & PrimUpdateFlags.PrimFlags) != 0 || - (updateFlags & PrimUpdateFlags.ParentID) != 0 || - (updateFlags & PrimUpdateFlags.Scale) != 0 || - (updateFlags & PrimUpdateFlags.PrimData) != 0 || - (updateFlags & PrimUpdateFlags.Text) != 0 || - (updateFlags & PrimUpdateFlags.NameValue) != 0 || - (updateFlags & PrimUpdateFlags.ExtraData) != 0 || - (updateFlags & PrimUpdateFlags.TextureAnim) != 0 || - (updateFlags & PrimUpdateFlags.Sound) != 0 || - (updateFlags & PrimUpdateFlags.Particles) != 0 || - (updateFlags & PrimUpdateFlags.Material) != 0 || - (updateFlags & PrimUpdateFlags.ClickAction) != 0 || - (updateFlags & PrimUpdateFlags.MediaURL) != 0 || - (updateFlags & PrimUpdateFlags.Joint) != 0) - { - canUseImproved = false; - } - } - }*/ - - #endregion Prim/Avatar Updates - #region Avatar Packet/Data Sending Methods /// @@ -3314,7 +3221,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ProcessAvatarTerseUpdates(); } - private void ProcessAvatarTerseUpdates() + protected void ProcessAvatarTerseUpdates() { ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); terse.Header.Reliable = false; @@ -3335,6 +3242,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); } + // HACK: Using the task category until the tiered reprioritization code is in OutPacket(terse, ThrottleOutPacketType.Task); } @@ -4430,11 +4338,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// protected virtual void RegisterLocalPacketHandlers() { - AddLocalPacketHandler(PacketType.LogoutRequest, Logout); + AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout); AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate); AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect); - AddLocalPacketHandler(PacketType.AgentCachedTexture, AgentTextureCached); - AddLocalPacketHandler(PacketType.MultipleObjectUpdate, MultipleObjUpdate); + AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached); + AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate); AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest); AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest); AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); @@ -4703,7 +4611,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// /// - protected virtual bool Logout(IClientAPI client, Packet packet) + protected virtual bool HandleLogout(IClientAPI client, Packet packet) { if (packet.Type == PacketType.LogoutRequest) { @@ -4741,7 +4649,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// /// - protected bool AgentTextureCached(IClientAPI simclient, Packet packet) + protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) { //m_log.Debug("texture cached: " + packet.ToString()); AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; @@ -4771,7 +4679,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } - protected bool MultipleObjUpdate(IClientAPI simClient, Packet packet) + protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet) { MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; if (multipleupdate.AgentData.SessionID != SessionId) return false; @@ -5050,7 +4958,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Packet to send /// Throttling category for the packet - private void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) + protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) { m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); } @@ -9944,7 +9852,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP commandMessagePacket.CommandBlock.Command = (uint)command; commandMessagePacket.CommandBlock.Time = time; - OutPacket(commandMessagePacket, ThrottleOutPacketType.Unknown); + OutPacket(commandMessagePacket, ThrottleOutPacketType.Task); } public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID, @@ -9962,7 +9870,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP updatePacket.DataBlockExtended.MediaHeight = mediaHeight; updatePacket.DataBlockExtended.MediaLoop = mediaLoop; - OutPacket(updatePacket, ThrottleOutPacketType.Unknown); + OutPacket(updatePacket, ThrottleOutPacketType.Task); } #endregion @@ -10236,7 +10144,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #region PriorityQueue - private class PriorityQueue + public class PriorityQueue { internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id); @@ -10264,7 +10172,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP this.m_comparison = comparison; } - internal object SyncRoot { get { return this.m_syncRoot; } } + public object SyncRoot { get { return this.m_syncRoot; } } internal int Count { get @@ -10276,7 +10184,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - internal bool Enqueue(TPriority priority, TValue value, uint local_id) + public bool Enqueue(TPriority priority, TValue value, uint local_id) { LookupItem item; @@ -10396,5 +10304,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion + public static OSD BuildEvent(string eventName, OSD eventBody) + { + OSDMap osdEvent = new OSDMap(2); + osdEvent.Add("message", new OSDString(eventName)); + osdEvent.Add("body", eventBody); + + return osdEvent; + } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 84a495959a..9856a1cce4 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -135,8 +135,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP private readonly TokenBucket m_throttle; /// Throttle buckets for each packet category private readonly TokenBucket[] m_throttleCategories; - /// Throttle rate defaults and limits - private readonly ThrottleRates m_defaultThrottleRates; /// Outgoing queues for throttled packets private readonly OpenSim.Framework.LocklessQueue[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue[THROTTLE_CATEGORY_COUNT]; /// A container that can hold one packet for each outbox, used to store @@ -145,6 +143,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// A reference to the LLUDPServer that is managing this client private readonly LLUDPServer m_udpServer; + private int m_defaultRTO = 3000; + private int m_maxRTO = 60000; + /// /// Default constructor /// @@ -155,13 +156,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Circuit code for this connection /// AgentID for the connected agent /// Remote endpoint for this connection - public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint) + public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO) { AgentID = agentID; RemoteEndPoint = remoteEndPoint; CircuitCode = circuitCode; m_udpServer = server; - m_defaultThrottleRates = rates; + if (defaultRTO != 0) + m_defaultRTO = defaultRTO; + if (maxRTO != 0) + m_maxRTO = maxRTO; + // Create a token bucket throttle for this client that has the scene token bucket as a parent m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total); // Create an array of token buckets for this clients different throttle categories @@ -178,7 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } // Default the retransmission timeout to three seconds - RTO = 3000; + RTO = m_defaultRTO; // Initialize this to a sane value to prevent early disconnects TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; @@ -500,7 +505,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); // Clamp the retransmission timeout to manageable values - rto = Utils.Clamp(RTO, 3000, 60000); + rto = Utils.Clamp(RTO, m_defaultRTO, m_maxRTO); RTO = rto; @@ -520,7 +525,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP RTTVAR = 0.0f; // Double the retransmission timeout - RTO = Math.Min(RTO * 2, 60000); + RTO = Math.Min(RTO * 2, m_maxRTO); } /// diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 74d3262680..93946ae50b 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -118,13 +118,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// //private UDPClientCollection m_clients = new UDPClientCollection(); /// Bandwidth throttle for this UDP server - private TokenBucket m_throttle; + protected TokenBucket m_throttle; /// Bandwidth throttle rates for this UDP server - private ThrottleRates m_throttleRates; + protected ThrottleRates m_throttleRates; /// Manages authentication for agent circuits private AgentCircuitManager m_circuitManager; /// Reference to the scene this UDP server is attached to - private Scene m_scene; + protected Scene m_scene; /// The X/Y coordinates of the scene this UDP server is attached to private Location m_location; /// The size of the receive buffer for the UDP socket. This value @@ -153,6 +153,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Flag to signal when clients should send pings private bool m_sendPing; + private int m_defaultRTO = 0; + private int m_maxRTO = 0; + public Socket Server { get { return null; } } public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) @@ -189,6 +192,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10); PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100); TextureSendLimit = config.GetInt("TextureSendLimit", 20); + + m_defaultRTO = config.GetInt("DefaultRTO", 0); + m_maxRTO = config.GetInt("MaxRTO", 0); } else { @@ -247,8 +253,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) { - // CoarseLocationUpdate packets cannot be split in an automated way - if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting) + // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way + if ((packet.Type == PacketType.CoarseLocationUpdate || packet.Type == PacketType.AvatarGroupsReply) && allowSplitting) allowSplitting = false; if (allowSplitting && packet.HasVariableBlocks) @@ -256,8 +262,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[][] datas = packet.ToBytesMultiple(); int packetCount = datas.Length; - //if (packetCount > 1) - // m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); + if (packetCount < 1) + m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length); for (int i = 0; i < packetCount; i++) { @@ -295,8 +301,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[][] datas = packet.ToBytesMultiple(); int packetCount = datas.Length; - //if (packetCount > 1) - // m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); + if (packetCount < 1) + m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length); for (int i = 0; i < packetCount; i++) { @@ -409,6 +415,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false); } + public void CompletePing(LLUDPClient udpClient, byte pingID) + { + CompletePingCheckPacket completePing = new CompletePingCheckPacket(); + completePing.PingID.PingID = pingID; + SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false); + } + public void ResendUnacked(LLUDPClient udpClient) { if (!udpClient.IsConnected) @@ -429,7 +442,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (expiredPackets != null) { - m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO); + //m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO); // Exponential backoff of the retransmission timeout udpClient.BackoffRTO(); @@ -585,7 +598,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP IClientAPI client; if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView)) { - m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); + //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); return; } @@ -669,10 +682,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // We don't need to do anything else with ping checks StartPingCheckPacket startPing = (StartPingCheckPacket)packet; - - CompletePingCheckPacket completePing = new CompletePingCheckPacket(); - completePing.PingID.PingID = startPing.PingID.PingID; - SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false); + CompletePing(udpClient, startPing.PingID.PingID); return; } else if (packet.Type == PacketType.CompletePingCheck) @@ -759,10 +769,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - private void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) + protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) { // Create the LLUDPClient - LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); + LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); IClientAPI existingClient; if (!m_scene.TryGetClient(agentID, out existingClient)) @@ -976,7 +986,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - private void LogoutHandler(IClientAPI client) + protected void LogoutHandler(IClientAPI client) { client.SendLogoutPacket(); if (client.IsActive) diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs index 008d827e20..aaf6e26d58 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs @@ -87,15 +87,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; Resend = throttleConfig.GetInt("resend_default", 12500); - Land = throttleConfig.GetInt("land_default", 500); - Wind = throttleConfig.GetInt("wind_default", 500); - Cloud = throttleConfig.GetInt("cloud_default", 500); - Task = throttleConfig.GetInt("task_default", 500); - Texture = throttleConfig.GetInt("texture_default", 500); - Asset = throttleConfig.GetInt("asset_default", 500); - State = throttleConfig.GetInt("state_default", 500); - - Total = throttleConfig.GetInt("client_throttle_max_bps", 0); + Land = throttleConfig.GetInt("land_default", 1000); + Wind = throttleConfig.GetInt("wind_default", 1000); + Cloud = throttleConfig.GetInt("cloud_default", 1000); + Task = throttleConfig.GetInt("task_default", 1000); + Texture = throttleConfig.GetInt("texture_default", 1000); + Asset = throttleConfig.GetInt("asset_default", 1000); + State = throttleConfig.GetInt("state_default", 1000); ResendLimit = throttleConfig.GetInt("resend_limit", 18750); LandLimit = throttleConfig.GetInt("land_limit", 29750); @@ -104,9 +102,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP TaskLimit = throttleConfig.GetInt("task_limit", 18750); TextureLimit = throttleConfig.GetInt("texture_limit", 55750); AssetLimit = throttleConfig.GetInt("asset_limit", 27500); - State = throttleConfig.GetInt("state_limit", 37000); + StateLimit = throttleConfig.GetInt("state_limit", 37000); - TotalLimit = throttleConfig.GetInt("client_throttle_max_bps", 0); + Total = throttleConfig.GetInt("client_throttle_max_bps", 0); + TotalLimit = Total; } catch (Exception) { } } diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Alerts/DeadlockAlert.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Alerts/DeadlockAlert.cs new file mode 100644 index 0000000000..b546ccb9fb --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Alerts/DeadlockAlert.cs @@ -0,0 +1,37 @@ +using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Alerts +{ + class DeadlockAlert : IAlert + { + private LastFrameTimeMonitor m_monitor; + + public DeadlockAlert(LastFrameTimeMonitor m_monitor) + { + this.m_monitor = m_monitor; + } + + #region Implementation of IAlert + + public string GetName() + { + return "Potential Deadlock Alert"; + } + + public void Test() + { + if (m_monitor.GetValue() > 60 * 1000) + { + if(OnTriggerAlert != null) + { + OnTriggerAlert(typeof (DeadlockAlert), + (int) (m_monitor.GetValue()/1000) + " second(s) since last frame processed.", true); + } + } + } + + public event Alert OnTriggerAlert; + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/IAlert.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/IAlert.cs new file mode 100644 index 0000000000..b533df9a5c --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/IAlert.cs @@ -0,0 +1,13 @@ +using System; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring +{ + internal delegate void Alert(Type reporter, string reason, bool fatal); + + interface IAlert + { + string GetName(); + void Test(); + event Alert OnTriggerAlert; + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/IMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/IMonitor.cs new file mode 100644 index 0000000000..a51dccdeba --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/IMonitor.cs @@ -0,0 +1,9 @@ +namespace OpenSim.Region.CoreModules.Framework.Monitoring +{ + interface IMonitor + { + double GetValue(); + string GetName(); + string GetFriendlyValue(); // Convert to readable numbers + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs new file mode 100644 index 0000000000..769af8df6d --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts; +using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring +{ + public class MonitorModule : IRegionModule + { + private Scene m_scene; + private readonly List m_monitors = new List(); + private readonly List m_alerts = new List(); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public void DebugMonitors(string module, string[] args) + { + foreach (IMonitor monitor in m_monitors) + { + m_log.Info("[MonitorModule] " + m_scene.RegionInfo.RegionName + " reports " + monitor.GetName() + " = " + monitor.GetFriendlyValue()); + } + } + + public void TestAlerts() + { + foreach (IAlert alert in m_alerts) + { + alert.Test(); + } + } + + #region Implementation of IRegionModule + + public void Initialise(Scene scene, IConfigSource source) + { + m_scene = scene; + + + m_scene.AddCommand(this, "monitor report", + "monitor report", + "Returns a variety of statistics about the current region and/or simulator", + DebugMonitors); + } + + public void PostInitialise() + { + m_monitors.Add(new AgentCountMonitor(m_scene)); + m_monitors.Add(new ChildAgentCountMonitor(m_scene)); + m_monitors.Add(new GCMemoryMonitor()); + m_monitors.Add(new ObjectCountMonitor(m_scene)); + m_monitors.Add(new PhysicsFrameMonitor(m_scene)); + m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); + m_monitors.Add(new PWSMemoryMonitor()); + m_monitors.Add(new ThreadCountMonitor()); + m_monitors.Add(new TotalFrameMonitor(m_scene)); + m_monitors.Add(new EventFrameMonitor(m_scene)); + m_monitors.Add(new LandFrameMonitor(m_scene)); + m_monitors.Add(new LastFrameTimeMonitor(m_scene)); + + m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); + + foreach (IAlert alert in m_alerts) + { + alert.OnTriggerAlert += OnTriggerAlert; + } + } + + void OnTriggerAlert(System.Type reporter, string reason, bool fatal) + { + m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")"); + } + + public void Close() + { + + } + + public string Name + { + get { return "Region Health Monitoring Module"; } + } + + public bool IsSharedModule + { + get { return false; } + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/AgentCountMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/AgentCountMonitor.cs new file mode 100644 index 0000000000..edc6e6b9e2 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/AgentCountMonitor.cs @@ -0,0 +1,33 @@ +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class AgentCountMonitor : IMonitor + { + private readonly Scene m_scene; + + public AgentCountMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return m_scene.SceneGraph.GetRootAgentCount(); + } + + public string GetName() + { + return "Root Agent Count"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + " agent(s)"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ChildAgentCountMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ChildAgentCountMonitor.cs new file mode 100644 index 0000000000..afe6b79953 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ChildAgentCountMonitor.cs @@ -0,0 +1,33 @@ +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class ChildAgentCountMonitor : IMonitor + { + private readonly Scene m_scene; + + public ChildAgentCountMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return m_scene.SceneGraph.GetChildAgentCount(); + } + + public string GetName() + { + return "Child Agent Count"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + " child agent(s)"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/EventFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/EventFrameMonitor.cs new file mode 100644 index 0000000000..dec5a9e445 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/EventFrameMonitor.cs @@ -0,0 +1,33 @@ +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class EventFrameMonitor : IMonitor + { + private readonly Scene m_scene; + + public EventFrameMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return m_scene.MonitorEventTime; + } + + public string GetName() + { + return "Total Event Frame Time"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + "ms"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/GCMemoryMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/GCMemoryMonitor.cs new file mode 100644 index 0000000000..cd67fea9ac --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/GCMemoryMonitor.cs @@ -0,0 +1,26 @@ +using System; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class GCMemoryMonitor : IMonitor + { + #region Implementation of IMonitor + + public double GetValue() + { + return GC.GetTotalMemory(false); + } + + public string GetName() + { + return "GC Reported Memory"; + } + + public string GetFriendlyValue() + { + return (int)(GetValue() / (1024*1024)) + "MB (Global)"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LandFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LandFrameMonitor.cs new file mode 100644 index 0000000000..d883fc7ee5 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LandFrameMonitor.cs @@ -0,0 +1,33 @@ +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class LandFrameMonitor : IMonitor + { + private readonly Scene m_scene; + + public LandFrameMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return m_scene.MonitorLandTime; + } + + public string GetName() + { + return "Land Frame Time"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + "ms"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LastFrameTimeMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LastFrameTimeMonitor.cs new file mode 100644 index 0000000000..36363f89f8 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/LastFrameTimeMonitor.cs @@ -0,0 +1,34 @@ +using System; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class LastFrameTimeMonitor : IMonitor + { + private readonly Scene m_scene; + + public LastFrameTimeMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return Environment.TickCount - m_scene.MonitorLastFrameTick; + } + + public string GetName() + { + return "Last Completed Frame At"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + "ms ago"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ObjectCountMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ObjectCountMonitor.cs new file mode 100644 index 0000000000..dd9b19df51 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ObjectCountMonitor.cs @@ -0,0 +1,33 @@ +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class ObjectCountMonitor : IMonitor + { + private readonly Scene m_scene; + + public ObjectCountMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return m_scene.SceneGraph.GetTotalObjectsCount(); + } + + public string GetName() + { + return "Total Objects Count"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + " Object(s)"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PWSMemoryMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PWSMemoryMonitor.cs new file mode 100644 index 0000000000..88f2938c52 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PWSMemoryMonitor.cs @@ -0,0 +1,26 @@ +using System; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class PWSMemoryMonitor : IMonitor + { + #region Implementation of IMonitor + + public double GetValue() + { + return System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64; + } + + public string GetName() + { + return "Private Working Set Memory"; + } + + public string GetFriendlyValue() + { + return (int)(GetValue() / (1024 * 1024)) + "MB (Global)"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsFrameMonitor.cs new file mode 100644 index 0000000000..4d62e4f831 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsFrameMonitor.cs @@ -0,0 +1,33 @@ +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class PhysicsFrameMonitor : IMonitor + { + private readonly Scene m_scene; + + public PhysicsFrameMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return m_scene.MonitorPhysicsSyncTime + m_scene.MonitorPhysicsUpdateTime; + } + + public string GetName() + { + return "Total Physics Frame Time"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + "ms"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsUpdateFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsUpdateFrameMonitor.cs new file mode 100644 index 0000000000..91ac282ebd --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/PhysicsUpdateFrameMonitor.cs @@ -0,0 +1,33 @@ +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class PhysicsUpdateFrameMonitor : IMonitor + { + private readonly Scene m_scene; + + public PhysicsUpdateFrameMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return m_scene.MonitorPhysicsUpdateTime; + } + + public string GetName() + { + return "Physics Update Frame Time"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + "ms"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ThreadCountMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ThreadCountMonitor.cs new file mode 100644 index 0000000000..9300a932f5 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/ThreadCountMonitor.cs @@ -0,0 +1,25 @@ + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class ThreadCountMonitor : IMonitor + { + #region Implementation of IMonitor + + public double GetValue() + { + return System.Diagnostics.Process.GetCurrentProcess().Threads.Count; + } + + public string GetName() + { + return "Total Threads"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + " Thread(s) (Global)"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/TotalFrameMonitor.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/TotalFrameMonitor.cs new file mode 100644 index 0000000000..dea1f94ca6 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/Monitors/TotalFrameMonitor.cs @@ -0,0 +1,33 @@ +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors +{ + class TotalFrameMonitor : IMonitor + { + private readonly Scene m_scene; + + public TotalFrameMonitor(Scene scene) + { + m_scene = scene; + } + + #region Implementation of IMonitor + + public double GetValue() + { + return m_scene.MonitorFrameTime; + } + + public string GetName() + { + return "Total Frame Time"; + } + + public string GetFriendlyValue() + { + return (int)GetValue() + "ms"; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs index 4199c98a9d..46ee3c005a 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs @@ -193,6 +193,10 @@ namespace OpenSim.Region.CoreModules.Hypergrid { return scene.RegionInfo; } + else if (m_scenes.Count > 0) + { + return m_scenes[0].RegionInfo; + } return null; } @@ -248,7 +252,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid { foreach (Scene nextScene in m_scenes) { - if (nextScene.RegionInfo.RegionName == regionName) + if (nextScene.RegionInfo.RegionName.Equals(regionName, StringComparison.InvariantCultureIgnoreCase)) { scene = nextScene; return true; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs index 046bee5b63..40ac647d08 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs @@ -322,10 +322,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { List rinfos = new List(); - // Commenting until regionname exists - //foreach (SimpleRegionInfo r in m_HyperlinkRegions.Values) - // if ((r.RegionName != null) && r.RegionName.StartsWith(name)) - // rinfos.Add(r); + if (name == string.Empty) + return rinfos; + + foreach (GridRegion r in m_HyperlinkRegions.Values) + if ((r.RegionName != null) && r.RegionName.ToLower().StartsWith(name.ToLower())) + rinfos.Add(r); rinfos.AddRange(m_GridServiceConnector.GetRegionsByName(scopeID, name, maxNumber)); return rinfos; diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 54acbc4359..c261943a3c 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -129,6 +129,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver successfulAssetRestores++; else failedAssetRestores++; + + if ((successfulAssetRestores + failedAssetRestores) % 250 == 0) + m_log.Debug("[ARCHIVER]: Loaded " + successfulAssetRestores + " assets and failed to load " + failedAssetRestores + " assets..."); } else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index d01cef7bcf..d1d6b6a377 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -35,7 +35,7 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.Framework.Scenes { #region Delegates - public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectIDID); + public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectID); public delegate void SetBypassPermissionsHandler(bool value); public delegate bool BypassPermissionsHandler(); public delegate bool PropagatePermissionsHandler(); @@ -147,28 +147,28 @@ namespace OpenSim.Region.Framework.Scenes public uint GenerateClientFlags(UUID userID, UUID objectID) { - SceneObjectPart part=m_scene.GetSceneObjectPart(objectID); + // libomv will moan about PrimFlags.ObjectYouOfficer being + // obsolete... +#pragma warning disable 0612 + const PrimFlags DEFAULT_FLAGS = + PrimFlags.ObjectModify | + PrimFlags.ObjectCopy | + PrimFlags.ObjectMove | + PrimFlags.ObjectTransfer | + PrimFlags.ObjectYouOwner | + PrimFlags.ObjectAnyOwner | + PrimFlags.ObjectOwnerModify | + PrimFlags.ObjectYouOfficer; +#pragma warning restore 0612 + + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); if (part == null) return 0; - // libomv will moan about PrimFlags.ObjectYouOfficer being - // obsolete... - #pragma warning disable 0612 - uint perms=part.GetEffectiveObjectFlags() | - (uint)PrimFlags.ObjectModify | - (uint)PrimFlags.ObjectCopy | - (uint)PrimFlags.ObjectMove | - (uint)PrimFlags.ObjectTransfer | - (uint)PrimFlags.ObjectYouOwner | - (uint)PrimFlags.ObjectAnyOwner | - (uint)PrimFlags.ObjectOwnerModify | - (uint)PrimFlags.ObjectYouOfficer; - #pragma warning restore 0612 - - GenerateClientFlagsHandler handlerGenerateClientFlags = - OnGenerateClientFlags; + uint perms = part.GetEffectiveObjectFlags() | (uint)DEFAULT_FLAGS; + GenerateClientFlagsHandler handlerGenerateClientFlags = OnGenerateClientFlags; if (handlerGenerateClientFlags != null) { Delegate[] list = handlerGenerateClientFlags.GetInvocationList(); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7c3875d5f0..a6ee40a0ab 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -135,6 +135,11 @@ namespace OpenSim.Region.Framework.Scenes protected SceneCommunicationService m_sceneGridService; public bool loginsdisabled = true; + public new float TimeDilation + { + get { return m_sceneGraph.PhysicsScene.TimeDilation; } + } + public SceneCommunicationService SceneGridService { get { return m_sceneGridService; } @@ -252,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes // Central Update Loop protected int m_fps = 10; - protected int m_frame; + protected uint m_frame; protected float m_timespan = 0.089f; protected DateTime m_lastupdate = DateTime.UtcNow; @@ -269,6 +274,23 @@ namespace OpenSim.Region.Framework.Scenes private int physicsMS2; private int physicsMS; private int otherMS; + private int tempOnRezMS; + private int eventMS; + private int backupMS; + private int terrainMS; + private int landMS; + private int lastCompletedFrame; + + public int MonitorFrameTime { get { return frameMS; } } + public int MonitorPhysicsUpdateTime { get { return physicsMS; } } + public int MonitorPhysicsSyncTime { get { return physicsMS2; } } + public int MonitorOtherTime { get { return otherMS; } } + public int MonitorTempOnRezTime { get { return tempOnRezMS; } } + public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event? + public int MonitorBackupTime { get { return backupMS; } } + public int MonitorTerrainTime { get { return terrainMS; } } + public int MonitorLandTime { get { return landMS; } } + public int MonitorLastFrameTick { get { return lastCompletedFrame; } } private bool m_physics_enabled = true; private bool m_scripts_enabled = true; @@ -1013,36 +1035,25 @@ namespace OpenSim.Region.Framework.Scenes /// public override void Update() { - int maintc = 0; + float physicsFPS; + int maintc; + while (!shuttingdown) { -//#if DEBUG -// int w = 0, io = 0; -// ThreadPool.GetAvailableThreads(out w, out io); -// if ((w < 10) || (io < 10)) -// m_log.DebugFormat("[WARNING]: ThreadPool reaching exhaustion. workers = {0}; io = {1}", w, io); -//#endif - maintc = Environment.TickCount; - TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; - float physicsFPS = 0; + physicsFPS = 0f; - frameMS = Environment.TickCount; + maintc = maintc = otherMS = Environment.TickCount; + int tmpFrameMS = maintc; + + // Increment the frame counter + ++m_frame; try { - // Increment the frame counter - m_frame++; - - // Loop it - if (m_frame == Int32.MaxValue) - m_frame = 0; - - otherMS = Environment.TickCount; - // Check if any objects have reached their targets CheckAtTargets(); - + // Update SceneObjectGroups that have scheduled themselves for updates // Objects queue their updates onto all scene presences if (m_frame % m_update_objects == 0) @@ -1053,62 +1064,92 @@ namespace OpenSim.Region.Framework.Scenes if (m_frame % m_update_presences == 0) m_sceneGraph.UpdatePresences(); - physicsMS2 = Environment.TickCount; + int TempPhysicsMS2 = Environment.TickCount; if ((m_frame % m_update_physics == 0) && m_physics_enabled) m_sceneGraph.UpdatePreparePhysics(); - physicsMS2 = Environment.TickCount - physicsMS2; + TempPhysicsMS2 = Environment.TickCount - TempPhysicsMS2; + physicsMS2 = TempPhysicsMS2; if (m_frame % m_update_entitymovement == 0) m_sceneGraph.UpdateScenePresenceMovement(); - physicsMS = Environment.TickCount; - if ((m_frame % m_update_physics == 0) && m_physics_enabled) - physicsFPS = m_sceneGraph.UpdatePhysics( - Math.Max(SinceLastFrame.TotalSeconds, m_timespan) - ); - if (m_frame % m_update_physics == 0 && SynchronizeScene != null) - SynchronizeScene(this); - - physicsMS = Environment.TickCount - physicsMS; - physicsMS += physicsMS2; + int TempPhysicsMS = Environment.TickCount; + if (m_frame % m_update_physics == 0) + { + if (m_physics_enabled) + physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan)); + if (SynchronizeScene != null) + SynchronizeScene(this); + } + TempPhysicsMS = Environment.TickCount - TempPhysicsMS; + physicsMS = TempPhysicsMS; // Delete temp-on-rez stuff if (m_frame % m_update_backup == 0) + { + int tozMS = Environment.TickCount; CleanTempObjects(); + tozMS -= Environment.TickCount; + tempOnRezMS = tozMS; + } if (RegionStatus != RegionStatus.SlaveScene) { if (m_frame % m_update_events == 0) + { + int evMS = Environment.TickCount; UpdateEvents(); + evMS -= Environment.TickCount; + eventMS = evMS; + } if (m_frame % m_update_backup == 0) + { + int backMS = Environment.TickCount; UpdateStorageBackup(); + backMS -= Environment.TickCount; + backupMS = backMS; + } if (m_frame % m_update_terrain == 0) + { + int terMS = Environment.TickCount; UpdateTerrain(); + terMS -= Environment.TickCount; + terrainMS = terMS; + } if (m_frame % m_update_land == 0) + { + int ldMS = Environment.TickCount; UpdateLand(); + ldMS -= Environment.TickCount; + landMS = ldMS; + } + + int tickCount = Environment.TickCount; + otherMS = tickCount - otherMS; + tmpFrameMS -= tickCount; + frameMS = tmpFrameMS; + lastCompletedFrame = tickCount; - otherMS = Environment.TickCount - otherMS; // if (m_frame%m_update_avatars == 0) // UpdateInWorldTime(); StatsReporter.AddPhysicsFPS(physicsFPS); - StatsReporter.AddTimeDilation(m_timedilation); + StatsReporter.AddTimeDilation(TimeDilation); StatsReporter.AddFPS(1); - StatsReporter.AddInPackets(0); StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); - frameMS = Environment.TickCount - frameMS; StatsReporter.addFrameMS(frameMS); - StatsReporter.addPhysicsMS(physicsMS); + StatsReporter.addPhysicsMS(physicsMS + physicsMS2); StatsReporter.addOtherMS(otherMS); StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); } - if (loginsdisabled && (m_frame > 20)) + + if (loginsdisabled && m_frame > 20) { // In 99.9% of cases it is a bad idea to manually force garbage collection. However, // this is a rare case where we know we have just went through a long cycle of heap @@ -1141,18 +1182,6 @@ namespace OpenSim.Region.Framework.Scenes } finally { - //updateLock.ReleaseMutex(); - // Get actual time dilation - float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds); - - // If actual time dilation is greater then one, we're catching up, so subtract - // the amount that's greater then 1 from the time dilation - if (tmpval > 1.0) - { - tmpval = tmpval - (tmpval - 1.0f); - } - m_timedilation = tmpval; - m_lastupdate = DateTime.UtcNow; } maintc = Environment.TickCount - maintc; @@ -1183,9 +1212,9 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_groupsWithTargets) { - foreach (KeyValuePair kvp in m_groupsWithTargets) + foreach (SceneObjectGroup entry in m_groupsWithTargets.Values) { - kvp.Value.checkAtTargets(); + entry.checkAtTargets(); } } } @@ -4606,7 +4635,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup if (trackedBody == null) return; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy. jointProxyObject.Velocity = trackedBody.Velocity; - jointProxyObject.RotationalVelocity = trackedBody.RotationalVelocity; + jointProxyObject.AngularVelocity = trackedBody.AngularVelocity; switch (joint.Type) { case PhysicsJointType.Ball: diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 82731d1c58..1547f9a9b6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -106,9 +106,8 @@ namespace OpenSim.Region.Framework.Scenes public float TimeDilation { - get { return m_timedilation; } + get { return 1.0f; } } - protected float m_timedilation = 1.0f; protected ulong m_regionHandle; protected string m_regionName; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index db055f968e..2fdb48dd89 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -369,26 +369,30 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void UpdateObjectGroups() { - Dictionary updates; + List updates; + // Some updates add more updates to the updateList. // Get the current list of updates and clear the list before iterating lock (m_updateList) { - updates = new Dictionary(m_updateList); + updates = new List(m_updateList.Values); m_updateList.Clear(); } + // Go through all updates - foreach (KeyValuePair kvp in updates) + for (int i = 0; i < updates.Count; i++) { + SceneObjectGroup sog = updates[i]; + // Don't abort the whole update if one entity happens to give us an exception. try { - kvp.Value.Update(); + sog.Update(); } catch (Exception e) { m_log.ErrorFormat( - "[INNER SCENE]: Failed to update {0}, {1} - {2}", kvp.Value.Name, kvp.Value.UUID, e); + "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 38a0cff7bf..0b752c967a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1015,9 +1015,9 @@ namespace OpenSim.Region.Framework.Scenes } } - public float GetTimeDilation() + public ushort GetTimeDilation() { - return m_scene.TimeDilation; + return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); } /// @@ -1857,28 +1857,15 @@ namespace OpenSim.Region.Framework.Scenes { bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); - //if (IsAttachment) - //{ - //foreach (SceneObjectPart part in m_parts.Values) - //{ - //part.SendScheduledUpdates(); - //} - //return; - //} - - if (UsePhysics && Util.DistanceLessThan(lastPhysGroupPos, AbsolutePosition, 0.02)) + if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) { m_rootPart.UpdateFlag = 1; lastPhysGroupPos = AbsolutePosition; } - if (UsePhysics && ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1) - || (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1) - || (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1) - || (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1))) + if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) { m_rootPart.UpdateFlag = 1; - lastPhysGroupRot = GroupRotation; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9b11582d7b..2bc7f66ef9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -253,6 +253,7 @@ namespace OpenSim.Region.Framework.Scenes protected Vector3 m_lastVelocity; protected Vector3 m_lastAcceleration; protected Vector3 m_lastAngularVelocity; + protected int m_lastTerseSent; // TODO: Those have to be changed into persistent properties at some later point, // or sit-camera on vehicles will break on sim-crossing. @@ -506,20 +507,17 @@ namespace OpenSim.Region.Framework.Scenes get { // If this is a linkset, we don't want the physics engine mucking up our group position here. - if (PhysActor != null && _parentID == 0) + PhysicsActor actor = PhysActor; + if (actor != null && _parentID == 0) { - m_groupPosition.X = PhysActor.Position.X; - m_groupPosition.Y = PhysActor.Position.Y; - m_groupPosition.Z = PhysActor.Position.Z; + m_groupPosition = actor.Position; } if (IsAttachment) { ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar); if (sp != null) - { return sp.AbsolutePosition; - } } return m_groupPosition; @@ -530,26 +528,25 @@ namespace OpenSim.Region.Framework.Scenes m_groupPosition = value; - if (PhysActor != null) + PhysicsActor actor = PhysActor; + if (actor != null) { try { // Root prim actually goes at Position if (_parentID == 0) { - PhysActor.Position = value; + actor.Position = value; } else { // To move the child prim in respect to the group position and rotation we have to calculate - Vector3 resultingposition = GetWorldPosition(); - PhysActor.Position = resultingposition; - Quaternion resultingrot = GetWorldRotation(); - PhysActor.Orientation = resultingrot; + actor.Position = GetWorldPosition(); + actor.Orientation = GetWorldRotation(); } // Tell the physics engines that this prim changed. - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); } catch (Exception e) { @@ -582,15 +579,14 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup != null && !ParentGroup.IsDeleted) { - if (_parentID != 0 && PhysActor != null) + PhysicsActor actor = PhysActor; + if (_parentID != 0 && actor != null) { - Vector3 resultingposition = GetWorldPosition(); - PhysActor.Position = resultingposition; - Quaternion resultingrot = GetWorldRotation(); - PhysActor.Orientation = resultingrot; + actor.Position = GetWorldPosition(); + actor.Orientation = GetWorldRotation(); // Tell the physics engines that this prim changed. - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); } } } @@ -601,12 +597,13 @@ namespace OpenSim.Region.Framework.Scenes get { // We don't want the physics engine mucking up the rotations in a linkset - if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (PhysActor != null)) + PhysicsActor actor = PhysActor; + if (_parentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null) { - if (PhysActor.Orientation.X != 0 || PhysActor.Orientation.Y != 0 - || PhysActor.Orientation.Z != 0 || PhysActor.Orientation.W != 0) + if (actor.Orientation.X != 0f || actor.Orientation.Y != 0f + || actor.Orientation.Z != 0f || actor.Orientation.W != 0f) { - m_rotationOffset = PhysActor.Orientation; + m_rotationOffset = actor.Orientation; } } @@ -618,24 +615,25 @@ namespace OpenSim.Region.Framework.Scenes StoreUndoState(); m_rotationOffset = value; - if (PhysActor != null) + PhysicsActor actor = PhysActor; + if (actor != null) { try { // Root prim gets value directly if (_parentID == 0) { - PhysActor.Orientation = value; - //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString()); + actor.Orientation = value; + //m_log.Info("[PART]: RO1:" + actor.Orientation.ToString()); } else { // Child prim we have to calculate it's world rotationwel Quaternion resultingrotation = GetWorldRotation(); - PhysActor.Orientation = resultingrotation; - //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString()); + actor.Orientation = resultingrotation; + //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); } - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); //} } catch (Exception ex) @@ -652,16 +650,12 @@ namespace OpenSim.Region.Framework.Scenes { get { - //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0 - //|| PhysActor.Velocity.Z != 0) - //{ - if (PhysActor != null) + PhysicsActor actor = PhysActor; + if (actor != null) { - if (PhysActor.IsPhysical) + if (actor.IsPhysical) { - m_velocity.X = PhysActor.Velocity.X; - m_velocity.Y = PhysActor.Velocity.Y; - m_velocity.Z = PhysActor.Velocity.Z; + m_velocity = actor.Velocity; } } @@ -671,31 +665,28 @@ namespace OpenSim.Region.Framework.Scenes set { m_velocity = value; - if (PhysActor != null) + + PhysicsActor actor = PhysActor; + if (actor != null) { - if (PhysActor.IsPhysical) + if (actor.IsPhysical) { - PhysActor.Velocity = value; - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + actor.Velocity = value; + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); } } } } - public Vector3 RotationalVelocity - { - get { return AngularVelocity; } - set { AngularVelocity = value; } - } - /// public Vector3 AngularVelocity { get { - if ((PhysActor != null) && PhysActor.IsPhysical) + PhysicsActor actor = PhysActor; + if ((actor != null) && actor.IsPhysical) { - m_angularVelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(), 0); + m_angularVelocity = actor.RotationalVelocity; } return m_angularVelocity; } @@ -715,9 +706,10 @@ namespace OpenSim.Region.Framework.Scenes set { m_description = value; - if (PhysActor != null) + PhysicsActor actor = PhysActor; + if (actor != null) { - PhysActor.SOPDescription = value; + actor.SOPDescription = value; } } } @@ -808,21 +800,23 @@ namespace OpenSim.Region.Framework.Scenes set { StoreUndoState(); -if (m_shape != null) { - m_shape.Scale = value; - - if (PhysActor != null && m_parentGroup != null) + if (m_shape != null) { - if (m_parentGroup.Scene != null) + m_shape.Scale = value; + + PhysicsActor actor = PhysActor; + if (actor != null && m_parentGroup != null) { - if (m_parentGroup.Scene.PhysicsScene != null) + if (m_parentGroup.Scene != null) { - PhysActor.Size = m_shape.Scale; - m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + if (m_parentGroup.Scene.PhysicsScene != null) + { + actor.Size = m_shape.Scale; + m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); + } } } } -} TriggerScriptChangedEvent(Changed.SCALE); } } @@ -1056,8 +1050,6 @@ if (m_shape != null) { #endregion Public Properties with only Get - - #region Private Methods private uint ApplyMask(uint val, bool set, uint mask) @@ -1551,9 +1543,9 @@ if (m_shape != null) { m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed? // make sure client isn't interpolating the joint proxy object - Velocity = new Vector3(0, 0, 0); - RotationalVelocity = new Vector3(0, 0, 0); - Acceleration = new Vector3(0, 0, 0); + Velocity = Vector3.Zero; + AngularVelocity = Vector3.Zero; + Acceleration = Vector3.Zero; } } } @@ -1816,7 +1808,7 @@ if (m_shape != null) { } CollisionEventUpdate a = (CollisionEventUpdate)e; - Dictionary collissionswith = a.m_objCollisionList; + Dictionary collissionswith = a.m_objCollisionList; List thisHitColliders = new List(); List endedColliders = new List(); List startedColliders = new List(); @@ -2382,8 +2374,8 @@ if (m_shape != null) { //isattachment = ParentGroup.RootPart.IsAttachment; byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; - remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, - lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, + remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape, + lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID, m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); } @@ -2393,17 +2385,20 @@ if (m_shape != null) { /// public void SendScheduledUpdates() { - const float VELOCITY_TOLERANCE = 0.01f; - const float POSITION_TOLERANCE = 0.1f; + const float ROTATION_TOLERANCE = 0.01f; + const float VELOCITY_TOLERANCE = 0.001f; + const float POSITION_TOLERANCE = 0.05f; + const int TIME_MS_TOLERANCE = 3000; if (m_updateFlag == 1) { // Throw away duplicate or insignificant updates - if (RotationOffset != m_lastRotation || - Acceleration != m_lastAcceleration || - (Velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE || - (RotationalVelocity - m_lastAngularVelocity).Length() > VELOCITY_TOLERANCE || - (OffsetPosition - m_lastPosition).Length() > POSITION_TOLERANCE) + if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + !Acceleration.Equals(m_lastAcceleration) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || + !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || + Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) { AddTerseUpdateToAllAvatars(); ClearUpdateSchedule(); @@ -2421,7 +2416,8 @@ if (m_shape != null) { m_lastRotation = RotationOffset; m_lastVelocity = Velocity; m_lastAcceleration = Acceleration; - m_lastAngularVelocity = RotationalVelocity; + m_lastAngularVelocity = AngularVelocity; + m_lastTerseSent = Environment.TickCount; } } else @@ -3780,10 +3776,9 @@ if (m_shape != null) { // Causes this thread to dig into the Client Thread Data. // Remember your locking here! remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, - (ushort)(m_parentGroup.GetTimeDilation() * - (float)ushort.MaxValue), LocalId, lPos, + m_parentGroup.GetTimeDilation(), LocalId, lPos, RotationOffset, Velocity, Acceleration, - RotationalVelocity, state, FromItemID, + AngularVelocity, state, FromItemID, OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 87fac0c5e7..6c0d9f2a9b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -76,8 +76,18 @@ namespace OpenSim.Region.Framework.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; - - public static byte[] DefaultTexture; + private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); + private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); + private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); + /// + /// Experimentally determined "fudge factor" to make sit-target positions + /// the same as in SecondLife. Fudge factor was tested for 36 different + /// test cases including prims of type box, sphere, cylinder, and torus, + /// with varying parameters for sit target location, prim size, prim + /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis + /// issue #1716 + /// + private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); public UUID currentParcelUUID = UUID.Zero; @@ -92,16 +102,18 @@ namespace OpenSim.Region.Framework.Scenes //private SceneObjectPart proxyObjectPart = null; public Vector3 lastKnownAllowedPosition; public bool sentMessageAboutRestrictedParcelFlyingDown; + public Vector4 CollisionPlane = Vector4.UnitW; private Vector3 m_lastPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; + //private int m_lastTerseSent; private bool m_updateflag; private byte m_movementflag; - private readonly List m_forcesList = new List(); + private Vector3? m_forceToApply; private uint m_requestedSitTargetID; - private UUID m_requestedSitTargetUUID = UUID.Zero; + private UUID m_requestedSitTargetUUID; private SendCourseLocationsMethod m_sendCourseLocationsMethod; private bool m_startAnimationSet; @@ -112,30 +124,24 @@ namespace OpenSim.Region.Framework.Scenes private float m_sitAvatarHeight = 2.0f; - // experimentally determined "fudge factor" to make sit-target positions - // the same as in SecondLife. Fudge factor was tested for 36 different - // test cases including prims of type box, sphere, cylinder, and torus, - // with varying parameters for sit target location, prim size, prim - // rotation, prim cut, prim twist, prim taper, and prim shear. See mantis - // issue #1716 - private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f); private float m_godlevel; private bool m_invulnerable = true; - private Vector3 m_LastChildAgentUpdatePosition; + private Vector3 m_lastChildAgentUpdatePosition; + private Vector3 m_lastChildAgentUpdateCamPosition; private int m_perfMonMS; private bool m_setAlwaysRun; private string m_movementAnimation = "DEFAULT"; - private long m_animPersistUntil = 0; - private bool m_allowFalling = false; - private bool m_useFlySlow = false; - private bool m_usePreJump = false; - private bool m_forceFly = false; - private bool m_flyDisabled = false; + private int m_animTickFall; + private int m_animTickJump; + private bool m_useFlySlow; + private bool m_usePreJump; + private bool m_forceFly; + private bool m_flyDisabled; private float m_speedModifier = 1.0f; @@ -143,7 +149,7 @@ namespace OpenSim.Region.Framework.Scenes public bool IsRestrictedToRegion; - public string JID = string.Empty; + public string JID = String.Empty; // Agent moves with a PID controller causing a force to be exerted. private bool m_newCoarseLocations = true; @@ -158,43 +164,43 @@ namespace OpenSim.Region.Framework.Scenes private readonly Vector3[] Dir_Vectors = new Vector3[6]; // Position of agent's camera in world (region cordinates) - protected Vector3 m_CameraCenter = Vector3.Zero; - protected Vector3 m_lastCameraCenter = Vector3.Zero; + protected Vector3 m_CameraCenter; + protected Vector3 m_lastCameraCenter; protected Timer m_reprioritization_timer; - protected bool m_reprioritizing = false; - protected bool m_reprioritization_called = false; + protected bool m_reprioritizing; + protected bool m_reprioritization_called; // Use these three vectors to figure out what the agent is looking at // Convert it to a Matrix and/or Quaternion - protected Vector3 m_CameraAtAxis = Vector3.Zero; - protected Vector3 m_CameraLeftAxis = Vector3.Zero; - protected Vector3 m_CameraUpAxis = Vector3.Zero; - private uint m_AgentControlFlags; + protected Vector3 m_CameraAtAxis; + protected Vector3 m_CameraLeftAxis; + protected Vector3 m_CameraUpAxis; + private AgentManager.ControlFlags m_AgentControlFlags; private Quaternion m_headrotation = Quaternion.Identity; private byte m_state; //Reuse the Vector3 instead of creating a new one on the UpdateMovement method - private Vector3 movementvector = Vector3.Zero; + private Vector3 movementvector; private bool m_autopilotMoving; - private Vector3 m_autoPilotTarget = Vector3.Zero; + private Vector3 m_autoPilotTarget; private bool m_sitAtAutoTarget; private string m_nextSitAnimation = String.Empty; //PauPaw:Proper PID Controler for autopilot************ private bool m_moveToPositionInProgress; - private Vector3 m_moveToPositionTarget = Vector3.Zero; + private Vector3 m_moveToPositionTarget; - private bool m_followCamAuto = false; + private bool m_followCamAuto; - private int m_movementUpdateCount = 0; + private int m_movementUpdateCount; private const int NumMovementsBetweenRayCast = 5; - private bool CameraConstraintActive = false; - //private int m_moveToPositionStateStatus = 0; + private bool CameraConstraintActive; + //private int m_moveToPositionStateStatus; //***************************************************** // Agent's Draw distance. @@ -268,11 +274,9 @@ namespace OpenSim.Region.Framework.Scenes get { return m_godlevel; } } - private readonly ulong m_regionHandle; - public ulong RegionHandle { - get { return m_regionHandle; } + get { return m_rootRegionHandle; } } public Vector3 CameraPosition @@ -379,8 +383,8 @@ namespace OpenSim.Region.Framework.Scenes public uint AgentControlFlags { - get { return m_AgentControlFlags; } - set { m_AgentControlFlags = value; } + get { return (uint)m_AgentControlFlags; } + set { m_AgentControlFlags = (AgentManager.ControlFlags)value; } } /// @@ -411,31 +415,27 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Absolute position of this avatar in 'region cordinates' + /// Position of this avatar relative to the region the avatar is in /// public override Vector3 AbsolutePosition { get { - if (m_physicsActor != null) - { - m_pos.X = m_physicsActor.Position.X; - m_pos.Y = m_physicsActor.Position.Y; - m_pos.Z = m_physicsActor.Position.Z; - } + PhysicsActor actor = m_physicsActor; + if (actor != null) + m_pos = actor.Position; return m_parentPosition + m_pos; } set { - if (m_physicsActor != null) + PhysicsActor actor = m_physicsActor; + if (actor != null) { try { lock (m_scene.SyncRoot) - { m_physicsActor.Position = value; - } } catch (Exception e) { @@ -444,7 +444,7 @@ namespace OpenSim.Region.Framework.Scenes } m_pos = value; - m_parentPosition = new Vector3(0, 0, 0); + m_parentPosition = Vector3.Zero; } } @@ -455,27 +455,21 @@ namespace OpenSim.Region.Framework.Scenes { get { - if (m_physicsActor != null) - { - m_velocity.X = m_physicsActor.Velocity.X; - m_velocity.Y = m_physicsActor.Velocity.Y; - m_velocity.Z = m_physicsActor.Velocity.Z; - } + PhysicsActor actor = m_physicsActor; + if (actor != null) + m_velocity = actor.Velocity; return m_velocity; } set { - //m_log.DebugFormat("In {0} setting velocity of {1} to {2}", m_scene.RegionInfo.RegionName, Name, value); - - if (m_physicsActor != null) + PhysicsActor actor = m_physicsActor; + if (actor != null) { try { lock (m_scene.SyncRoot) - { - m_physicsActor.Velocity = value; - } + actor.Velocity = value; } catch (Exception e) { @@ -627,7 +621,7 @@ namespace OpenSim.Region.Framework.Scenes { m_sendCourseLocationsMethod = SendCoarseLocationsDefault; CreateSceneViewer(); - m_regionHandle = reginfo.RegionHandle; + m_rootRegionHandle = reginfo.RegionHandle; m_controllingClient = client; m_firstname = m_controllingClient.FirstName; m_lastname = m_controllingClient.LastName; @@ -710,25 +704,25 @@ namespace OpenSim.Region.Framework.Scenes private void SetDirectionVectors() { - Dir_Vectors[0] = new Vector3(1, 0, 0); //FORWARD - Dir_Vectors[1] = new Vector3(-1, 0, 0); //BACK - Dir_Vectors[2] = new Vector3(0, 1, 0); //LEFT - Dir_Vectors[3] = new Vector3(0, -1, 0); //RIGHT - Dir_Vectors[4] = new Vector3(0, 0, 1); //UP - Dir_Vectors[5] = new Vector3(0, 0, -1); //DOWN - Dir_Vectors[5] = new Vector3(0, 0, -0.5f); //DOWN_Nudge + Dir_Vectors[0] = Vector3.UnitX; //FORWARD + Dir_Vectors[1] = -Vector3.UnitX; //BACK + Dir_Vectors[2] = Vector3.UnitY; //LEFT + Dir_Vectors[3] = -Vector3.UnitY; //RIGHT + Dir_Vectors[4] = Vector3.UnitZ; //UP + Dir_Vectors[5] = -Vector3.UnitZ; //DOWN + Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge } private Vector3[] GetWalkDirectionVectors() { Vector3[] vector = new Vector3[6]; - vector[0] = new Vector3(m_CameraUpAxis.Z, 0, -m_CameraAtAxis.Z); //FORWARD - vector[1] = new Vector3(-m_CameraUpAxis.Z, 0, m_CameraAtAxis.Z); //BACK - vector[2] = new Vector3(0, 1, 0); //LEFT - vector[3] = new Vector3(0, -1, 0); //RIGHT - vector[4] = new Vector3(m_CameraAtAxis.Z, 0, m_CameraUpAxis.Z); //UP - vector[5] = new Vector3(-m_CameraAtAxis.Z, 0, -m_CameraUpAxis.Z); //DOWN - vector[5] = new Vector3(-m_CameraAtAxis.Z, 0, -m_CameraUpAxis.Z); //DOWN_Nudge + vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD + vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK + vector[2] = Vector3.UnitY; //LEFT + vector[3] = -Vector3.UnitY; //RIGHT + vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP + vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN + vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge return vector; } @@ -781,6 +775,8 @@ namespace OpenSim.Region.Framework.Scenes if (gm != null) m_grouptitle = gm.GetGroupTitle(m_uuid); + m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; + m_scene.SetRootAgentScene(m_uuid); // Moved this from SendInitialData to ensure that m_appearance is initialized @@ -811,7 +807,6 @@ namespace OpenSim.Region.Framework.Scenes pos = emergencyPos; } - float localAVHeight = 1.56f; if (m_avHeight != 127.0f) { @@ -906,6 +901,8 @@ namespace OpenSim.Region.Framework.Scenes m_isChildAgent = true; m_scene.SwapRootAgentCount(true); RemoveFromPhysicalScene(); + + // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into m_scene.EventManager.TriggerOnMakeChildAgent(this); } @@ -937,7 +934,7 @@ namespace OpenSim.Region.Framework.Scenes isFlying = m_physicsActor.Flying; RemoveFromPhysicalScene(); - Velocity = new Vector3(0, 0, 0); + Velocity = Vector3.Zero; AbsolutePosition = pos; AddToPhysicalScene(isFlying); if (m_appearance != null) @@ -985,12 +982,13 @@ namespace OpenSim.Region.Framework.Scenes if (m_avHeight != 127.0f) { - AbsolutePosition = AbsolutePosition + new Vector3(0, 0, (m_avHeight / 6f)); + AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (m_avHeight / 6f)); } else { - AbsolutePosition = AbsolutePosition + new Vector3(0, 0, (1.56f / 6f)); + AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); } + TrySetMovementAnimation("LAND"); SendFullUpdateToAllClients(); } @@ -1076,7 +1074,7 @@ namespace OpenSim.Region.Framework.Scenes } m_isChildAgent = false; - bool m_flying = ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); MakeRootAgent(AbsolutePosition, m_flying); if ((m_callbackURI != null) && !m_callbackURI.Equals("")) @@ -1103,9 +1101,12 @@ namespace OpenSim.Region.Framework.Scenes /// public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) { + const float POSITION_TOLERANCE = 0.02f; + const float VELOCITY_TOLERANCE = 0.02f; + const float ROTATION_TOLERANCE = 0.02f; + if (m_followCamAuto) { - if (hitYN) { CameraConstraintActive = true; @@ -1114,11 +1115,11 @@ namespace OpenSim.Region.Framework.Scenes Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); } - else + else { - if ((m_pos - m_lastPosition).Length() > 0.02f || - (m_velocity - m_lastVelocity).Length() > 0.02f || - m_bodyRot != m_lastRotation) + if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) { if (CameraConstraintActive) { @@ -1127,13 +1128,11 @@ namespace OpenSim.Region.Framework.Scenes } } } - } + } } - Array m_dirControlFlags = Enum.GetValues(typeof(Dir_ControlFlags)); - /// - /// This is the event handler for client movement. If a client is moving, this event is triggering. + /// This is the event handler for client movement. If a client is moving, this event is triggering. /// public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { @@ -1149,15 +1148,13 @@ namespace OpenSim.Region.Framework.Scenes if (m_movementUpdateCount < 1) m_movementUpdateCount = 1; - // Must check for standing up even when PhysicsActor is null, - // since sitting currently removes avatar from physical scene - //m_log.Debug("agentPos:" + AbsolutePosition.ToString()); + #region Sanity Checking // This is irritating. Really. if (!AbsolutePosition.IsFinite()) { RemoveFromPhysicalScene(); - m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error# 9999902"); + m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); m_pos = m_LastFinitePos; if (!m_pos.IsFinite()) @@ -1165,7 +1162,7 @@ namespace OpenSim.Region.Framework.Scenes m_pos.X = 127f; m_pos.Y = 127f; m_pos.Z = 127f; - m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error# 9999903"); + m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); } AddToPhysicalScene(false); @@ -1175,18 +1172,11 @@ namespace OpenSim.Region.Framework.Scenes m_LastFinitePos = m_pos; } - //m_physicsActor.AddForce(new PhysicsVector(999999999, 99999999, 999999999999999), true); + #endregion Sanity Checking - //ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); - //if (land != null) - //{ - //if (land.landData.landingType == (byte)1 && land.landData.userLocation != Vector3.Zero) - //{ - // agent.startpos = land.landData.userLocation; - //} - //} + #region Inputs - uint flags = agentData.ControlFlags; + AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; Quaternion bodyRotation = agentData.BodyRotation; // Camera location in world. We'll need to raytrace @@ -1207,87 +1197,85 @@ namespace OpenSim.Region.Framework.Scenes // The Agent's Draw distance setting m_DrawDistance = agentData.Far; - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) - { - StandUp(); - } - // Check if Client has camera in 'follow cam' or 'build' mode. Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; + m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; + m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; + + #endregion Inputs + + if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) + { + StandUp(); + } + //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); // Raycast from the avatar's head to the camera to see if there's anything blocking the view if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) { if (m_followCamAuto) { - Vector3 headadjustment = new Vector3(0, 0, 0.3f); - m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - (m_pos + headadjustment)), Vector3.Distance(m_CameraCenter, (m_pos + headadjustment)) + 0.3f, RayCastCameraCallback); + Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; + m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); } } - m_mouseLook = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; - m_leftButtonDown = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; - lock (scriptedcontrols) { if (scriptedcontrols.Count > 0) { - SendControlToScripts(flags); + SendControlToScripts((uint)flags); flags = RemoveIgnoredControls(flags, IgnoredControls); } } - if (PhysicsActor == null) - { - return; - } - if (m_autopilotMoving) CheckAtSitTarget(); - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) + if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) { // TODO: This doesn't prevent the user from walking yet. // Setting parent ID would fix this, if we knew what value // to use. Or we could add a m_isSitting variable. - TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); } + // In the future, these values might need to go global. // Here's where you get them. - m_AgentControlFlags = flags; m_headrotation = agentData.HeadRotation; m_state = agentData.State; + PhysicsActor actor = PhysicsActor; + if (actor == null) + { + return; + } + if (m_allowMovement) { int i = 0; bool update_movementflag = false; bool update_rotation = false; bool DCFlagKeyPressed = false; - Vector3 agent_control_v3 = new Vector3(0, 0, 0); + Vector3 agent_control_v3 = Vector3.Zero; Quaternion q = bodyRotation; - if (PhysicsActor != null) - { - bool oldflying = PhysicsActor.Flying; - if (m_forceFly) - PhysicsActor.Flying = true; - else if (m_flyDisabled) - PhysicsActor.Flying = false; - else - PhysicsActor.Flying = ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + bool oldflying = PhysicsActor.Flying; - if (PhysicsActor.Flying != oldflying) - { - update_movementflag = true; - } - } + if (m_forceFly) + actor.Flying = true; + else if (m_flyDisabled) + actor.Flying = false; + else + actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + + if (actor.Flying != oldflying) + update_movementflag = true; if (q != m_bodyRot) { @@ -1309,10 +1297,9 @@ namespace OpenSim.Region.Framework.Scenes else dirVectors = Dir_Vectors; - - foreach (Dir_ControlFlags DCF in m_dirControlFlags) + foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) { - if ((flags & (uint)DCF) != 0) + if (((uint)flags & (uint)DCF) != 0) { bResetMoveToPosition = true; DCFlagKeyPressed = true; @@ -1358,7 +1345,7 @@ namespace OpenSim.Region.Framework.Scenes if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) { //Check the error term of the current position in relation to the target position - if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 1.5) + if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 1.5f) { // we are close enough to the target m_moveToPositionTarget = Vector3.Zero; @@ -1439,8 +1426,8 @@ namespace OpenSim.Region.Framework.Scenes if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) { // Are the landing controls requirements filled? - bool controlland = (((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || - ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || + ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); // Are the collision requirements fulfilled? bool colliding = (m_physicsActor.IsColliding == true); @@ -1537,7 +1524,7 @@ namespace OpenSim.Region.Framework.Scenes if (part != null) { AbsolutePosition = part.AbsolutePosition; - Velocity = new Vector3(0, 0, 0); + Velocity = Vector3.Zero; SendFullUpdateToAllClients(); //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); @@ -1607,7 +1594,7 @@ namespace OpenSim.Region.Framework.Scenes } m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); - m_parentPosition = new Vector3(); + m_parentPosition = Vector3.Zero; m_parentID = 0; SendFullUpdateToAllClients(); @@ -1834,7 +1821,7 @@ namespace OpenSim.Region.Framework.Scenes //Quaternion result = (sitTargetOrient * vq) * nq; m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); - m_pos += m_sitTargetCorrectionOffset; + m_pos += SIT_TARGET_ADJUSTMENT; m_bodyRot = sitTargetOrient; //Rotation = sitTargetOrient; m_parentPosition = part.AbsolutePosition; @@ -1854,7 +1841,7 @@ namespace OpenSim.Region.Framework.Scenes } m_parentID = m_requestedSitTargetID; - Velocity = new Vector3(0, 0, 0); + Velocity = Vector3.Zero; RemoveFromPhysicalScene(); TrySetMovementAnimation(sitAnimation); @@ -2011,7 +1998,7 @@ namespace OpenSim.Region.Framework.Scenes protected void TrySetMovementAnimation(string anim) { //m_log.DebugFormat("Updating movement animation to {0}", anim); - + if (!m_isChildAgent) { if (m_animations.TrySetDefaultAnimation(anim, m_controllingClient.NextAnimationSequenceNumber, UUID.Zero)) @@ -2046,200 +2033,169 @@ namespace OpenSim.Region.Framework.Scenes /// public string GetMovementAnimation() { - if ((m_animPersistUntil > 0) && (m_animPersistUntil > DateTime.Now.Ticks)) - { - //We don't want our existing state to end yet. - return m_movementAnimation; + const float FALL_DELAY = 0.33f; + const float PREJUMP_DELAY = 0.25f; - } - else if (m_movementflag != 0) + #region Inputs + + AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_AgentControlFlags; + PhysicsActor actor = m_physicsActor; + + // Create forward and left vectors from the current avatar rotation + Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_bodyRot); + Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix); + Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); + + // Check control flags + bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; + bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; + bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; + bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; + //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; + //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; + bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; + bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; + //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; + //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK; + + // Direction in which the avatar is trying to move + Vector3 move = Vector3.Zero; + if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; } + if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; } + if (heldLeft) { move.X += left.X; move.Y += left.Y; } + if (heldRight) { move.X -= left.X; move.Y -= left.Y; } + if (heldUp) { move.Z += 1; } + if (heldDown) { move.Z -= 1; } + + // Is the avatar trying to move? + bool moving = (move != Vector3.Zero); + bool jumping = m_animTickJump != 0; + + #endregion Inputs + + #region Flying + + if (actor != null && actor.Flying) { - //We're moving - m_allowFalling = true; - if (PhysicsActor != null && PhysicsActor.IsColliding) + m_animTickFall = 0; + m_animTickJump = 0; + + if (move.X != 0f || move.Y != 0f) { - //And colliding. Can you guess what it is yet? - if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) - { - //Down key is being pressed. - if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) + (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0) - { - return "CROUCHWALK"; - } - else - { - return "CROUCH"; - } - } - else if (m_setAlwaysRun) - { - return "RUN"; - } + return (m_useFlySlow ? "FLYSLOW" : "FLY"); + } + else if (move.Z > 0f) + { + return "HOVER_UP"; + } + else if (move.Z < 0f) + { + if (actor != null && actor.IsColliding) + return "LAND"; else - { - //If we're prejumping then inhibit this, it's a problem - //caused by a false positive on IsColliding - if (m_movementAnimation == "PREJUMP") - { - return "PREJUMP"; - } - else - { - return "WALK"; - } - } - + return "HOVER_DOWN"; } else { - //We're not colliding. Colliding isn't cool these days. - if (PhysicsActor != null && PhysicsActor.Flying) - { - //Are we moving forwards or backwards? - if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0) - { - //Then we really are flying - if (m_setAlwaysRun) - { - return "FLY"; - } - else - { - if (m_useFlySlow == false) - { - return "FLY"; - } - else - { - return "FLYSLOW"; - } - } - } - else - { - if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) - { - return "HOVER_UP"; - } - else - { - return "HOVER_DOWN"; - } - } + return "HOVER"; + } + } - } - else if (m_movementAnimation == "JUMP") + #endregion Flying + + #region Falling/Floating/Landing + + if (actor == null || !actor.IsColliding) + { + float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; + float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; + + if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f)) + { + // Just started falling + m_animTickFall = Environment.TickCount; + } + else if (!jumping && fallElapsed > FALL_DELAY) + { + // Falling long enough to trigger the animation + return "FALLDOWN"; + } + + return m_movementAnimation; + } + + #endregion Falling/Floating/Landing + + #region Ground Movement + + if (m_movementAnimation == "FALLDOWN") + { + m_animTickFall = Environment.TickCount; + + // TODO: SOFT_LAND support + return "LAND"; + } + else if (m_movementAnimation == "LAND") + { + float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; + + if (landElapsed <= FALL_DELAY) + return "LAND"; + } + + m_animTickFall = 0; + + if (move.Z > 0f) + { + // Jumping + if (!jumping) + { + // Begin prejump + m_animTickJump = Environment.TickCount; + return "PREJUMP"; + } + else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f) + { + // Start actual jump + if (m_animTickJump == -1) { - //If we were already jumping, continue to jump until we collide + // Already jumping! End the current jump + m_animTickJump = 0; return "JUMP"; + } - } - else if (m_movementAnimation == "PREJUMP" && (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == 0) - { - //If we were in a prejump, and the UP key is no longer being held down - //then we're not going to fly, so we're jumping - return "JUMP"; - - } - else if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) - { - //They're pressing up, so we're either going to fly or jump - return "PREJUMP"; - } - else - { - //If we're moving and not flying and not jumping and not colliding.. - - if (m_movementAnimation == "WALK" || m_movementAnimation == "RUN") - { - //Let's not enter a FALLDOWN state here, since we're probably - //not colliding because we're going down hill. - return m_movementAnimation; - } - //Record the time we enter this state so we know whether to "land" or not - m_animPersistUntil = DateTime.Now.Ticks; - return "FALLDOWN"; - - } + m_animTickJump = -1; + return "JUMP"; } } else { - //We're not moving. - if (PhysicsActor != null && PhysicsActor.IsColliding) + // Not jumping + m_animTickJump = 0; + + if (move.X != 0f || move.Y != 0f) { - //But we are colliding. - if (m_movementAnimation == "FALLDOWN") - { - //We're re-using the m_animPersistUntil value here to see how long we've been falling - if ((DateTime.Now.Ticks - m_animPersistUntil) > TimeSpan.TicksPerSecond) - { - //Make sure we don't change state for a bit - m_animPersistUntil = DateTime.Now.Ticks + TimeSpan.TicksPerSecond; - return "LAND"; - } - else - { - //We haven't been falling very long, we were probably just walking down hill - return "STAND"; - } - } - else if (m_movementAnimation == "JUMP" || m_movementAnimation == "HOVER_DOWN") - { - //Make sure we don't change state for a bit - m_animPersistUntil = DateTime.Now.Ticks + (1 * TimeSpan.TicksPerSecond); - return "SOFT_LAND"; - - } - else if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) - { - return "PREJUMP"; - } - else if (PhysicsActor != null && PhysicsActor.Flying) - { - m_allowFalling = true; - if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) - { - return "HOVER_UP"; - } - else if ((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) - { - return "HOVER_DOWN"; - } - else - { - return "HOVER"; - } - } + // Walking / crouchwalking / running + if (move.Z < 0f) + return "CROUCHWALK"; + else if (m_setAlwaysRun) + return "RUN"; else - { - return "STAND"; - } - + return "WALK"; } else { - //We're not colliding. - if (PhysicsActor != null && PhysicsActor.Flying) - { - - return "HOVER"; - - } - else if ((m_movementAnimation == "JUMP" || m_movementAnimation == "PREJUMP") && (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == 0) - { - - return "JUMP"; - - } + // Not walking + if (move.Z < 0f) + return "CROUCH"; else - { - //Record the time we enter this state so we know whether to "land" or not - m_animPersistUntil = DateTime.Now.Ticks; - return "FALLDOWN"; // this falling animation is invoked too frequently when capsule tilt correction is used - why? - } + return "STAND"; } } + + #endregion Ground Movement + + return m_movementAnimation; } /// @@ -2247,24 +2203,16 @@ namespace OpenSim.Region.Framework.Scenes /// protected void UpdateMovementAnimations() { - string movementAnimation = GetMovementAnimation(); - - if (movementAnimation == "FALLDOWN" && m_allowFalling == false) + m_movementAnimation = GetMovementAnimation(); + + if (m_movementAnimation == "PREJUMP" && !m_usePreJump) { - movementAnimation = m_movementAnimation; - } - else - { - m_movementAnimation = movementAnimation; - } - if (movementAnimation == "PREJUMP" && m_usePreJump == false) - { - //This was the previous behavior before PREJUMP + // This was the previous behavior before PREJUMP TrySetMovementAnimation("JUMP"); } else { - TrySetMovementAnimation(movementAnimation); + TrySetMovementAnimation(m_movementAnimation); } } @@ -2277,7 +2225,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_isChildAgent) { - m_log.Debug("DEBUG: AddNewMovement: child agent, Making root agent!"); + m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); // we have to reset the user's child agent connections. // Likely, here they've lost the eventqueue for other regions so border @@ -2286,7 +2234,7 @@ namespace OpenSim.Region.Framework.Scenes List regions = new List(KnownChildRegionHandles); regions.Remove(m_scene.RegionInfo.RegionHandle); - MakeRootAgent(new Vector3(127, 127, 127), true); + MakeRootAgent(new Vector3(127f, 127f, 127f), true); // Async command if (m_scene.SceneGridService != null) @@ -2298,47 +2246,45 @@ namespace OpenSim.Region.Framework.Scenes System.Threading.Thread.Sleep(500); } - if (m_scene.SceneGridService != null) { m_scene.SceneGridService.EnableNeighbourChildAgents(this, new List()); } - - return; } m_perfMonMS = Environment.TickCount; m_rotation = rotation; - NewForce newVelocity = new NewForce(); Vector3 direc = vec * rotation; direc.Normalize(); direc *= 0.03f * 128f * m_speedModifier; - if (m_physicsActor.Flying) + + PhysicsActor actor = m_physicsActor; + if (actor != null) { - direc *= 4; - //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - //bool colliding = (m_physicsActor.IsColliding==true); - //if (controlland) - // m_log.Info("[AGENT]: landCommand"); - //if (colliding) - // m_log.Info("[AGENT]: colliding"); - //if (m_physicsActor.Flying && colliding && controlland) - //{ - // StopFlying(); - // m_log.Info("[AGENT]: Stop FLying"); - //} - } - else - { - if (!m_physicsActor.Flying && m_physicsActor.IsColliding) + if (actor.Flying) + { + direc *= 4.0f; + //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + //bool colliding = (m_physicsActor.IsColliding==true); + //if (controlland) + // m_log.Info("[AGENT]: landCommand"); + //if (colliding) + // m_log.Info("[AGENT]: colliding"); + //if (m_physicsActor.Flying && colliding && controlland) + //{ + // StopFlying(); + // m_log.Info("[AGENT]: Stop FLying"); + //} + } + else if (!actor.Flying && actor.IsColliding) { if (direc.Z > 2.0f) { - direc.Z *= 3; + direc.Z *= 3.0f; // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. TrySetMovementAnimation("PREJUMP"); @@ -2347,10 +2293,8 @@ namespace OpenSim.Region.Framework.Scenes } } - newVelocity.X = direc.X; - newVelocity.Y = direc.Y; - newVelocity.Z = direc.Z; - m_forcesList.Add(newVelocity); + // TODO: Add the force instead of only setting it to support multiple forces per frame? + m_forceToApply = direc; m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); } @@ -2361,8 +2305,10 @@ namespace OpenSim.Region.Framework.Scenes public override void Update() { - const float VELOCITY_TOLERANCE = 0.01f; - const float POSITION_TOLERANCE = 10.0f; + const float ROTATION_TOLERANCE = 0.01f; + const float VELOCITY_TOLERANCE = 0.001f; + const float POSITION_TOLERANCE = 0.05f; + //const int TIME_MS_TOLERANCE = 3000; SendPrimUpdates(); @@ -2374,17 +2320,25 @@ namespace OpenSim.Region.Framework.Scenes if (m_isChildAgent == false) { + PhysicsActor actor = m_physicsActor; + + // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to + // grab the latest PhysicsActor velocity, whereas m_velocity is often + // storing a requested force instead of an actual traveling velocity + // Throw away duplicate or insignificant updates - if (m_bodyRot != m_lastRotation || - (m_velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE || - (m_pos - m_lastPosition).Length() > POSITION_TOLERANCE) + if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) + //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) { SendTerseUpdateToAllClients(); // Update the "last" values m_lastPosition = m_pos; m_lastRotation = m_bodyRot; - m_lastVelocity = m_velocity; + m_lastVelocity = Velocity; + //m_lastTerseSent = Environment.TickCount; } // followed suggestion from mic bowman. reversed the two lines below. @@ -2410,11 +2364,16 @@ namespace OpenSim.Region.Framework.Scenes { m_perfMonMS = Environment.TickCount; - Vector3 pos = m_pos; - pos.Z -= m_appearance.HipOffset; + PhysicsActor actor = m_physicsActor; + Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; - remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, - pos, m_velocity, Vector3.Zero, m_bodyRot, Vector4.UnitW, m_uuid, null, GetUpdatePriority(remoteClient))); + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); + + remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, + pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); m_scene.StatsReporter.AddAgentUpdates(1); @@ -2510,7 +2469,7 @@ namespace OpenSim.Region.Framework.Scenes return; Vector3 pos = m_pos; - pos.Z -= m_appearance.HipOffset; + pos.Z += m_appearance.HipOffset; remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, pos, m_appearance.Texture.GetBytes(), @@ -2581,7 +2540,7 @@ namespace OpenSim.Region.Framework.Scenes // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); Vector3 pos = m_pos; - pos.Z -= m_appearance.HipOffset; + pos.Z += m_appearance.HipOffset; m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); @@ -2690,7 +2649,7 @@ namespace OpenSim.Region.Framework.Scenes } Vector3 pos = m_pos; - pos.Z -= m_appearance.HipOffset; + pos.Z += m_appearance.HipOffset; m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); @@ -2778,7 +2737,8 @@ namespace OpenSim.Region.Framework.Scenes } // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m - if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) + if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || + Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) { ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); cadu.ActiveGroupID = UUID.Zero.Guid; @@ -2792,7 +2752,7 @@ namespace OpenSim.Region.Framework.Scenes cadu.godlevel = m_godlevel; cadu.GroupAccess = 0; cadu.Position = new sLLVector3(AbsolutePosition); - cadu.regionHandle = m_scene.RegionInfo.RegionHandle; + cadu.regionHandle = m_rootRegionHandle; float multiplier = 1; int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); if (innacurateNeighbors != 0) @@ -2812,11 +2772,9 @@ namespace OpenSim.Region.Framework.Scenes agentpos.CopyFrom(cadu); m_scene.SendOutChildAgentUpdates(agentpos, this); - - m_LastChildAgentUpdatePosition.X = AbsolutePosition.X; - m_LastChildAgentUpdatePosition.Y = AbsolutePosition.Y; - m_LastChildAgentUpdatePosition.Z = AbsolutePosition.Z; + m_lastChildAgentUpdatePosition = AbsolutePosition; + m_lastChildAgentUpdateCamPosition = CameraPosition; } } @@ -2941,9 +2899,9 @@ namespace OpenSim.Region.Framework.Scenes m_inTransit = true; if ((m_physicsActor != null) && m_physicsActor.Flying) - m_AgentControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; - else if ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) - m_AgentControlFlags &= ~(uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; + m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY; + else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) + m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY; } public void NotInTransit() @@ -2959,7 +2917,7 @@ namespace OpenSim.Region.Framework.Scenes public void Reset() { // Put the child agent back at the center - AbsolutePosition = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 70); + AbsolutePosition = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); ResetAnimations(); } @@ -3069,9 +3027,11 @@ namespace OpenSim.Region.Framework.Scenes int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; + Vector3 offset = new Vector3(shiftx, shifty, 0f); + m_DrawDistance = cAgentData.Far; - if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! - m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); + if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! + m_pos = cAgentData.Position + offset; if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) { @@ -3079,8 +3039,7 @@ namespace OpenSim.Region.Framework.Scenes ReprioritizeUpdates(); } - // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region - m_CameraCenter = cAgentData.Center; + m_CameraCenter = cAgentData.Center + offset; m_avHeight = cAgentData.Size.Z; //SetHeight(cAgentData.AVHeight); @@ -3093,16 +3052,16 @@ namespace OpenSim.Region.Framework.Scenes m_sceneViewer.Reset(); //cAgentData.AVHeight; - //cAgentData.regionHandle; + m_rootRegionHandle = cAgentData.RegionHandle; //m_velocity = cAgentData.Velocity; } public void CopyTo(AgentData cAgent) { cAgent.AgentID = UUID; - cAgent.RegionHandle = m_scene.RegionInfo.RegionHandle; + cAgent.RegionHandle = m_rootRegionHandle; - cAgent.Position = m_pos; + cAgent.Position = AbsolutePosition; cAgent.Velocity = m_velocity; cAgent.Center = m_CameraCenter; // Don't copy the size; it is inferred from apearance parameters @@ -3129,7 +3088,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.HeadRotation = m_headrotation; cAgent.BodyRotation = m_bodyRot; - cAgent.ControlFlags = m_AgentControlFlags; + cAgent.ControlFlags = (uint)m_AgentControlFlags; if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) cAgent.GodLevel = (byte)m_godlevel; @@ -3199,7 +3158,8 @@ namespace OpenSim.Region.Framework.Scenes public void CopyFrom(AgentData cAgent) { - m_rootRegionHandle= cAgent.RegionHandle; + m_rootRegionHandle = cAgent.RegionHandle; + m_callbackURI = cAgent.CallbackURI; m_pos = cAgent.Position; @@ -3217,7 +3177,7 @@ namespace OpenSim.Region.Framework.Scenes m_headrotation = cAgent.HeadRotation; m_bodyRot = cAgent.BodyRotation; - m_AgentControlFlags = cAgent.ControlFlags; + m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) m_godlevel = cAgent.GodLevel; @@ -3291,47 +3251,18 @@ namespace OpenSim.Region.Framework.Scenes /// public override void UpdateMovement() { - lock (m_forcesList) + if (m_forceToApply.HasValue) { - if (m_forcesList.Count > 0) - { - //we are only interested in the last velocity added to the list [Although they are called forces, they are actually velocities] - NewForce force = m_forcesList[m_forcesList.Count - 1]; + Vector3 force = m_forceToApply.Value; - m_updateflag = true; - try - { - movementvector.X = force.X; - movementvector.Y = force.Y; - movementvector.Z = force.Z; - Velocity = movementvector; - } - catch (NullReferenceException) - { - // Under extreme load, this returns a NullReference Exception that we can ignore. - // Ignoring this causes no movement to be sent to the physics engine... - // which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter! - } + m_updateflag = true; + movementvector = force; + Velocity = force; - m_forcesList.Clear(); - } + m_forceToApply = null; } } - static ScenePresence() - { - Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture(); - DefaultTexture = textu.GetBytes(); - - } - - public class NewForce - { - public float X; - public float Y; - public float Z; - } - public override void SetText(string text, Vector3 color, double alpha) { throw new Exception("Can't set Text on avatar."); @@ -3342,7 +3273,6 @@ namespace OpenSim.Region.Framework.Scenes /// public void AddToPhysicalScene(bool isFlying) { - PhysicsScene scene = m_scene.PhysicsScene; Vector3 pVec = AbsolutePosition; @@ -3388,15 +3318,48 @@ namespace OpenSim.Region.Framework.Scenes // as of this comment the interval is set in AddToPhysicalScene UpdateMovementAnimations(); + CollisionEventUpdate collisionData = (CollisionEventUpdate)e; + Dictionary coldata = collisionData.m_objCollisionList; + + CollisionPlane = Vector4.UnitW; + + if (coldata.Count != 0) + { + switch (m_movementAnimation) + { + case "STAND": + case "WALK": + case "RUN": + case "CROUCH": + case "CROUCHWALK": + { + ContactPoint lowest; + lowest.SurfaceNormal = Vector3.Zero; + lowest.Position = Vector3.Zero; + lowest.Position.Z = Single.NaN; + + foreach (ContactPoint contact in coldata.Values) + { + if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) + { + lowest = contact; + } + } + + CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); + } + break; + } + } + if (m_invulnerable) return; - CollisionEventUpdate collisionData = (CollisionEventUpdate)e; - Dictionary coldata = collisionData.m_objCollisionList; + float starthealth = Health; uint killerObj = 0; foreach (uint localid in coldata.Keys) { - if (coldata[localid] <= 0.10f || m_invulnerable) + if (coldata[localid].PenetrationDepth <= 0.10f || m_invulnerable) continue; //if (localid == 0) //continue; @@ -3406,9 +3369,9 @@ namespace OpenSim.Region.Framework.Scenes if (part != null && part.ParentGroup.Damage != -1.0f) Health -= part.ParentGroup.Damage; else - Health -= coldata[localid] * 5; + Health -= coldata[localid].PenetrationDepth * 5.0f; - if (Health <= 0) + if (Health <= 0.0f) { if (localid != 0) killerObj = localid; @@ -3471,11 +3434,6 @@ namespace OpenSim.Region.Framework.Scenes public ScenePresence() { - if (DefaultTexture == null) - { - Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture(); - DefaultTexture = textu.GetBytes(); - } m_sendCourseLocationsMethod = SendCoarseLocationsDefault; CreateSceneViewer(); } @@ -3632,19 +3590,10 @@ namespace OpenSim.Region.Framework.Scenes IgnoredControls &= ~(ScriptControlled)controls; if (scriptedcontrols.ContainsKey(Script_item_UUID)) scriptedcontrols.Remove(Script_item_UUID); - } else { - - if (scriptedcontrols.ContainsKey(Script_item_UUID)) - { - scriptedcontrols[Script_item_UUID] = obj; - } - else - { - scriptedcontrols.Add(Script_item_UUID, obj); - } + scriptedcontrols[Script_item_UUID] = obj; } } ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); @@ -3662,12 +3611,14 @@ namespace OpenSim.Region.Framework.Scenes public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) { + ScriptControllers takecontrols; + lock (scriptedcontrols) { - if (scriptedcontrols.ContainsKey(Script_item_UUID)) + if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) { - ScriptControllers takecontrolls = scriptedcontrols[Script_item_UUID]; - ScriptControlled sctc = takecontrolls.eventControls; + ScriptControlled sctc = takecontrols.eventControls; + ControllingClient.SendTakeControls((int)sctc, false, false); ControllingClient.SendTakeControls((int)sctc, true, false); @@ -3678,7 +3629,6 @@ namespace OpenSim.Region.Framework.Scenes IgnoredControls |= scData.ignoreControls; } } - } } @@ -3745,9 +3695,11 @@ namespace OpenSim.Region.Framework.Scenes { lock (scriptedcontrols) { - foreach (UUID scriptUUID in scriptedcontrols.Keys) + foreach (KeyValuePair kvp in scriptedcontrols) { - ScriptControllers scriptControlData = scriptedcontrols[scriptUUID]; + UUID scriptUUID = kvp.Key; + ScriptControllers scriptControlData = kvp.Value; + ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle ScriptControlled localChange = localHeld ^ localLast; // the changed bits @@ -3763,37 +3715,40 @@ namespace OpenSim.Region.Framework.Scenes LastCommands = allflags; } - internal static uint RemoveIgnoredControls(uint flags, ScriptControlled Ignored) + internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) { - if (Ignored == ScriptControlled.CONTROL_ZERO) + if (ignored == ScriptControlled.CONTROL_ZERO) return flags; - if ((Ignored & ScriptControlled.CONTROL_BACK) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); - if ((Ignored & ScriptControlled.CONTROL_FWD) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); - if ((Ignored & ScriptControlled.CONTROL_DOWN) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); - if ((Ignored & ScriptControlled.CONTROL_UP) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); - if ((Ignored & ScriptControlled.CONTROL_LEFT) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); - if ((Ignored & ScriptControlled.CONTROL_RIGHT) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); - if ((Ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); - if ((Ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); - if ((Ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); - if ((Ignored & ScriptControlled.CONTROL_LBUTTON) != 0) - flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); - //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, - //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, - //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, - //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, - //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, - //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, - //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG + + if ((ignored & ScriptControlled.CONTROL_BACK) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); + if ((ignored & ScriptControlled.CONTROL_FWD) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); + if ((ignored & ScriptControlled.CONTROL_DOWN) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); + if ((ignored & ScriptControlled.CONTROL_UP) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); + if ((ignored & ScriptControlled.CONTROL_LEFT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); + if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); + if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); + if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); + if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); + if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); + + //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, + //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, + //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, + //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, + //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, + //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, + //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG + return flags; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs index 19c0fea4c8..f495022177 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs @@ -219,7 +219,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(presence.IsChildAgent, Is.True, "Did not change to child agent after MakeChildAgent"); // Accepts 0 but rejects Constants.RegionSize - Vector3 pos = new Vector3(0,Constants.RegionSize-1,0); + Vector3 pos = new Vector3(0,unchecked(Constants.RegionSize-1),0); presence.MakeRootAgent(pos,true); Assert.That(presence.IsChildAgent, Is.False, "Did not go back to root agent"); Assert.That(presence.AbsolutePosition, Is.EqualTo(pos), "Position is not the same one entered"); @@ -246,7 +246,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests scene2.AddNewClient(testclient); ScenePresence presence = scene.GetScenePresence(agent1); - presence.MakeRootAgent(new Vector3(0,Constants.RegionSize-1,0), true); + presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); ScenePresence presence2 = scene2.GetScenePresence(agent1); diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs index fbe43d6450..2c5093f58d 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs @@ -81,12 +81,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement y.Scale = new Vector3(0.01f,0.01f,0.01f); y.LastOwnerID = UUID.Zero; y.GroupPosition = groupPos; - y.OffsetPosition = new Vector3(0, 0, 0); - y.RotationOffset = new Quaternion(0,0,0,0); - y.Velocity = new Vector3(0, 0, 0); - y.RotationalVelocity = new Vector3(0, 0, 0); - y.AngularVelocity = new Vector3(0, 0, 0); - y.Acceleration = new Vector3(0, 0, 0); + y.OffsetPosition = Vector3.Zero; + y.RotationOffset = Quaternion.Identity; + y.Velocity = Vector3.Zero; + y.AngularVelocity = Vector3.Zero; + y.Acceleration = Vector3.Zero; y.Flags = 0; y.TrimPermissions(); diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs index e185351615..a6afa5ac74 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs @@ -172,8 +172,6 @@ namespace OpenSim.Region.OptionalModules.ContentManagement result |= Diff.ANGULARVELOCITY; if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition)) result |= Diff.OFFSETPOSITION; - if (!AreVectorsEquivalent(first.RotationalVelocity, second.RotationalVelocity)) - result |= Diff.ROTATIONALVELOCITY; if (!AreVectorsEquivalent(first.Scale, second.Scale)) result |= Diff.SCALE; if (!AreVectorsEquivalent(first.Velocity, second.Velocity)) diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 6bfdff2807..f58129d241 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -52,6 +52,20 @@ namespace OpenSim.Region.Physics.Manager , Absolute } + public struct ContactPoint + { + public Vector3 Position; + public Vector3 SurfaceNormal; + public float PenetrationDepth; + + public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth) + { + Position = position; + SurfaceNormal = surfaceNormal; + PenetrationDepth = penetrationDepth; + } + } + public class CollisionEventUpdate : EventArgs { // Raising the event on the object, so don't need to provide location.. further up the tree knows that info. @@ -59,9 +73,9 @@ namespace OpenSim.Region.Physics.Manager public int m_colliderType; public int m_GenericStartEnd; //public uint m_LocalID; - public Dictionary m_objCollisionList = new Dictionary(); + public Dictionary m_objCollisionList = new Dictionary(); - public CollisionEventUpdate(uint localID, int colliderType, int GenericStartEnd, Dictionary objCollisionList) + public CollisionEventUpdate(uint localID, int colliderType, int GenericStartEnd, Dictionary objCollisionList) { m_colliderType = colliderType; m_GenericStartEnd = GenericStartEnd; @@ -72,8 +86,7 @@ namespace OpenSim.Region.Physics.Manager { m_colliderType = (int) ActorTypes.Unknown; m_GenericStartEnd = 1; - // m_objCollisionList = null; - m_objCollisionList = new Dictionary(); + m_objCollisionList = new Dictionary(); } public int collidertype @@ -88,16 +101,16 @@ namespace OpenSim.Region.Physics.Manager set { m_GenericStartEnd = value; } } - public void addCollider(uint localID, float depth) + public void addCollider(uint localID, ContactPoint contact) { if (!m_objCollisionList.ContainsKey(localID)) { - m_objCollisionList.Add(localID, depth); + m_objCollisionList.Add(localID, contact); } else { - if (m_objCollisionList[localID] < depth) - m_objCollisionList[localID] = depth; + if (m_objCollisionList[localID].PenetrationDepth < contact.PenetrationDepth) + m_objCollisionList[localID] = contact; } } } diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index bb0d18e647..6d515e9eca 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -75,6 +75,11 @@ namespace OpenSim.Region.Physics.Manager public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical); + public virtual float TimeDilation + { + get { return 1.0f; } + } + public virtual bool SupportsNINJAJoints { get { return false; } diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index fbe1949994..fded95e4bb 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -284,9 +284,13 @@ namespace OpenSim.Region.Physics.Meshing try { - idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); + OpenMetaverse.Imaging.ManagedImage unusedData; + OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); + unusedData = null; - if (cacheSculptMaps) + //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); + + if (cacheSculptMaps && idata != null) { try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } @@ -299,12 +303,12 @@ namespace OpenSim.Region.Physics.Meshing } catch (IndexOutOfRangeException) { - m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); + m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); return null; } - catch (Exception) + catch (Exception ex) { - m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed!"); + m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); return null; } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index c86bc62b92..1bc4a25351 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1209,11 +1209,11 @@ namespace OpenSim.Region.Physics.OdePlugin m_requestedUpdateFrequency = 0; m_eventsubscription = 0; } - public void AddCollisionEvent(uint CollidedWith, float depth) + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (m_eventsubscription > 0) { - CollisionEventsThisFrame.addCollider(CollidedWith, depth); + CollisionEventsThisFrame.addCollider(CollidedWith, contact); } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 5ff9d32bc1..f4b502a467 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -2958,11 +2958,11 @@ Console.WriteLine(" JointCreateFixed"); m_eventsubscription = 0; } - public void AddCollisionEvent(uint CollidedWith, float depth) + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); - CollisionEventsThisFrame.addCollider(CollidedWith,depth); + CollisionEventsThisFrame.addCollider(CollidedWith, contact); } public void SendCollisions() diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 2f42646c20..a8e006bfa5 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -159,6 +159,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float ODE_STEPSIZE = 0.020f; private float metersInSpace = 29.9f; + private float m_timeDilation = 1.0f; public float gravityx = 0f; public float gravityy = 0f; @@ -177,8 +178,8 @@ namespace OpenSim.Region.Physics.OdePlugin //private int m_returncollisions = 10; private readonly IntPtr contactgroup; - internal IntPtr LandGeom; + internal IntPtr LandGeom; internal IntPtr WaterGeom; private float nmTerrainContactFriction = 255.0f; @@ -250,7 +251,7 @@ namespace OpenSim.Region.Physics.OdePlugin private bool m_NINJA_physics_joints_enabled = false; //private Dictionary jointpart_name_map = new Dictionary(); private readonly Dictionary> joints_connecting_actor = new Dictionary>(); - private d.ContactGeom[] contacts = new d.ContactGeom[80]; + private d.ContactGeom[] contacts; private readonly List requestedJointsToBeCreated = new List(); // lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active private readonly List pendingJoints = new List(); // can lock for longer. accessed only by OdeScene. private readonly List activeJoints = new List(); // can lock for longer. accessed only by OdeScene. @@ -396,6 +397,8 @@ namespace OpenSim.Region.Physics.OdePlugin avStandupTensor = 550000f; } + int contactsPerCollision = 80; + if (m_config != null) { IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; @@ -438,6 +441,8 @@ namespace OpenSim.Region.Physics.OdePlugin avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", true); + contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); + geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); @@ -475,10 +480,11 @@ namespace OpenSim.Region.Physics.OdePlugin m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false); minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); - } } + contacts = new d.ContactGeom[contactsPerCollision]; + staticPrimspace = new IntPtr[(int)(300 / metersInSpace), (int)(300 / metersInSpace)]; // Centeral contact friction and bounce @@ -771,7 +777,9 @@ namespace OpenSim.Region.Physics.OdePlugin lock (contacts) { - count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); + count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); + if (count > contacts.Length) + m_log.Error("[PHYSICS]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); } } catch (SEHException) @@ -799,7 +807,7 @@ namespace OpenSim.Region.Physics.OdePlugin p2 = PANull; } - float max_collision_depth = 0f; + ContactPoint maxDepthContact = new ContactPoint(); if (p1.CollisionScore + count >= float.MaxValue) p1.CollisionScore = 0; p1.CollisionScore += count; @@ -810,9 +818,17 @@ namespace OpenSim.Region.Physics.OdePlugin for (int i = 0; i < count; i++) { + d.ContactGeom curContact = contacts[i]; + if (curContact.depth > maxDepthContact.PenetrationDepth) + { + maxDepthContact = new ContactPoint( + new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), + new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), + curContact.depth + ); + } - max_collision_depth = (contacts[i].depth > max_collision_depth) ? contacts[i].depth : max_collision_depth; //m_log.Warn("[CCOUNT]: " + count); IntPtr joint; // If we're colliding with terrain, use 'TerrainContact' instead of contact. @@ -829,7 +845,7 @@ namespace OpenSim.Region.Physics.OdePlugin p2.CollidingObj = true; break; case (int)ActorTypes.Prim: - if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0) + if (p2.Velocity.LengthSquared() > 0.0f) p2.CollidingObj = true; break; case (int)ActorTypes.Unknown: @@ -845,14 +861,14 @@ namespace OpenSim.Region.Physics.OdePlugin #region InterPenetration Handling - Unintended physics explosions # region disabled code1 - if (contacts[i].depth >= 0.08f) + if (curContact.depth >= 0.08f) { //This is disabled at the moment only because it needs more tweaking //It will eventually be uncommented /* - if (contacts[i].depth >= 1.00f) + if (contact.depth >= 1.00f) { - //m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString()); + //m_log.Debug("[PHYSICS]: " + contact.depth.ToString()); } //If you interpenetrate a prim with an agent @@ -862,37 +878,37 @@ namespace OpenSim.Region.Physics.OdePlugin p2.PhysicsActorType == (int) ActorTypes.Prim)) { - //contacts[i].depth = contacts[i].depth * 4.15f; + //contact.depth = contact.depth * 4.15f; /* if (p2.PhysicsActorType == (int) ActorTypes.Agent) { p2.CollidingObj = true; - contacts[i].depth = 0.003f; + contact.depth = 0.003f; p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); OdeCharacter character = (OdeCharacter) p2; character.SetPidStatus(true); - contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2)); + contact.pos = new d.Vector3(contact.pos.X + (p1.Size.X / 2), contact.pos.Y + (p1.Size.Y / 2), contact.pos.Z + (p1.Size.Z / 2)); } else { - //contacts[i].depth = 0.0000000f; + //contact.depth = 0.0000000f; } if (p1.PhysicsActorType == (int) ActorTypes.Agent) { p1.CollidingObj = true; - contacts[i].depth = 0.003f; + contact.depth = 0.003f; p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); - contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2)); + contact.pos = new d.Vector3(contact.pos.X + (p2.Size.X / 2), contact.pos.Y + (p2.Size.Y / 2), contact.pos.Z + (p2.Size.Z / 2)); OdeCharacter character = (OdeCharacter)p1; character.SetPidStatus(true); } else { - //contacts[i].depth = 0.0000000f; + //contact.depth = 0.0000000f; } @@ -917,7 +933,7 @@ namespace OpenSim.Region.Physics.OdePlugin //AddPhysicsActorTaint(p2); //} - //if (contacts[i].depth >= 0.25f) + //if (contact.depth >= 0.25f) //{ // Don't collide, one or both prim will expld. @@ -935,21 +951,21 @@ namespace OpenSim.Region.Physics.OdePlugin //AddPhysicsActorTaint(p2); //} - //contacts[i].depth = contacts[i].depth / 8f; - //contacts[i].normal = new d.Vector3(0, 0, 1); + //contact.depth = contact.depth / 8f; + //contact.normal = new d.Vector3(0, 0, 1); //} //if (op1.m_disabled || op2.m_disabled) //{ //Manually disabled objects stay disabled - //contacts[i].depth = 0f; + //contact.depth = 0f; //} #endregion } */ #endregion - if (contacts[i].depth >= 1.00f) + if (curContact.depth >= 1.00f) { - //m_log.Info("[P]: " + contacts[i].depth.ToString()); + //m_log.Info("[P]: " + contact.depth.ToString()); if ((p2.PhysicsActorType == (int) ActorTypes.Agent && p1.PhysicsActorType == (int) ActorTypes.Unknown) || (p1.PhysicsActorType == (int) ActorTypes.Agent && @@ -962,12 +978,12 @@ namespace OpenSim.Region.Physics.OdePlugin OdeCharacter character = (OdeCharacter) p2; //p2.CollidingObj = true; - contacts[i].depth = 0.00000003f; + curContact.depth = 0.00000003f; p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f); - contacts[i].pos = - new d.Vector3(contacts[i].pos.X + (p1.Size.X/2), - contacts[i].pos.Y + (p1.Size.Y/2), - contacts[i].pos.Z + (p1.Size.Z/2)); + curContact.pos = + new d.Vector3(curContact.pos.X + (p1.Size.X/2), + curContact.pos.Y + (p1.Size.Y/2), + curContact.pos.Z + (p1.Size.Z/2)); character.SetPidStatus(true); } } @@ -980,12 +996,12 @@ namespace OpenSim.Region.Physics.OdePlugin OdeCharacter character = (OdeCharacter) p1; //p2.CollidingObj = true; - contacts[i].depth = 0.00000003f; + curContact.depth = 0.00000003f; p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f); - contacts[i].pos = - new d.Vector3(contacts[i].pos.X + (p1.Size.X/2), - contacts[i].pos.Y + (p1.Size.Y/2), - contacts[i].pos.Z + (p1.Size.Z/2)); + curContact.pos = + new d.Vector3(curContact.pos.X + (p1.Size.X/2), + curContact.pos.Y + (p1.Size.Y/2), + curContact.pos.Z + (p1.Size.Z/2)); character.SetPidStatus(true); } } @@ -1007,16 +1023,15 @@ namespace OpenSim.Region.Physics.OdePlugin if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) skipThisContact = true; // No collision on volume detect prims - if (!skipThisContact && contacts[i].depth < 0f) + if (!skipThisContact && curContact.depth < 0f) skipThisContact = true; - if (!skipThisContact && checkDupe(contacts[i], p2.PhysicsActorType)) + if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType)) skipThisContact = true; - int maxContactsbeforedeath = 4000; + const int maxContactsbeforedeath = 4000; joint = IntPtr.Zero; - if (!skipThisContact) { // If we're colliding against terrain @@ -1027,8 +1042,8 @@ namespace OpenSim.Region.Physics.OdePlugin (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { // Use the movement terrain contact - AvatarMovementTerrainContact.geom = contacts[i]; - _perloopContact.Add(contacts[i]); + AvatarMovementTerrainContact.geom = curContact; + _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); @@ -1040,8 +1055,8 @@ namespace OpenSim.Region.Physics.OdePlugin if (p2.PhysicsActorType == (int)ActorTypes.Agent) { // Use the non moving terrain contact - TerrainContact.geom = contacts[i]; - _perloopContact.Add(contacts[i]); + TerrainContact.geom = curContact; + _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); @@ -1066,8 +1081,8 @@ namespace OpenSim.Region.Physics.OdePlugin material = ((OdePrim)p2).m_material; //m_log.DebugFormat("Material: {0}", material); - m_materialContacts[material, movintYN].geom = contacts[i]; - _perloopContact.Add(contacts[i]); + m_materialContacts[material, movintYN].geom = curContact; + _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { @@ -1092,8 +1107,8 @@ namespace OpenSim.Region.Physics.OdePlugin if (p2 is OdePrim) material = ((OdePrim)p2).m_material; //m_log.DebugFormat("Material: {0}", material); - m_materialContacts[material, movintYN].geom = contacts[i]; - _perloopContact.Add(contacts[i]); + m_materialContacts[material, movintYN].geom = curContact; + _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { @@ -1121,20 +1136,20 @@ namespace OpenSim.Region.Physics.OdePlugin */ //WaterContact.surface.soft_cfm = 0.0000f; //WaterContact.surface.soft_erp = 0.00000f; - if (contacts[i].depth > 0.1f) + if (curContact.depth > 0.1f) { - contacts[i].depth *= 52; - //contacts[i].normal = new d.Vector3(0, 0, 1); - //contacts[i].pos = new d.Vector3(0, 0, contacts[i].pos.Z - 5f); + curContact.depth *= 52; + //contact.normal = new d.Vector3(0, 0, 1); + //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); } - WaterContact.geom = contacts[i]; - _perloopContact.Add(contacts[i]); + WaterContact.geom = curContact; + _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref WaterContact); m_global_contactcount++; } - //m_log.Info("[PHYSICS]: Prim Water Contact" + contacts[i].depth); + //m_log.Info("[PHYSICS]: Prim Water Contact" + contact.depth); } else { @@ -1145,8 +1160,8 @@ namespace OpenSim.Region.Physics.OdePlugin if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { // Use the Movement prim contact - AvatarMovementprimContact.geom = contacts[i]; - _perloopContact.Add(contacts[i]); + AvatarMovementprimContact.geom = curContact; + _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); @@ -1156,8 +1171,8 @@ namespace OpenSim.Region.Physics.OdePlugin else { // Use the non movement contact - contact.geom = contacts[i]; - _perloopContact.Add(contacts[i]); + contact.geom = curContact; + _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { @@ -1175,8 +1190,8 @@ namespace OpenSim.Region.Physics.OdePlugin material = ((OdePrim)p2).m_material; //m_log.DebugFormat("Material: {0}", material); - m_materialContacts[material, 0].geom = contacts[i]; - _perloopContact.Add(contacts[i]); + m_materialContacts[material, 0].geom = curContact; + _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { @@ -1194,7 +1209,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } - collision_accounting_events(p1, p2, max_collision_depth); + collision_accounting_events(p1, p2, maxDepthContact); if (count > geomContactPointsStartthrottle) { // If there are more then 3 contact points, it's likely @@ -1278,7 +1293,7 @@ namespace OpenSim.Region.Physics.OdePlugin return result; } - private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, float collisiondepth) + private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { // obj1LocalID = 0; //returncollisions = false; @@ -1299,7 +1314,7 @@ namespace OpenSim.Region.Physics.OdePlugin case ActorTypes.Agent: cc1 = (OdeCharacter)p1; obj2LocalID = cc1.m_localID; - cc1.AddCollisionEvent(cc2.m_localID, collisiondepth); + cc1.AddCollisionEvent(cc2.m_localID, contact); //ctype = (int)CollisionCategories.Character; //if (cc1.CollidingObj) @@ -1314,7 +1329,7 @@ namespace OpenSim.Region.Physics.OdePlugin { cp1 = (OdePrim) p1; obj2LocalID = cp1.m_localID; - cp1.AddCollisionEvent(cc2.m_localID, collisiondepth); + cp1.AddCollisionEvent(cc2.m_localID, contact); } //ctype = (int)CollisionCategories.Geom; @@ -1334,7 +1349,7 @@ namespace OpenSim.Region.Physics.OdePlugin break; } - cc2.AddCollisionEvent(obj2LocalID, collisiondepth); + cc2.AddCollisionEvent(obj2LocalID, contact); break; case ActorTypes.Prim: @@ -1350,7 +1365,7 @@ namespace OpenSim.Region.Physics.OdePlugin { cc1 = (OdeCharacter) p1; obj2LocalID = cc1.m_localID; - cc1.AddCollisionEvent(cp2.m_localID, collisiondepth); + cc1.AddCollisionEvent(cp2.m_localID, contact); //ctype = (int)CollisionCategories.Character; //if (cc1.CollidingObj) @@ -1366,7 +1381,7 @@ namespace OpenSim.Region.Physics.OdePlugin { cp1 = (OdePrim) p1; obj2LocalID = cp1.m_localID; - cp1.AddCollisionEvent(cp2.m_localID, collisiondepth); + cp1.AddCollisionEvent(cp2.m_localID, contact); //ctype = (int)CollisionCategories.Geom; //if (cp1.CollidingObj) @@ -1387,7 +1402,7 @@ namespace OpenSim.Region.Physics.OdePlugin break; } - cp2.AddCollisionEvent(obj2LocalID, collisiondepth); + cp2.AddCollisionEvent(obj2LocalID, contact); } break; } @@ -1750,6 +1765,11 @@ namespace OpenSim.Region.Physics.OdePlugin return result; } + public override float TimeDilation + { + get { return m_timeDilation; } + } + public override bool SupportsNINJAJoints { get { return m_NINJA_physics_joints_enabled; } @@ -2657,8 +2677,10 @@ namespace OpenSim.Region.Physics.OdePlugin // Figure out the Frames Per Second we're going at. //(step_time == 0.004f, there's 250 of those per second. Times the step time/step size - - fps = (step_time/ODE_STEPSIZE) * 1000; + + fps = (step_time / ODE_STEPSIZE) * 1000; + // HACK: Using a time dilation of 1.0 to debug rubberbanding issues + //m_timeDilation = Math.Min((step_time / ODE_STEPSIZE) / (0.09375f / ODE_STEPSIZE), 1.0f); step_time = 0.09375f; diff --git a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs index f8af902dc1..e4ca635cfd 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs @@ -34,9 +34,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces { public interface ICompiler { - object PerformScriptCompile(string source, string asset, UUID ownerID); + void PerformScriptCompile(string source, string asset, UUID ownerID, out string assembly, out Dictionary, KeyValuePair> linemap); string[] GetWarnings(); - Dictionary, KeyValuePair> - LineMap(); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 3849558a07..0ea62d77c1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2163,7 +2163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetOmega() { m_host.AddScriptLPS(1); - return new LSL_Vector(m_host.RotationalVelocity.X, m_host.RotationalVelocity.Y, m_host.RotationalVelocity.Z); + return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); } public LSL_Float llGetTimeOfDay() @@ -3159,7 +3159,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llTargetOmega(LSL_Vector axis, double spinrate, double gain) { m_host.AddScriptLPS(1); - m_host.RotationalVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); m_host.ScheduleTerseUpdate(); m_host.SendTerseUpdateToAllClients(); @@ -3817,7 +3816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { case 1: // DATA_ONLINE (0|1) // TODO: implement fetching of this information - if (userProfile.CurrentAgent.AgentOnline) + if (userProfile.CurrentAgent!=null && userProfile.CurrentAgent.AgentOnline) reply = "1"; else reply = "0"; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs index 917ca447c5..121159c0d8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return; //ILease lease = (ILease)RemotingServices.GetLifetimeService(data as MarshalByRefObject); - RemotingServices.GetLifetimeService(data as MarshalByRefObject); + //RemotingServices.GetLifetimeService(data as MarshalByRefObject); // lease.Register(m_sponser); MethodInfo mi = inits[api]; diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index fe2642958c..3080c711b0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -74,7 +74,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private string FilePrefix; private string ScriptEnginesPath = "ScriptEngines"; // mapping between LSL and C# line/column numbers - private Dictionary, KeyValuePair> m_positionMap; private ICodeConverter LSL_Converter; private List m_warnings = new List(); @@ -91,6 +90,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private static UInt64 scriptCompileCounter = 0; // And a counter public IScriptEngine m_scriptEngine; + private Dictionary, KeyValuePair>> m_lineMaps = + new Dictionary, KeyValuePair>>(); + public Compiler(IScriptEngine scriptEngine) { m_scriptEngine = scriptEngine; @@ -172,8 +174,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools else { #if DEBUG -// m_log.Debug("[Compiler]: " + -// "Config OK. Default language \"" + defaultCompileLanguage + "\" specified in \"DefaultCompileLanguage\" is recognized as a valid language."); + // m_log.Debug("[Compiler]: " + + // "Config OK. Default language \"" + defaultCompileLanguage + "\" specified in \"DefaultCompileLanguage\" is recognized as a valid language."); #endif // LANGUAGE IS IN ALLOW-LIST DefaultCompileLanguage = LanguageMapping[defaultCompileLanguage]; @@ -212,12 +214,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools catch (Exception ex) { m_log.Error("[Compiler]: Exception trying to create ScriptEngine directory \"" + Path.Combine(ScriptEnginesPath, - m_scriptEngine.World.RegionInfo.RegionID.ToString())+ "\": " + ex.ToString()); + m_scriptEngine.World.RegionInfo.RegionID.ToString()) + "\": " + ex.ToString()); } } foreach (string file in Directory.GetFiles(Path.Combine(ScriptEnginesPath, - m_scriptEngine.World.RegionInfo.RegionID.ToString()),FilePrefix + "_compiled*")) + m_scriptEngine.World.RegionInfo.RegionID.ToString()), FilePrefix + "_compiled*")) { try { @@ -271,16 +273,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// /// LSL script /// Filename to .dll assembly - public object PerformScriptCompile(string Script, string asset, UUID ownerUUID) + public void PerformScriptCompile(string Script, string asset, UUID ownerUUID, + out string assembly, out Dictionary, KeyValuePair> linemap) { - m_positionMap = null; + linemap = null; m_warnings.Clear(); - - string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( + + assembly = Path.Combine(ScriptEnginesPath, Path.Combine( m_scriptEngine.World.RegionInfo.RegionID.ToString(), FilePrefix + "_compiled_" + asset + ".dll")); -// string OutFile = Path.Combine(ScriptEnginesPath, -// FilePrefix + "_compiled_" + asset + ".dll"); if (!Directory.Exists(ScriptEnginesPath)) { @@ -305,60 +306,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } } + // Don't recompile if we already have it + // Performing 3 file exists tests for every script can still be slow + if (File.Exists(assembly) && File.Exists(assembly + ".text") && File.Exists(assembly + ".map")) + { + // If we have already read this linemap file, then it will be in our dictionary. + // Don't build another copy of the dictionary (saves memory) and certainly + // don't keep reading the same file from disk multiple times. + if (!m_lineMaps.ContainsKey(assembly)) + m_lineMaps[assembly] = ReadMapFile(assembly + ".map"); + linemap = m_lineMaps[assembly]; + return; + } + if (Script == String.Empty) { - if (File.Exists(OutFile)) - return OutFile; - throw new Exception("Cannot find script assembly and no script text present"); } - // Don't recompile if we already have it - // - if (File.Exists(OutFile) && File.Exists(OutFile+".text") && File.Exists(OutFile+".map")) - { - ReadMapFile(OutFile+".map"); - return OutFile; - } - - enumCompileType l = DefaultCompileLanguage; + enumCompileType language = DefaultCompileLanguage; if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture)) - l = enumCompileType.cs; + language = enumCompileType.cs; if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture)) { - l = enumCompileType.vb; + language = enumCompileType.vb; // We need to remove //vb, it won't compile with that Script = Script.Substring(4, Script.Length - 4); } if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture)) - l = enumCompileType.lsl; + language = enumCompileType.lsl; if (Script.StartsWith("//js", true, CultureInfo.InvariantCulture)) - l = enumCompileType.js; + language = enumCompileType.js; if (Script.StartsWith("//yp", true, CultureInfo.InvariantCulture)) - l = enumCompileType.yp; + language = enumCompileType.yp; - if (!AllowedCompilers.ContainsKey(l.ToString())) + if (!AllowedCompilers.ContainsKey(language.ToString())) { // Not allowed to compile to this language! string errtext = String.Empty; - errtext += "The compiler for language \"" + l.ToString() + "\" is not in list of allowed compilers. Script will not be executed!"; + errtext += "The compiler for language \"" + language.ToString() + "\" is not in list of allowed compilers. Script will not be executed!"; throw new Exception(errtext); } - if (m_scriptEngine.World.Permissions.CanCompileScript(ownerUUID, (int)l) == false) { + if (m_scriptEngine.World.Permissions.CanCompileScript(ownerUUID, (int)language) == false) + { // Not allowed to compile to this language! string errtext = String.Empty; errtext += ownerUUID + " is not in list of allowed users for this scripting language. Script will not be executed!"; throw new Exception(errtext); } - + string compileScript = Script; - if (l == enumCompileType.lsl) + if (language == enumCompileType.lsl) { // Its LSL, convert it to C# LSL_Converter = (ICodeConverter)new CSCodeGenerator(); @@ -370,16 +374,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools AddWarning(warning); } - m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; + linemap = ((CSCodeGenerator)LSL_Converter).PositionMap; + // Write the linemap to a file and save it in our dictionary for next time. + m_lineMaps[assembly] = linemap; + WriteMapFile(assembly + ".map", linemap); } - if (l == enumCompileType.yp) + if (language == enumCompileType.yp) { // Its YP, convert it to C# compileScript = YP_Converter.Convert(Script); } - switch (l) + switch (language) { case enumCompileType.cs: case enumCompileType.lsl: @@ -396,7 +403,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools break; } - return CompileFromDotNetText(compileScript, l, asset); + assembly = CompileFromDotNetText(compileScript, language, asset, assembly); + return; } public string[] GetWarnings() @@ -468,22 +476,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// /// CS script /// Filename to .dll assembly - internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset) + internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset, string assembly) { string ext = "." + lang.ToString(); // Output assembly name scriptCompileCounter++; - string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( - m_scriptEngine.World.RegionInfo.RegionID.ToString(), - FilePrefix + "_compiled_" + asset + ".dll")); try { - File.Delete(OutFile); + File.Delete(assembly); } catch (Exception e) // NOTLEGIT - Should be just FileIOException { - throw new Exception("Unable to delete old existing "+ + throw new Exception("Unable to delete old existing " + "script-file before writing new. Compile aborted: " + e.ToString()); } @@ -492,7 +497,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools if (WriteScriptSourceToDebugFile) { string srcFileName = FilePrefix + "_source_" + - Path.GetFileNameWithoutExtension(OutFile) + ext; + Path.GetFileNameWithoutExtension(assembly) + ext; try { File.WriteAllText(Path.Combine(Path.Combine( @@ -502,7 +507,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } catch (Exception ex) //NOTLEGIT - Should be just FileIOException { - m_log.Error("[Compiler]: Exception while "+ + m_log.Error("[Compiler]: Exception while " + "trying to write script source to file \"" + srcFileName + "\": " + ex.ToString()); } @@ -528,7 +533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } parameters.GenerateExecutable = false; - parameters.OutputAssembly = OutFile; + parameters.OutputAssembly = assembly; parameters.IncludeDebugInformation = CompileWithDebugInformation; //parameters.WarningLevel = 1; // Should be 4? parameters.TreatWarningsAsErrors = false; @@ -543,7 +548,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools case enumCompileType.cs: case enumCompileType.lsl: bool complete = false; - bool retried = false; + bool retried = false; do { lock (CScodeProvider) @@ -584,7 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools parameters, Script); break; default: - throw new Exception("Compiler is not able to recongnize "+ + throw new Exception("Compiler is not able to recongnize " + "language type \"" + lang.ToString() + "\""); } @@ -609,7 +614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools if (severity == "Error") { - lslPos = FindErrorPosition(CompErr.Line, CompErr.Column); + lslPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]); string text = CompErr.ErrorText; // Use LSL type names @@ -635,14 +640,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // the compile may not be immediately apparent. Wait a // reasonable amount of time before giving up on it. - if (!File.Exists(OutFile)) + if (!File.Exists(assembly)) { - for (int i=0; i<20 && !File.Exists(OutFile); i++) + for (int i = 0; i < 20 && !File.Exists(assembly); i++) { System.Threading.Thread.Sleep(250); } // One final chance... - if (!File.Exists(OutFile)) + if (!File.Exists(assembly)) { errtext = String.Empty; errtext += "No compile error. But not able to locate compiled file."; @@ -650,15 +655,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } } -// m_log.DebugFormat("[Compiler] Compiled new assembly "+ -// "for {0}", asset); + // m_log.DebugFormat("[Compiler] Compiled new assembly "+ + // "for {0}", asset); // Because windows likes to perform exclusive locks, we simply // write out a textual representation of the file here // // Read the binary file into a buffer // - FileInfo fi = new FileInfo(OutFile); + FileInfo fi = new FileInfo(assembly); if (fi == null) { @@ -671,7 +676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools try { - FileStream fs = File.Open(OutFile, FileMode.Open, FileAccess.Read); + FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read); fs.Read(data, 0, data.Length); fs.Close(); } @@ -690,40 +695,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools Byte[] buf = enc.GetBytes(filetext); - FileStream sfs = File.Create(OutFile+".text"); + FileStream sfs = File.Create(assembly + ".text"); sfs.Write(buf, 0, buf.Length); sfs.Close(); - string posmap = String.Empty; - if (m_positionMap != null) - { - foreach (KeyValuePair, KeyValuePair> kvp in m_positionMap) - { - KeyValuePair k = kvp.Key; - KeyValuePair v = kvp.Value; - posmap += String.Format("{0},{1},{2},{3}\n", - k.Key, k.Value, v.Key, v.Value); - } - } - - buf = enc.GetBytes(posmap); - - FileStream mfs = File.Create(OutFile+".map"); - mfs.Write(buf, 0, buf.Length); - mfs.Close(); - - return OutFile; + return assembly; } - public KeyValuePair FindErrorPosition(int line, int col) + private class kvpSorter : IComparer> { - return FindErrorPosition(line, col, m_positionMap); - } - - private class kvpSorter : IComparer> - { - public int Compare(KeyValuePair a, - KeyValuePair b) + public int Compare(KeyValuePair a, + KeyValuePair b) { return a.Key.CompareTo(b.Key); } @@ -742,8 +724,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools out ret)) return ret; - List> sorted = - new List>(positionMap.Keys); + List> sorted = + new List>(positionMap.Keys); sorted.Sort(new kvpSorter()); @@ -791,32 +773,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools return message; } - public Dictionary, KeyValuePair> LineMap() + + private static void WriteMapFile(string filename, Dictionary, KeyValuePair> linemap) { - if (m_positionMap == null) - return null; - - Dictionary, KeyValuePair> ret = - new Dictionary, KeyValuePair>(); - - foreach (KeyValuePair kvp in m_positionMap.Keys) - ret.Add(kvp, m_positionMap[kvp]); - - return ret; + string mapstring = String.Empty; + foreach (KeyValuePair, KeyValuePair> kvp in linemap) + { + KeyValuePair k = kvp.Key; + KeyValuePair v = kvp.Value; + mapstring += String.Format("{0},{1},{2},{3}\n", k.Key, k.Value, v.Key, v.Value); + } + + System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + Byte[] mapbytes = enc.GetBytes(mapstring); + FileStream mfs = File.Create(filename); + mfs.Write(mapbytes, 0, mapbytes.Length); + mfs.Close(); } - private void ReadMapFile(string filename) + + private static Dictionary, KeyValuePair> ReadMapFile(string filename) { + Dictionary, KeyValuePair> linemap; try { StreamReader r = File.OpenText(filename); + linemap = new Dictionary, KeyValuePair>(); - m_positionMap = new Dictionary, KeyValuePair>(); - string line; while ((line = r.ReadLine()) != null) { - String[] parts = line.Split(new Char[] {','}); + String[] parts = line.Split(new Char[] { ',' }); int kk = System.Convert.ToInt32(parts[0]); int kv = System.Convert.ToInt32(parts[1]); int vk = System.Convert.ToInt32(parts[2]); @@ -825,12 +812,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools KeyValuePair k = new KeyValuePair(kk, kv); KeyValuePair v = new KeyValuePair(vk, vv); - m_positionMap[k] = v; + linemap[k] = v; } } catch { + linemap = new Dictionary, KeyValuePair>(); } + return linemap; } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 2b858ecd9e..549c038fc4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -74,27 +74,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance private string m_PrimName; private string m_ScriptName; private string m_Assembly; - private int m_StartParam = 0; + private int m_StartParam; private string m_CurrentEvent = String.Empty; - private bool m_InSelfDelete = false; + private bool m_InSelfDelete; private int m_MaxScriptQueue; private bool m_SaveState = true; - private bool m_ShuttingDown = false; - private int m_ControlEventsInQueue = 0; - private int m_LastControlLevel = 0; - private bool m_CollisionInQueue = false; + private bool m_ShuttingDown; + private int m_ControlEventsInQueue; + private int m_LastControlLevel; + private bool m_CollisionInQueue; private TaskInventoryItem m_thisScriptTask; // The following is for setting a minimum delay between events - private double m_minEventDelay = 0; - private long m_eventDelayTicks = 0; - private long m_nextEventTimeTicks = 0; + private double m_minEventDelay; + private long m_eventDelayTicks; + private long m_nextEventTimeTicks; private bool m_startOnInit = true; - private UUID m_AttachedAvatar = UUID.Zero; + private UUID m_AttachedAvatar; private StateSource m_stateSource; private bool m_postOnRez; - private bool m_startedFromSavedState = false; - private string m_CurrentState = String.Empty; - private UUID m_RegionID = UUID.Zero; + private bool m_startedFromSavedState; + private UUID m_CurrentStateHash; + private UUID m_RegionID; private Dictionary, KeyValuePair> m_LineMap; @@ -252,16 +252,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { m_Apis[api] = am.CreateApi(api); m_Apis[api].Initialize(engine, part, m_LocalID, itemID); - } + } + + try + { + if (dom != System.AppDomain.CurrentDomain) + m_Script = (IScript)dom.CreateInstanceAndUnwrap( + Path.GetFileNameWithoutExtension(assembly), + "SecondLife.Script"); + else + m_Script = (IScript)Assembly.Load( + Path.GetFileNameWithoutExtension(assembly)).CreateInstance( + "SecondLife.Script"); - try - { - m_Script = (IScript)dom.CreateInstanceAndUnwrap( - Path.GetFileNameWithoutExtension(assembly), - "SecondLife.Script"); //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); - RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); + //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); // lease.Register(this); } catch (Exception) @@ -893,7 +899,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance string xml = ScriptSerializer.Serialize(this); - if (m_CurrentState != xml) + // Compare hash of the state we just just created with the state last written to disk + // If the state is different, update the disk file. + UUID hash = UUID.Parse(Utils.MD5String(xml)); + + if(hash != m_CurrentStateHash) { try { @@ -911,7 +921,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance //{ // throw new Exception("Completed persistence save, but no file was created"); //} - m_CurrentState = xml; + m_CurrentStateHash = hash; } } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 7b19ce3463..b0fce75112 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -50,6 +50,9 @@ using OpenSim.Region.ScriptEngine.Shared.CodeTools; using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Interfaces; +using ScriptCompileQueue = OpenSim.Framework.LocklessQueue; +using Parallel = OpenSim.Framework.Parallel; + namespace OpenSim.Region.ScriptEngine.XEngine { public class XEngine : INonSharedRegionModule, IScriptModule, IScriptEngine @@ -73,9 +76,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine private bool m_InitialStartup = true; private int m_ScriptFailCount; // Number of script fails since compile queue was last empty private string m_ScriptErrorMessage; + private Dictionary m_uniqueScripts = new Dictionary(); + private bool m_AppDomainLoading; -// disable warning: need to keep a reference to XEngine.EventManager -// alive to avoid it being garbage collected + // disable warning: need to keep a reference to XEngine.EventManager + // alive to avoid it being garbage collected #pragma warning disable 414 private EventManager m_EventManager; #pragma warning restore 414 @@ -114,7 +119,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine private Dictionary > m_DomainScripts = new Dictionary >(); - private Queue m_CompileQueue = new Queue(100); + private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); IWorkItemResult m_CurrentCompile = null; public string ScriptEngineName @@ -201,6 +206,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; + m_AppDomainLoading = m_ScriptConfig.GetBoolean("AppDomainLoading", true); m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); @@ -470,6 +476,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (engine != ScriptEngineName) return; + // If we've seen this exact script text before, use that reference instead + if (m_uniqueScripts.ContainsKey(script)) + script = m_uniqueScripts[script]; + else + m_uniqueScripts[script] = script; + Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource}; if (stateSource == (int)StateSource.ScriptedRez) @@ -478,16 +490,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine } else { - lock (m_CompileQueue) - { - m_CompileQueue.Enqueue(parms); + m_CompileQueue.Enqueue(parms); - if (m_CurrentCompile == null) - { - m_CurrentCompile = m_ThreadPool.QueueWorkItem( - new WorkItemCallback(this.DoOnRezScriptQueue), - new Object[0]); - } + if (m_CurrentCompile == null) + { + m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); } } } @@ -498,50 +505,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine { m_InitialStartup = false; System.Threading.Thread.Sleep(15000); - lock (m_CompileQueue) + + if (m_CompileQueue.Count == 0) { - if (m_CompileQueue.Count==0) - // No scripts on region, so won't get triggered later - // by the queue becoming empty so we trigger it here - m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty); + // No scripts on region, so won't get triggered later + // by the queue becoming empty so we trigger it here + m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty); } } - Object o; - lock (m_CompileQueue) + List compiles = new List(); + object[] o; + while (m_CompileQueue.Dequeue(out o)) { - o = m_CompileQueue.Dequeue(); - if (o == null) - { - m_CurrentCompile = null; - return null; - } + compiles.Add(o); } - DoOnRezScript(o); + Parallel.For(0, compiles.Count, delegate(int i) { DoOnRezScript(compiles[i]); }); + + m_CurrentCompile = null; + m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, + m_ScriptErrorMessage); + m_ScriptFailCount = 0; - lock (m_CompileQueue) - { - if (m_CompileQueue.Count > 0) - { - m_CurrentCompile = m_ThreadPool.QueueWorkItem( - new WorkItemCallback(this.DoOnRezScriptQueue), - new Object[0]); - } - else - { - m_CurrentCompile = null; - m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, - m_ScriptErrorMessage); - m_ScriptFailCount = 0; - } - } return null; } - private bool DoOnRezScript(object parm) + private bool DoOnRezScript(object[] parms) { - Object[] p = (Object[])parm; + Object[] p = parms; uint localID = (uint)p[0]; UUID itemID = (UUID)p[1]; string script =(string)p[2]; @@ -590,14 +582,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine { lock (m_AddingAssemblies) { - assembly = (string)m_Compiler.PerformScriptCompile(script, - assetID.ToString(), item.OwnerID); + m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); if (!m_AddingAssemblies.ContainsKey(assembly)) { m_AddingAssemblies[assembly] = 1; } else { m_AddingAssemblies[assembly]++; } - linemap = m_Compiler.LineMap(); } string[] warnings = m_Compiler.GetWarnings(); @@ -696,19 +686,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; Evidence evidence = new Evidence(baseEvidence); - AppDomain sandbox = - AppDomain.CreateDomain( - m_Scene.RegionInfo.RegionID.ToString(), - evidence, appSetup); -/* - PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); - AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); - PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); - PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); - CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); - sandboxPolicy.RootCodeGroup = sandboxCodeGroup; - sandbox.SetAppDomainPolicy(sandboxPolicy); -*/ + AppDomain sandbox; + if (m_AppDomainLoading) + sandbox = AppDomain.CreateDomain( + m_Scene.RegionInfo.RegionID.ToString(), + evidence, appSetup); + else + sandbox = AppDomain.CurrentDomain; + + //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); + //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); + //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); + //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); + //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); + //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; + //sandbox.SetAppDomainPolicy(sandboxPolicy); + m_AppDomains[appDomain] = sandbox; m_AppDomains[appDomain].AssemblyResolve += @@ -905,9 +898,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine AppDomain domain = m_AppDomains[id]; m_AppDomains.Remove(id); - AppDomain.Unload(domain); + if (domain != AppDomain.CurrentDomain) + AppDomain.Unload(domain); domain = null; -// m_log.DebugFormat("[XEngine] Unloaded app domain {0}", id.ToString()); + // m_log.DebugFormat("[XEngine] Unloaded app domain {0}", id.ToString()); } } diff --git a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs index 7926efbc80..c2ad9db027 100644 --- a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs @@ -105,10 +105,14 @@ namespace OpenSim.Services.Connectors catch (Exception e) { m_log.WarnFormat("[AUTHORIZATION CONNECTOR]: Unable to send authorize {0} for region {1} error thrown during comms with remote server. Reason: {2}", userID, regionID, e.Message); - message=""; + message = ""; + return m_ResponseOnFailure; + } + if (response == null) + { + message = "Null response"; return m_ResponseOnFailure; } - m_log.DebugFormat("[AUTHORIZATION CONNECTOR] response from remote service was {0}", response.Message); message = response.Message; diff --git a/OpenSim/TestSuite/PhysicsBot.cs b/OpenSim/TestSuite/PhysicsBot.cs index 9c9c1ea2aa..fac42756a8 100644 --- a/OpenSim/TestSuite/PhysicsBot.cs +++ b/OpenSim/TestSuite/PhysicsBot.cs @@ -130,9 +130,9 @@ namespace OpenSim.TestSuite public void startup() { client.Settings.LOGIN_SERVER = loginURI; - client.Network.OnConnected += new NetworkManager.ConnectedCallback(this.Network_OnConnected); - client.Network.OnSimConnected += new NetworkManager.SimConnectedCallback(this.Network_OnConnected); - client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(this.Network_OnDisconnected); + client.Network.LoginProgress += this.Network_LoginProgress; + client.Network.SimConnected += this.Network_SimConnected; + client.Network.Disconnected += this.Network_OnDisconnected; if (client.Network.Login(firstname, lastname, password, "pCampBot", "Your name")) { @@ -155,19 +155,22 @@ namespace OpenSim.TestSuite } } - public void Network_OnConnected(object sender) + public void Network_LoginProgress(object sender, LoginProgressEventArgs args) { - if (OnConnected != null) + if (args.Status == LoginStatus.Success) { - OnConnected(this, EventType.CONNECTED); + if (OnConnected != null) + { + OnConnected(this, EventType.CONNECTED); + } } } - public void Simulator_Connected(object sender) + public void Network_SimConnected(object sender, SimConnectedEventArgs args) { } - public void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message) + public void Network_OnDisconnected(object sender, DisconnectedEventArgs args) { if (OnDisconnected != null) { diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 38986a28ff..5d4af3144c 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -151,9 +151,9 @@ namespace pCampBot client.Throttle.Texture = 100000; client.Throttle.Wind = 100000; client.Throttle.Total = 400000; - client.Network.OnConnected += new NetworkManager.ConnectedCallback(this.Network_OnConnected); - client.Network.OnSimConnected += new NetworkManager.SimConnectedCallback(this.Network_OnConnected); - client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(this.Network_OnDisconnected); + client.Network.LoginProgress += this.Network_LoginProgress; + client.Network.SimConnected += this.Network_SimConnected; + client.Network.Disconnected += this.Network_OnDisconnected; client.Objects.ObjectUpdate += Objects_NewPrim; //client.Assets.OnAssetReceived += Asset_ReceivedCallback; if (client.Network.Login(firstname, lastname, password, "pCampBot", "Your name")) @@ -349,19 +349,22 @@ namespace pCampBot return clothfolder; } - public void Network_OnConnected(object sender) + public void Network_LoginProgress(object sender, LoginProgressEventArgs args) { - if (OnConnected != null) + if (args.Status == LoginStatus.Success) { - OnConnected(this, EventType.CONNECTED); + if (OnConnected != null) + { + OnConnected(this, EventType.CONNECTED); + } } } - public void Simulator_Connected(object sender) + public void Network_SimConnected(object sender, SimConnectedEventArgs args) { } - public void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message) + public void Network_OnDisconnected(object sender, DisconnectedEventArgs args) { if (OnDisconnected != null) { diff --git a/bin/OpenMetaverse.dll b/bin/OpenMetaverse.dll index 8b07942fcb..edbf3ce2bb 100644 Binary files a/bin/OpenMetaverse.dll and b/bin/OpenMetaverse.dll differ diff --git a/bin/OpenMetaverse.dll.config b/bin/OpenMetaverse.dll.config index 489ee6bcd7..13fdc11c72 100644 --- a/bin/OpenMetaverse.dll.config +++ b/bin/OpenMetaverse.dll.config @@ -1,7 +1,7 @@ - - - + + + diff --git a/bin/OpenMetaverseTypes.dll b/bin/OpenMetaverseTypes.dll index 331d58b722..95d60217bd 100644 Binary files a/bin/OpenMetaverseTypes.dll and b/bin/OpenMetaverseTypes.dll differ diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 927eb7aaac..6606270b00 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -42,7 +42,7 @@ ; SmartThreadPool is reported to work well on Mono/Linux, but ; UnsafeQueueUserWorkItem has been benchmarked with better ; performance on .NET/Windows - ;async_call_method = SmartThreadPool + async_call_method = SmartThreadPool ; There are several operations on large collections (such as ; the current avatar list) that can be run synchronously or @@ -148,7 +148,7 @@ MaximumTimeBeforePersistenceConsidered = 600 ; Should avatars in neighbor sims see objects in this sim? - see_into_this_sim_from_neighbor = True + see_into_this_sim_from_neighbor = true ; ## ; ## PHYSICS @@ -399,13 +399,13 @@ ; These are default values that will be overriden by clients ; ;resend_default = 12500 - ;land_default = 500 - ;wind_default = 500 - ;cloud_default = 50 - ;task_default = 500 - ;texture_default = 500 - ;asset_default = 500 - ;state_default = 500 + ;land_default = 1000 + ;wind_default = 1000 + ;cloud_default = 1000 + ;task_default = 1000 + ;texture_default = 1000 + ;asset_default = 1000 + ;state_default = 1000 ; Per-client maximum burst rates in bytes per second for the various ; throttle categories. These are default values that will be overriden by @@ -577,6 +577,9 @@ ; used to control llMove2Target body_pid_derivative = 35 body_pid_gain = 25 + + ; maximum number of contact points to generate per collision + contacts_per_collision = 80 ; amount of time a geom/body will try to cross a region border before it gets disabled geom_crossing_failures_before_outofbounds = 5 @@ -937,6 +940,13 @@ ; Stack size per thread created ThreadStackSize = 262144 + + ; Set this to true (the default) to load each script into a separate + ; AppDomain. Setting this to false will load all script assemblies into the + ; current AppDomain, which will reduce the per-script overhead at the + ; expense of reduced security and the inability to garbage collect the + ; script assemblies + AppDomainLoading = true ; Rate to poll for asynchronous command replies (ms) ; currently unused diff --git a/bin/libopenjpeg-dotnet-2.1.3.0-dotnet-1-i686.so b/bin/libopenjpeg-dotnet-2.1.3.0-dotnet-1-i686.so index 9571b1d84e..0106b56ff9 100644 Binary files a/bin/libopenjpeg-dotnet-2.1.3.0-dotnet-1-i686.so and b/bin/libopenjpeg-dotnet-2.1.3.0-dotnet-1-i686.so differ diff --git a/bin/libopenjpeg-dotnet-2.1.3.0-dotnet-1-x86_64.so b/bin/libopenjpeg-dotnet-2.1.3.0-dotnet-1-x86_64.so index c2627e85be..be11bb477d 100644 Binary files a/bin/libopenjpeg-dotnet-2.1.3.0-dotnet-1-x86_64.so and b/bin/libopenjpeg-dotnet-2.1.3.0-dotnet-1-x86_64.so differ diff --git a/bin/openjpeg-dotnet-x86_64.dll b/bin/openjpeg-dotnet-x86_64.dll new file mode 100644 index 0000000000..97729fffa0 Binary files /dev/null and b/bin/openjpeg-dotnet-x86_64.dll differ diff --git a/bin/openjpeg-dotnet.dll b/bin/openjpeg-dotnet.dll index 1cede1c499..64b2557ece 100644 Binary files a/bin/openjpeg-dotnet.dll and b/bin/openjpeg-dotnet.dll differ