diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index d10fba4173..ecde8ac92a 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -288,24 +288,15 @@ namespace OpenSim.Data.MySQL public bool Store(RegionData data) { - if (data.Data.ContainsKey("uuid")) - data.Data.Remove("uuid"); - if (data.Data.ContainsKey("ScopeID")) - data.Data.Remove("ScopeID"); - if (data.Data.ContainsKey("regionName")) - data.Data.Remove("regionName"); - if (data.Data.ContainsKey("posX")) - data.Data.Remove("posX"); - if (data.Data.ContainsKey("posY")) - data.Data.Remove("posY"); - if (data.Data.ContainsKey("sizeX")) - data.Data.Remove("sizeX"); - if (data.Data.ContainsKey("sizeY")) - data.Data.Remove("sizeY"); - if (data.Data.ContainsKey("locX")) - data.Data.Remove("locX"); - if (data.Data.ContainsKey("locY")) - data.Data.Remove("locY"); + data.Data.Remove("uuid"); + data.Data.Remove("ScopeID"); + data.Data.Remove("regionName"); + data.Data.Remove("posX"); + data.Data.Remove("posY"); + data.Data.Remove("sizeX"); + data.Data.Remove("sizeY"); + data.Data.Remove("locX"); + data.Data.Remove("locY"); if (data.RegionName.Length > 128) data.RegionName = data.RegionName.Substring(0, 128); diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 8b24cdfa52..5e1cb72870 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -170,7 +170,8 @@ namespace OpenSim.Data.MySQL "AttachedPosY, AttachedPosZ, " + "PhysicsShapeType, Density, GravityModifier, " + "Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " + - "RotationAxisLocks, sopanims, sitactrange, pseudocrc" + + "RotationAxisLocks, sopanims, sitactrange, pseudocrc, " + + "lnkstBinData" + ") values (" + "?UUID, " + "?CreationDate, ?Name, ?Text, " + "?Description, ?SitName, ?TouchName, " + @@ -204,8 +205,9 @@ namespace OpenSim.Data.MySQL "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " + "?AttachedPosY, ?AttachedPosZ, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " + - "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," + - "?RotationAxisLocks, ?sopanims, ?sitactrange, ?pseudocrc)"; + "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs, " + + "?RotationAxisLocks, ?sopanims, ?sitactrange, ?pseudocrc, " + + "?lnkstBinData)"; FillPrimCommand(cmd, prim, obj.UUID, regionUUID); @@ -344,12 +346,27 @@ namespace OpenSim.Data.MySQL else prim.Shape = BuildShape(reader); - UUID parentID = DBGuid.FromDB(reader["SceneGroupID"].ToString()); - if (parentID != prim.UUID) - prim.ParentUUID = parentID; - prims[prim.UUID] = prim; + UUID parentID = DBGuid.FromDB(reader["SceneGroupID"].ToString()); + if (parentID.NotEqual(prim.UUID)) + prim.ParentUUID = parentID; + else + { + //create linkset and extract its data stored on root + SceneObjectGroup newSog = new SceneObjectGroup(prim); + if(objects.TryAdd(prim.UUID, newSog)) + { + if(reader["lnkstBinData"] is not DBNull) + { + byte[] data = (byte[])reader["lnkstBinData"]; + newSog.LinksetData = LinksetData.FromBin(data); + } + } + else + m_log.Warn($"[REGION DB]: duplicated SOG with root prim \"{prim.Name}\" {prim.UUID} in region {regionID}"); + } + ++count; if (count % ROWS_PER_QUERY == 0) m_log.Debug("[REGION DB]: Loaded " + count + " prims..."); @@ -362,24 +379,12 @@ namespace OpenSim.Data.MySQL #endregion Prim Loading - #region SceneObjectGroup Creation - - // Create all of the SOGs from the root prims first - foreach (SceneObjectPart prim in prims.Values) - { - if (prim.ParentUUID.IsZero()) - { - objects[prim.UUID] = new SceneObjectGroup(prim); - } - } - // Add all of the children objects to the SOGs foreach (SceneObjectPart prim in prims.Values) { - SceneObjectGroup sog; - if (prim.UUID != prim.ParentUUID) + if (prim.UUID.NotEqual(prim.ParentUUID)) { - if (objects.TryGetValue(prim.ParentUUID, out sog)) + if (objects.TryGetValue(prim.ParentUUID, out SceneObjectGroup sog)) { int originalLinkNum = prim.LinkNum; @@ -392,16 +397,13 @@ namespace OpenSim.Data.MySQL } else { - m_log.WarnFormat( - "[REGION DB]: Database contains an orphan child prim {0} {1} in region {2} pointing to missing parent {3}. This prim will not be loaded.", - prim.Name, prim.UUID, regionID, prim.ParentUUID); + m_log.Warn( + $"[REGION DB]: orphan child prim {prim.Name} {prim.UUID} in region {regionID} with missing parent {prim.ParentUUID}. Prim not loaded."); } } } - #endregion SceneObjectGroup Creation - - m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); + m_log.Debug($"[REGION DB]: Loaded {objects.Count} objects using {prims.Count} prims"); #region Prim Inventory Loading @@ -1188,7 +1190,7 @@ namespace OpenSim.Data.MySQL int pseudocrc = (int)row["pseudocrc"]; if(pseudocrc != 0) prim.PseudoCRC = pseudocrc; - + return prim; } @@ -1609,6 +1611,11 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("sitactrange", prim.SitActiveRange); cmd.Parameters.AddWithValue("pseudocrc", prim.PseudoCRC); + + if(prim.IsRoot && prim.ParentGroup.LinksetData is not null) + cmd.Parameters.AddWithValue("lnkstBinData", prim.ParentGroup.LinksetData.ToBin()); + else + cmd.Parameters.AddWithValue("lnkstBinData", null); } /// diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index 30407aff1d..142916551c 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -553,3 +553,8 @@ COMMIT; :VERSION 64 #----- material overrides ALTER TABLE `primshapes` ADD COLUMN `MatOvrd` blob default NULL; COMMIT; + +:VERSION 65 #----- add linkset data binary storage column +BEGIN; +ALTER TABLE `prims` ADD COLUMN `lnkstBinData` blob default NULL; +COMMIT; \ No newline at end of file diff --git a/OpenSim/Data/Null/NullAuthenticationData.cs b/OpenSim/Data/Null/NullAuthenticationData.cs index 620deb9786..72a0b95cc4 100644 --- a/OpenSim/Data/Null/NullAuthenticationData.cs +++ b/OpenSim/Data/Null/NullAuthenticationData.cs @@ -45,10 +45,7 @@ namespace OpenSim.Data.Null public AuthenticationData Get(UUID principalID) { - if (m_DataByUUID.ContainsKey(principalID)) - return m_DataByUUID[principalID]; - - return null; + return m_DataByUUID.TryGetValue(principalID, out AuthenticationData ad) ? ad :null; } public bool Store(AuthenticationData data) @@ -71,10 +68,7 @@ namespace OpenSim.Data.Null public bool CheckToken(UUID principalID, string token, int lifetime) { - if (m_Tokens.ContainsKey(principalID)) - return m_Tokens[principalID] == token; - - return false; + return m_Tokens.TryGetValue(principalID, out string tk) ? tk == token : false; } } } \ No newline at end of file diff --git a/OpenSim/Data/Null/NullPresenceData.cs b/OpenSim/Data/Null/NullPresenceData.cs index 8c442c9c5b..ec031fab69 100644 --- a/OpenSim/Data/Null/NullPresenceData.cs +++ b/OpenSim/Data/Null/NullPresenceData.cs @@ -71,12 +71,7 @@ namespace OpenSim.Data.Null if (Instance != this) return Instance.Get(sessionID); - if (m_presenceData.ContainsKey(sessionID)) - { - return m_presenceData[sessionID]; - } - - return null; + return m_presenceData.TryGetValue(sessionID, out PresenceData pd) ? pd : null; } public void LogoutRegionAgents(UUID regionID) @@ -101,9 +96,9 @@ namespace OpenSim.Data.Null if (Instance != this) return Instance.ReportAgent(sessionID, regionID); - if (m_presenceData.ContainsKey(sessionID)) + if (m_presenceData.TryGetValue(sessionID, out PresenceData pd)) { - m_presenceData[sessionID].RegionID = regionID; + pd.RegionID = regionID; return true; } @@ -134,13 +129,12 @@ namespace OpenSim.Data.Null } else if (field == "SessionID") { - UUID session = UUID.Zero; - if (!UUID.TryParse(data, out session)) + if (!UUID.TryParse(data, out UUID session)) return presences.ToArray(); - if (m_presenceData.ContainsKey(session)) + if (m_presenceData.TryGetValue(session, out PresenceData pd)) { - presences.Add(m_presenceData[session]); + presences.Add(pd); return presences.ToArray(); } } @@ -158,7 +152,7 @@ namespace OpenSim.Data.Null { foreach (PresenceData p in m_presenceData.Values) { - if (p.Data.ContainsKey(field) && p.Data[field] == data) + if (p.Data.TryGetValue(field, out string spd) && spd == data) presences.Add(p); } return presences.ToArray(); diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs index 60d16e48d6..77ae12ff62 100644 --- a/OpenSim/Data/Null/NullRegionData.cs +++ b/OpenSim/Data/Null/NullRegionData.cs @@ -176,11 +176,8 @@ namespace OpenSim.Data.Null lock (m_regionData) { - if (m_regionData.ContainsKey(regionID)) - return m_regionData[regionID]; + return m_regionData.TryGetValue(regionID, out RegionData rd) ? rd : null; } - - return null; } public List Get(int startX, int startY, int endX, int endY, UUID scopeID) @@ -226,13 +223,13 @@ namespace OpenSim.Data.Null lock (m_regionData) { - if (!m_regionData.ContainsKey(regionID)) - return false; - - m_regionData[regionID].Data[item] = value; + if(m_regionData.TryGetValue(regionID, out RegionData rd)) + { + rd.Data[item] = value; + return true; + } + return false; } - - return true; } public bool Delete(UUID regionID) @@ -240,17 +237,12 @@ namespace OpenSim.Data.Null if (m_useStaticInstance && Instance != this) return Instance.Delete(regionID); -// m_log.DebugFormat("[NULL REGION DATA]: Deleting region {0}", regionID); + //m_log.DebugFormat("[NULL REGION DATA]: Deleting region {0}", regionID); lock (m_regionData) { - if (!m_regionData.ContainsKey(regionID)) - return false; - - m_regionData.Remove(regionID); + return m_regionData.Remove(regionID); } - - return true; } public List GetDefaultRegions(UUID scopeID) diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index 97e4b797f1..0744f4ae47 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs @@ -83,11 +83,7 @@ namespace OpenSim.Data.Null public string LoadRegionEnvironmentSettings(UUID regionUUID) { lock (EnvironmentSettings) - { - if (EnvironmentSettings.ContainsKey(regionUUID)) - return EnvironmentSettings[regionUUID]; - } - return string.Empty; + return EnvironmentSettings.TryGetValue(regionUUID, out string es) ? es : string.Empty; } public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) @@ -102,8 +98,7 @@ namespace OpenSim.Data.Null { lock (EnvironmentSettings) { - if (EnvironmentSettings.ContainsKey(regionUUID)) - EnvironmentSettings.Remove(regionUUID); + EnvironmentSettings.Remove(regionUUID); } } #endregion @@ -136,16 +131,12 @@ namespace OpenSim.Data.Null Dictionary m_bakedterrains = new Dictionary(); public void StoreTerrain(TerrainData ter, UUID regionID) { - if (m_terrains.ContainsKey(regionID)) - m_terrains.Remove(regionID); - m_terrains.Add(regionID, ter); + m_terrains[regionID] = ter; } public void StoreBakedTerrain(TerrainData ter, UUID regionID) { - if (m_bakedterrains.ContainsKey(regionID)) - m_bakedterrains.Remove(regionID); - m_bakedterrains.Add(regionID, ter); + m_bakedterrains[regionID] = ter; } // Legacy. Just don't do this. @@ -159,29 +150,17 @@ namespace OpenSim.Data.Null // Returns 'null' if region not found public double[,] LoadTerrain(UUID regionID) { - if (m_terrains.ContainsKey(regionID)) - { - return m_terrains[regionID].GetDoubles(); - } - return null; + return m_terrains.TryGetValue(regionID, out TerrainData terrData) ? terrData.GetDoubles() : null; } public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { - if (m_terrains.ContainsKey(regionID)) - { - return m_terrains[regionID]; - } - return null; + return m_terrains.TryGetValue(regionID, out TerrainData terrData) ? terrData : null; } public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { - if (m_bakedterrains.ContainsKey(regionID)) - { - return m_bakedterrains[regionID]; - } - return null; + return m_bakedterrains.TryGetValue(regionID, out TerrainData terrData) ? terrData : null; } public void RemoveLandObject(UUID globalID) diff --git a/OpenSim/Data/Null/NullUserAccountData.cs b/OpenSim/Data/Null/NullUserAccountData.cs index b4428da8bb..7c0f12765d 100644 --- a/OpenSim/Data/Null/NullUserAccountData.cs +++ b/OpenSim/Data/Null/NullUserAccountData.cs @@ -47,9 +47,6 @@ namespace OpenSim.Data.Null public NullUserAccountData(string connectionString, string realm) { -// m_log.DebugFormat( -// "[NULL USER ACCOUNT DATA]: Initializing new NullUserAccountData with connectionString [{0}], realm [{1}]", -// connectionString, realm); } /// @@ -62,51 +59,38 @@ namespace OpenSim.Data.Null /// public UserAccountData[] Get(string[] fields, string[] values) { -// if (m_log.IsDebugEnabled) -// { -// m_log.DebugFormat( -// "[NULL USER ACCOUNT DATA]: Called Get with fields [{0}], values [{1}]", -// string.Join(", ", fields), string.Join(", ", values)); -// } + //if (m_log.IsDebugEnabled) + //{ + // m_log.DebugFormat( + // "[NULL USER ACCOUNT DATA]: Called Get with fields [{0}], values [{1}]", + // string.Join(", ", fields), string.Join(", ", values)); + //} - UserAccountData[] userAccounts = new UserAccountData[0]; - - List fieldsLst = new List(fields); - if (fieldsLst.Contains("PrincipalID")) + try { - int i = fieldsLst.IndexOf("PrincipalID"); - UUID id = UUID.Zero; - if (UUID.TryParse(values[i], out id)) - if (m_DataByUUID.ContainsKey(id)) - userAccounts = new UserAccountData[] { m_DataByUUID[id] }; - } - else if (fieldsLst.Contains("FirstName") && fieldsLst.Contains("LastName")) - { - int findex = fieldsLst.IndexOf("FirstName"); - int lindex = fieldsLst.IndexOf("LastName"); - if (m_DataByName.ContainsKey(values[findex] + " " + values[lindex])) + UserAccountData uad; + int i = Array.FindIndex(fields, (fn) => fn == "PrincipalID"); + if (i >= 0) { - userAccounts = new UserAccountData[] { m_DataByName[values[findex] + " " + values[lindex]] }; + if (UUID.TryParse(values[i], out UUID id) && m_DataByUUID.TryGetValue(id, out uad)) + return new UserAccountData[] { uad }; } - } - else if (fieldsLst.Contains("Email")) - { - int i = fieldsLst.IndexOf("Email"); - if (m_DataByEmail.ContainsKey(values[i])) - userAccounts = new UserAccountData[] { m_DataByEmail[values[i]] }; - } -// if (m_log.IsDebugEnabled) -// { -// StringBuilder sb = new StringBuilder(); -// foreach (UserAccountData uad in userAccounts) -// sb.AppendFormat("({0} {1} {2}) ", uad.FirstName, uad.LastName, uad.PrincipalID); -// -// m_log.DebugFormat( -// "[NULL USER ACCOUNT DATA]: Returning {0} user accounts out of {1}: [{2}]", userAccounts.Length, m_DataByName.Count, sb); -// } + i = Array.FindIndex(fields, (fn) => fn == "FirstName"); + if (i >= 0) + { + int lindex = Array.FindIndex(fields, i + 1, (fn) => fn == "LastName"); + if(lindex >= 0 && m_DataByName.TryGetValue(values[i] + " " + values[lindex], out uad)) + return new UserAccountData[] { uad }; + } - return userAccounts; + i = Array.FindIndex(fields, (fn) => fn == "Email"); + if (i >= 0 && m_DataByEmail.TryGetValue(values[i], out uad)) + return new UserAccountData[] { uad }; + } + catch { } + + return Array.Empty(); } public bool Store(UserAccountData data) @@ -120,18 +104,18 @@ namespace OpenSim.Data.Null m_DataByUUID[data.PrincipalID] = data; m_DataByName[data.FirstName + " " + data.LastName] = data; - if (data.Data.ContainsKey("Email") && data.Data["Email"] != null && data.Data["Email"] != string.Empty) - m_DataByEmail[data.Data["Email"]] = data; + if (data.Data.TryGetValue("Email", out string semail) && !string.IsNullOrEmpty(semail)) + m_DataByEmail[semail] = data; -// m_log.DebugFormat("m_DataByUUID count is {0}, m_DataByName count is {1}", m_DataByUUID.Count, m_DataByName.Count); + // m_log.DebugFormat("m_DataByUUID count is {0}, m_DataByName count is {1}", m_DataByUUID.Count, m_DataByName.Count); return true; } public UserAccountData[] GetUsers(UUID scopeID, string query) { -// m_log.DebugFormat( -// "[NULL USER ACCOUNT DATA]: Called GetUsers with scope [{0}], query [{1}]", scopeID, query); + //m_log.DebugFormat( + // "[NULL USER ACCOUNT DATA]: Called GetUsers with scope [{0}], query [{1}]", scopeID, query); string[] words = query.Split(); @@ -177,15 +161,12 @@ namespace OpenSim.Data.Null // Only delete by PrincipalID if (field.Equals("PrincipalID")) { - UUID uuid = UUID.Zero; - if (UUID.TryParse(val, out uuid) && m_DataByUUID.ContainsKey(uuid)) + if (UUID.TryParse(val, out UUID uuid) && m_DataByUUID.TryGetValue(uuid, out UserAccountData account)) { - UserAccountData account = m_DataByUUID[uuid]; m_DataByUUID.Remove(uuid); - if (m_DataByName.ContainsKey(account.FirstName + " " + account.LastName)) - m_DataByName.Remove(account.FirstName + " " + account.LastName); - if (account.Data.ContainsKey("Email") && account.Data["Email"] != string.Empty && m_DataByEmail.ContainsKey(account.Data["Email"])) - m_DataByEmail.Remove(account.Data["Email"]); + m_DataByName.Remove(account.FirstName + " " + account.LastName); + if (account.Data.TryGetValue("Email", out string semail) && !string.IsNullOrEmpty(semail)) + m_DataByEmail.Remove(semail); return true; } diff --git a/OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs b/OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs index 625c0108a6..17aae4388e 100644 --- a/OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLAuthenticationData.cs @@ -107,10 +107,8 @@ namespace OpenSim.Data.PGSQL public bool Store(AuthenticationData data) { - if (data.Data.ContainsKey("UUID")) - data.Data.Remove("UUID"); - if (data.Data.ContainsKey("uuid")) - data.Data.Remove("uuid"); + data.Data.Remove("UUID"); + data.Data.Remove("uuid"); /* Dictionary oAuth = new Dictionary(); diff --git a/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs b/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs index a89183b0d4..2d8aef0bae 100644 --- a/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs +++ b/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs @@ -183,12 +183,12 @@ namespace OpenSim.Data.PGSQL using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand()) { - if ( m_FieldTypes.ContainsKey(field) ) - cmd.Parameters.Add(m_database.CreateParameter(field, key, m_FieldTypes[field])); + if ( m_FieldTypes.TryGetValue(field, out string ftype) ) + cmd.Parameters.Add(m_database.CreateParameter(field, key, ftype)); else cmd.Parameters.Add(m_database.CreateParameter(field, key)); - string query = String.Format("SELECT * FROM {0} WHERE \"{1}\" = :{1}", m_Realm, field, field); + string query = $"SELECT * FROM {m_Realm} WHERE \"{field}\" = :{field}"; cmd.Connection = conn; cmd.CommandText = query; @@ -243,8 +243,8 @@ namespace OpenSim.Data.PGSQL for (int i = 0; i < fields.Length; i++) { - if ( m_FieldTypes.ContainsKey(fields[i]) ) - cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], m_FieldTypes[fields[i]])); + if ( m_FieldTypes.TryGetValue(fields[i], out string ftype) ) + cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], ftype)); else cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i])); @@ -398,8 +398,9 @@ namespace OpenSim.Data.PGSQL { constraints.Add(new KeyValuePair(fi.Name, fi.GetValue(row).ToString() )); } - if (m_FieldTypes.ContainsKey(fi.Name)) - cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row), m_FieldTypes[fi.Name])); + + if (m_FieldTypes.TryGetValue(fi.Name, out string ftype)) + cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row), ftype)); else cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row))); } @@ -418,8 +419,8 @@ namespace OpenSim.Data.PGSQL names.Add(kvp.Key); values.Add(":" + kvp.Key); - if (m_FieldTypes.ContainsKey(kvp.Key)) - cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value, m_FieldTypes[kvp.Key])); + if (m_FieldTypes.TryGetValue(kvp.Key, out string ftype)) + cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value, ftype)); else cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value)); } @@ -493,8 +494,8 @@ namespace OpenSim.Data.PGSQL { for (int i = 0; i < fields.Length; i++) { - if (m_FieldTypes.ContainsKey(fields[i])) - cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], m_FieldTypes[fields[i]])); + if (m_FieldTypes.TryGetValue(fields[i], out string ftype)) + cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], ftype)); else cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i])); diff --git a/OpenSim/Data/PGSQL/PGSQLRegionData.cs b/OpenSim/Data/PGSQL/PGSQLRegionData.cs index 5577226c66..96a86f1cb6 100644 --- a/OpenSim/Data/PGSQL/PGSQLRegionData.cs +++ b/OpenSim/Data/PGSQL/PGSQLRegionData.cs @@ -293,24 +293,15 @@ namespace OpenSim.Data.PGSQL public bool Store(RegionData data) { - if (data.Data.ContainsKey("uuid")) - data.Data.Remove("uuid"); - if (data.Data.ContainsKey("ScopeID")) - data.Data.Remove("ScopeID"); - if (data.Data.ContainsKey("regionName")) - data.Data.Remove("regionName"); - if (data.Data.ContainsKey("posX")) - data.Data.Remove("posX"); - if (data.Data.ContainsKey("posY")) - data.Data.Remove("posY"); - if (data.Data.ContainsKey("sizeX")) - data.Data.Remove("sizeX"); - if (data.Data.ContainsKey("sizeY")) - data.Data.Remove("sizeY"); - if (data.Data.ContainsKey("locX")) - data.Data.Remove("locX"); - if (data.Data.ContainsKey("locY")) - data.Data.Remove("locY"); + data.Data.Remove("uuid"); + data.Data.Remove("ScopeID"); + data.Data.Remove("regionName"); + data.Data.Remove("posX"); + data.Data.Remove("posY"); + data.Data.Remove("sizeX"); + data.Data.Remove("sizeY"); + data.Data.Remove("locX"); + data.Data.Remove("locY"); string[] fields = new List(data.Data.Keys).ToArray(); diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index 590b2c7dfa..1578a991c2 100755 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -158,6 +158,11 @@ namespace OpenSim.Data.PGSQL } grp = new SceneObjectGroup(sceneObjectPart); + if (reader["lnkstBinData"] is not DBNull) + { + byte[] data = (byte[])reader["lnkstBinData"]; + grp.LinksetData = LinksetData.FromBin(data); + } } else { @@ -191,12 +196,12 @@ namespace OpenSim.Data.PGSQL { while (itemReader.Read()) { - if (!(itemReader["primID"] is DBNull)) + if (itemReader["primID"] is not DBNull) { - UUID primID = new UUID(itemReader["primID"].ToString()); - if (prims.ContainsKey(primID)) + if(UUID.TryParse(itemReader["primID"].ToString(), out UUID primID) && + prims.TryGetValue(primID, out SceneObjectPart sop)) { - primsWithInventory.Add(prims[primID]); + primsWithInventory.Add(sop); } } } @@ -347,7 +352,7 @@ namespace OpenSim.Data.PGSQL ""ClickAction"" = :ClickAction, ""Material"" = :Material, ""CollisionSound"" = :CollisionSound, ""CollisionSoundVolume"" = :CollisionSoundVolume, ""PassTouches"" = :PassTouches, ""LinkNumber"" = :LinkNumber, ""MediaURL"" = :MediaURL, ""DynAttrs"" = :DynAttrs, ""Vehicle"" = :Vehicle, ""PhysInertia"" = :PhysInertia, ""standtargetx"" =:standtargetx, ""standtargety"" =:standtargety, ""standtargetz"" =:standtargetz, - ""sitactrange"" =:sitactrange, ""pseudocrc"" = :pseudocrc, ""sopanims"" = :sopanims + ""sitactrange"" =:sitactrange, ""pseudocrc"" = :pseudocrc, ""sopanims"" = :sopanims, ""lnkstBinData"" = :lnkstBinData WHERE ""UUID"" = :UUID ; @@ -363,7 +368,7 @@ namespace OpenSim.Data.PGSQL ""ForceMouselook"", ""ScriptAccessPin"", ""AllowedDrop"", ""DieAtEdge"", ""SalePrice"", ""SaleType"", ""ColorR"", ""ColorG"", ""ColorB"", ""ColorA"", ""ParticleSystem"", ""ClickAction"", ""Material"", ""CollisionSound"", ""CollisionSoundVolume"", ""PassTouches"", ""LinkNumber"", ""MediaURL"", ""DynAttrs"", ""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"", ""PassCollisions"", ""RotationAxisLocks"", ""RezzerID"" , ""Vehicle"", ""PhysInertia"", - ""standtargetx"", ""standtargety"", ""standtargetz"", ""sitactrange"", ""pseudocrc"",""sopanims"" + ""standtargetx"", ""standtargety"", ""standtargetz"", ""sitactrange"", ""pseudocrc"",""sopanims"",""lnkstBinData"" ) Select :UUID, :CreationDate, :Name, :Text, :Description, :SitName, :TouchName, :ObjectFlags, :OwnerMask, :NextOwnerMask, :GroupMask, :EveryoneMask, :BaseMask, :PositionX, :PositionY, :PositionZ, :GroupPositionX, :GroupPositionY, :GroupPositionZ, :VelocityX, @@ -1871,6 +1876,11 @@ namespace OpenSim.Data.PGSQL else parameters.Add(_Database.CreateParameter("sopanims", null)); + if (prim.IsRoot && prim.ParentGroup.LinksetData is not null) + parameters.Add(_Database.CreateParameter("lnkstBinData", prim.ParentGroup.LinksetData.ToBin())); + else + parameters.Add(_Database.CreateParameter("lnkstBinData", null)); + return parameters.ToArray(); } diff --git a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations index 1def32ef1f..6d4793ed56 100644 --- a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations @@ -1261,3 +1261,8 @@ BEGIN; ALTER TABLE `prims` ADD COLUMN `sopanims` bytea NULL; ALTER TABLE `primshapes` ADD COLUMN `MatOvrd` bytea NULL; COMMIT; + +:VERSION 53 #----- add linkset data binary storage column +BEGIN; +ALTER TABLE `prims` ADD COLUMN `lnkstBinData` bytea NULL; +COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index e81b33a001..8e7085532e 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -405,3 +405,8 @@ BEGIN; ALTER TABLE `prims` ADD COLUMN `sopanims` blob default NULL; ALTER TABLE `primshapes` ADD COLUMN `MatOvrd` blob default NULL; COMMIT; + +:VERSION 41 #----- add linkset data binary storage column +BEGIN; +ALTER TABLE `prims` ADD COLUMN `lnkstBinData` blob default NULL; +COMMIT; diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs index 13f2f03e29..d9e79b8128 100644 --- a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs +++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs @@ -129,8 +129,7 @@ namespace OpenSim.Data.SQLite public bool Store(AuthenticationData data) { - if (data.Data.ContainsKey("UUID")) - data.Data.Remove("UUID"); + data.Data.Remove("UUID"); string[] fields = new List(data.Data.Keys).ToArray(); string[] values = new string[data.Data.Count]; diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index ed33fd4a30..211805b77b 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -657,6 +657,12 @@ namespace OpenSim.Data.SQLite SceneObjectGroup group = new SceneObjectGroup(prim); + if (primRow["lnkstBinData"] is not DBNull) + { + byte[] data = (byte[])primRow["lnkstBinData"]; + group.LinksetData = LinksetData.FromBin(data); + } + createdObjects.Add(group.UUID, group); retvals.Add(group); LoadItems(prim); @@ -1244,6 +1250,8 @@ namespace OpenSim.Data.SQLite createCol(prims, "pseudocrc", typeof(int)); createCol(prims, "sopanims", typeof(byte[])); + createCol(prims, "lnkstBinData", typeof(byte[])); + // Add in contraints prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] }; @@ -2196,6 +2204,10 @@ namespace OpenSim.Data.SQLite row["pseudocrc"] = prim.PseudoCRC; row["sopanims"] = prim.SerializeAnimations(); + if (prim.IsRoot && prim.ParentGroup.LinksetData is not null) + row["lnkstBinData"] = prim.ParentGroup.LinksetData.ToBin(); + else + row["lnkstBinData"] = null; } /// diff --git a/OpenSim/Framework/AnimationSet.cs b/OpenSim/Framework/AnimationSet.cs index ea2ba5d346..0cc39d8fed 100644 --- a/OpenSim/Framework/AnimationSet.cs +++ b/OpenSim/Framework/AnimationSet.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Text; using OpenMetaverse; namespace OpenSim.Framework @@ -127,20 +128,19 @@ namespace OpenSim.Framework Console.WriteLine("--------------------"); } + public static readonly byte[] ZeroCountBytesReply = osUTF8.GetASCIIBytes("version 1\ncount 0\n"); public Byte[] ToBytes() { // If there was an error parsing the input, we give back an // empty set rather than the original data. - if (m_parseError) - { - string dummy = "version 1\ncount 0\n"; - return System.Text.Encoding.ASCII.GetBytes(dummy); - } + if (m_parseError || m_animations.Count == 0) + return ZeroCountBytesReply; - string assetData = String.Format("version 1\ncount {0}\n", m_animations.Count); + osUTF8 sb = OSUTF8Cached.Acquire(); + sb.AppendASCII("$version 1\ncount {m_animations.Count}\n"); foreach (KeyValuePair> kvp in m_animations) - assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key); - return System.Text.Encoding.ASCII.GetBytes(assetData); + sb.AppendASCII($"{kvp.Key} {kvp.Value.Value} {kvp.Value.Key}\n"); + return OSUTF8Cached.GetArrayAndRelease(sb); } /* public bool Validate(AnimationSetValidator val) diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 848f47cb3c..b9d8daf99a 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -32,6 +32,7 @@ using OpenMetaverse; using OpenMetaverse.StructuredData; using log4net; using System.Text; +using System.Runtime.InteropServices; namespace OpenSim.Framework { @@ -541,16 +542,20 @@ namespace OpenSim.Framework lock (m_attachments) { - if (!m_attachments.ContainsKey(attach.AttachPoint)) - m_attachments[attach.AttachPoint] = new List(); + ref List atlst = ref CollectionsMarshal.GetValueRefOrAddDefault(m_attachments, attach.AttachPoint, out bool ex); + if(!ex) + { + atlst = new List() { attach }; + return; + } - foreach (AvatarAttachment prev in m_attachments[attach.AttachPoint]) + foreach (AvatarAttachment prev in atlst) { if (prev.ItemID.Equals(attach.ItemID)) return; } - m_attachments[attach.AttachPoint].Add(attach); + atlst.Add(attach); } } @@ -562,8 +567,7 @@ namespace OpenSim.Framework lock (m_attachments) { - m_attachments[attach.AttachPoint] = new List(); - m_attachments[attach.AttachPoint].Add(attach); + m_attachments[attach.AttachPoint] = new List() { attach }; } } diff --git a/OpenSim/Framework/AvatarWearable.cs b/OpenSim/Framework/AvatarWearable.cs index 6435307b98..32de787ed7 100644 --- a/OpenSim/Framework/AvatarWearable.cs +++ b/OpenSim/Framework/AvatarWearable.cs @@ -185,11 +185,8 @@ namespace OpenSim.Framework public void RemoveItem(UUID itemID) { - if (m_items.ContainsKey(itemID)) - { - m_ids.Remove(itemID); - m_items.Remove(itemID); - } + m_ids.Remove(itemID); + m_items.Remove(itemID); } public void RemoveAsset(UUID assetID) @@ -225,9 +222,7 @@ namespace OpenSim.Framework public UUID GetAsset(UUID itemID) { - if (!m_items.ContainsKey(itemID)) - return UUID.Zero; - return m_items[itemID]; + return m_items.TryGetValue(itemID, out UUID id) ? id : UUID.Zero; } public static AvatarWearable[] DefaultWearables diff --git a/OpenSim/Framework/BasicDOSProtector.cs b/OpenSim/Framework/BasicDOSProtector.cs index d1026088b2..c80bee5622 100644 --- a/OpenSim/Framework/BasicDOSProtector.cs +++ b/OpenSim/Framework/BasicDOSProtector.cs @@ -103,7 +103,7 @@ namespace OpenSim.Framework public bool IsBlocked(string key) { bool ret = false; - _blockLockSlim.EnterReadLock(); + _blockLockSlim.EnterReadLock(); ret = _tempBlocked.ContainsKey(key); _blockLockSlim.ExitReadLock(); return ret; @@ -140,11 +140,8 @@ namespace OpenSim.Framework if (_options.MaxConcurrentSessions > 0) { - int sessionscount = 0; - _sessionLockSlim.EnterReadLock(); - if (_sessions.ContainsKey(key)) - sessionscount = _sessions[key]; + _sessions.TryGetValue(key, out int sessionscount); _sessionLockSlim.ExitReadLock(); if (sessionscount > _options.MaxConcurrentSessions) diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs index 3ca85d7d1a..a5bf3a6aa0 100644 --- a/OpenSim/Framework/Cache.cs +++ b/OpenSim/Framework/Cache.cs @@ -344,26 +344,20 @@ namespace OpenSim.Framework // protected virtual CacheItemBase GetItem(string index) { - CacheItemBase item = null; lock (m_Index) { - if (m_Lookup.ContainsKey(index)) - item = m_Lookup[index]; - - if (item == null) + if(m_Lookup.TryGetValue(index, out CacheItemBase item)) { + item.hits++; + item.lastUsed = DateTime.UtcNow; Expire(true); - return null; + return item; } - item.hits++; - item.lastUsed = DateTime.UtcNow; - Expire(true); + return null; } - - return item; } // Get an item from cache. Do not try to fetch from source if not @@ -566,12 +560,9 @@ namespace OpenSim.Framework { lock (m_Index) { - if (!m_Lookup.ContainsKey(uuid)) - return; - - CacheItemBase item = m_Lookup[uuid]; + if (m_Lookup.TryGetValue(uuid, out CacheItemBase item)) + m_Index.Remove(item); m_Lookup.Remove(uuid); - m_Index.Remove(item); } } diff --git a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs index 0d2c5caf80..809a705d4e 100644 --- a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs @@ -46,39 +46,36 @@ namespace OpenSim.Framework.Monitoring public virtual string Report() { StringBuilder sb = new StringBuilder(Environment.NewLine); - sb.Append("MEMORY STATISTICS"); - sb.Append(Environment.NewLine); sb.AppendFormat( - "Heap allocated to OpenSim : {0} MB\n", - Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)); - - sb.AppendFormat( - "Heap allocation rate (last/avg): {0}/{1}MB/s\n", + "Heap allocated: {0}MB \t allocation rate (last/avg): {1}/{2}MB/s\n", + Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0), Math.Round((MemoryWatchdog.LastHeapAllocationRate * 1000) / 1048576.0, 3), Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1048576.0, 3)); + GCMemoryInfo gcmem = GC.GetGCMemoryInfo(); + sb.AppendFormat( + "GCTotalCommited: {0}MB \t GCTotalAvaiable {1}MB \t GCHMthreshold {2}MB\n", + Math.Round(gcmem.TotalCommittedBytes / 1024.0 / 1024.0), + Math.Round(gcmem.TotalAvailableMemoryBytes / 1024.0 / 1024.0), + Math.Round(gcmem.HighMemoryLoadThresholdBytes / 1024.0 / 1024.0)); + try { using (Process myprocess = Process.GetCurrentProcess()) { sb.AppendFormat( - "Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", + "Process memory: Physical {0}MB \t Paged {1}MB\n", Math.Round(myprocess.WorkingSet64 / 1024.0 / 1024.0), - Math.Round(myprocess.PagedMemorySize64 / 1024.0 / 1024.0), - Math.Round(myprocess.VirtualMemorySize64 / 1024.0 / 1024.0)); + Math.Round(myprocess.PagedMemorySize64 / 1024.0 / 1024.0)); sb.AppendFormat( - "Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", + "Peak process memory: Physical {0}MB \t Paged {1}MB \t\n", Math.Round(myprocess.PeakWorkingSet64 / 1024.0 / 1024.0), - Math.Round(myprocess.PeakPagedMemorySize64 / 1024.0 / 1024.0), - Math.Round(myprocess.PeakVirtualMemorySize64 / 1024.0 / 1024.0)); + Math.Round(myprocess.PeakPagedMemorySize64 / 1024.0 / 1024.0)); sb.AppendFormat("\nTotal process Threads {0}\n", myprocess.Threads.Count); } } catch { } -// else -// sb.Append("Process reported as Exited \n"); - return sb.ToString(); } diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 0e5626b164..447303e7dc 100755 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; @@ -188,6 +189,43 @@ namespace OpenSim.Framework.Monitoring { foreach (string report in GetAllStatsReports()) con.Output(report); + con.Output(MemoryReport()); + } + + private static string MemoryReport() + { + StringBuilder sb = new StringBuilder(Environment.NewLine); + sb.AppendFormat( + "Heap allocated: {0}MB \t allocation rate (last/avg): {1}/{2}MB/s\n", + Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0), + Math.Round((MemoryWatchdog.LastHeapAllocationRate * 1000) / 1048576.0, 3), + Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1048576.0, 3)); + + GCMemoryInfo gcmem = GC.GetGCMemoryInfo(); + sb.AppendFormat( + "GCTotalCommited: {0}MB \t GCTotalAvaiable {1}MB \t GCHMthreshold {2}MB\n", + Math.Round(gcmem.TotalCommittedBytes / 1024.0 / 1024.0), + Math.Round(gcmem.TotalAvailableMemoryBytes / 1024.0 / 1024.0), + Math.Round(gcmem.HighMemoryLoadThresholdBytes / 1024.0 / 1024.0)); + + try + { + using (Process myprocess = Process.GetCurrentProcess()) + { + sb.AppendFormat( + "Process memory: Physical {0}MB \t Paged {1}MB\n", + Math.Round(myprocess.WorkingSet64 / 1024.0 / 1024.0), + Math.Round(myprocess.PagedMemorySize64 / 1024.0 / 1024.0)); + sb.AppendFormat( + "Peak process memory: Physical {0}MB \t Paged {1}MB \t\n", + Math.Round(myprocess.PeakWorkingSet64 / 1024.0 / 1024.0), + Math.Round(myprocess.PeakPagedMemorySize64 / 1024.0 / 1024.0)); + sb.AppendFormat("\nTotal process Threads {0}\n", myprocess.Threads.Count); + } + } + catch + { } + return sb.ToString(); } private static List GetCategoryStatsReports( diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs index 7b9b92214b..cb0e5993e5 100644 --- a/OpenSim/Framework/Monitoring/Watchdog.cs +++ b/OpenSim/Framework/Monitoring/Watchdog.cs @@ -269,18 +269,13 @@ namespace OpenSim.Framework.Monitoring { lock (m_threads) { - if (m_threads.ContainsKey(threadID)) + if(RemoveThread(threadID)) { //ThreadWatchdogInfo twi = m_threads[threadID]; //twi.Thread.Abort(); - RemoveThread(threadID); - return true; } - else - { - return false; - } + return false; } } @@ -325,11 +320,8 @@ namespace OpenSim.Framework.Monitoring { lock (m_threads) { - if (m_threads.ContainsKey(Thread.CurrentThread.ManagedThreadId)) - return m_threads[Thread.CurrentThread.ManagedThreadId]; + return m_threads.TryGetValue(Thread.CurrentThread.ManagedThreadId, out ThreadWatchdogInfo twi) ? twi : null; } - - return null; } /// diff --git a/OpenSim/Framework/PluginLoader.cs b/OpenSim/Framework/PluginLoader.cs index 07929a9764..054e78a928 100644 --- a/OpenSim/Framework/PluginLoader.cs +++ b/OpenSim/Framework/PluginLoader.cs @@ -159,17 +159,13 @@ namespace OpenSim.Framework { log.Info("[PLUGINS]: Loading extension point " + ext); - if (constraints.ContainsKey(ext)) + if (constraints.TryGetValue(ext , out IPluginConstraint cons)) { - IPluginConstraint cons = constraints[ext]; if (cons.Apply(ext)) log.Error("[PLUGINS]: " + ext + " failed constraint: " + cons.Message); } - IPluginFilter filter = null; - - if (filters.ContainsKey(ext)) - filter = filters[ext]; + filters.TryGetValue(ext, out IPluginFilter filter); List loadedPlugins = new List(); foreach (PluginExtensionNode node in AddinManager.GetExtensionNodes(ext)) diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 3ffa4bc5a3..79ff06aba2 100755 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -1139,12 +1139,13 @@ namespace OpenSim.Framework UInt32.TryParse(args["region_yloc"].AsString(), out locy); RegionLocY = locy; } - if (args.ContainsKey("region_size_x")) - RegionSizeX = (uint)args["region_size_x"].AsInteger(); - if (args.ContainsKey("region_size_y")) - RegionSizeY = (uint)args["region_size_y"].AsInteger(); - if (args.ContainsKey("region_size_z")) - RegionSizeZ = (uint)args["region_size_z"].AsInteger(); + OSD osdtmp; + if (args.TryGetValue("region_size_x", out osdtmp)) + RegionSizeX = (uint)osdtmp.AsInteger(); + if (args.TryGetValue("region_size_y", out osdtmp)) + RegionSizeY = (uint)osdtmp.AsInteger(); + if (args.TryGetValue("region_size_z", out osdtmp)) + RegionSizeZ = (uint)osdtmp.AsInteger(); IPAddress ip_addr = null; if (args["internal_ep_address"] != null) diff --git a/OpenSim/Framework/RegionURI.cs b/OpenSim/Framework/RegionURI.cs index 56bb04416f..d3e0a8dbc1 100644 --- a/OpenSim/Framework/RegionURI.cs +++ b/OpenSim/Framework/RegionURI.cs @@ -32,17 +32,18 @@ namespace OpenSim.Framework { public class RegionURI { - private static byte[] schemaSep = osUTF8.GetASCIIBytes("://"); - private static byte[] altschemaSep = osUTF8.GetASCIIBytes("|!!"); - private static byte[] nameSep = osUTF8.GetASCIIBytes(":/ "); - private static byte[] altnameSep = osUTF8.GetASCIIBytes(":/ +|"); - private static byte[] escapePref = osUTF8.GetASCIIBytes("+%"); - private static byte[] altPortSepPref = osUTF8.GetASCIIBytes(":|"); + private static readonly byte[] schemaSep = osUTF8.GetASCIIBytes("://"); + private static readonly byte[] altschemaSep = osUTF8.GetASCIIBytes("|!!"); + private static readonly byte[] nameSep = osUTF8.GetASCIIBytes(":/ "); + private static readonly byte[] altnameSep = osUTF8.GetASCIIBytes(":/ +|"); + private static readonly byte[] escapePref = osUTF8.GetASCIIBytes("+%"); + private static readonly byte[] altPortSepPref = osUTF8.GetASCIIBytes(":|"); + private static readonly byte[] forbidonname = osUTF8.GetASCIIBytes(".,:;\\/"); public enum URIFlags : int { None = 0, - Valid = 1 << 0, + //Valid = 1 << 0, HasHost = 1 << 1, HasResolvedHost = 1 << 2, HasUserName = 1 << 3, @@ -70,7 +71,7 @@ namespace OpenSim.Framework { originalURI = _originalURI; Parse(_originalURI); - if (!HasHost) + if (!HasHost && HasRegionName) Flags |= URIFlags.IsLocalGrid; } @@ -81,7 +82,10 @@ namespace OpenSim.Framework if(!HasHost) { - Flags |= URIFlags.IsLocalGrid; + if(!HasRegionName) + Flags = URIFlags.None; + else + Flags |= URIFlags.IsLocalGrid; return; } if(gi == null) @@ -290,6 +294,12 @@ namespace OpenSim.Framework if (tmpSlice.Length <= 0) return; + if(tmpSlice.IndexOfAny(forbidonname) > 0) + { + Flags = URIFlags.None; + return; + } + RegionName = tmpSlice.ToString(); Flags |= URIFlags.HasRegionName; diff --git a/OpenSim/Framework/RegistryCore.cs b/OpenSim/Framework/RegistryCore.cs index 98d595a847..d5e13bbde7 100644 --- a/OpenSim/Framework/RegistryCore.cs +++ b/OpenSim/Framework/RegistryCore.cs @@ -53,9 +53,9 @@ namespace OpenSim.Framework public bool TryGet(out T iface) { - if (m_moduleInterfaces.ContainsKey(typeof(T))) + if (m_moduleInterfaces.TryGetValue(typeof(T), out object o)) { - iface = (T)m_moduleInterfaces[typeof(T)]; + iface = (T)o; return true; } iface = default(T); diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs index 5270885b62..5d5682fefc 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs @@ -695,8 +695,8 @@ namespace OSHttpServer m_stream.EndWrite(res); ContextTimeoutManager.ContextLeaveActiveSend(); - didleave = true; m_currentResponse.CheckSendNextAsyncContinue(); + didleave = true; } catch (Exception e) { diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpResponse.cs index e20d8ab7ba..e1c5f6eac9 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpResponse.cs @@ -25,7 +25,7 @@ namespace OSHttpServer public int RawBufferLen { get; set; } public double RequestTS { get; private set; } - internal byte[] m_headerBytes = null; + internal osUTF8 m_headerBytes = null; /// /// Initializes a new instance of the class. @@ -228,55 +228,65 @@ namespace OSHttpServer m_headers[name] = value; } - public byte[] GetHeaders() + public void GetHeaders() { HeadersSent = true; - var sb = osStringBuilderCache.Acquire(); + osUTF8 osu = OSUTF8Cached.Acquire(8 * 1024); - if(string.IsNullOrWhiteSpace(m_httpVersion)) - sb.AppendFormat("HTTP/1.1 {0} {1}\r\n", (int)Status, - string.IsNullOrEmpty(Reason) ? Status.ToString() : Reason); + if (string.IsNullOrWhiteSpace(m_httpVersion)) + { + osu.AppendASCII($"HTTP/1.1 {(int)Status} "); + if (string.IsNullOrEmpty(Reason)) + osu.AppendASCII($"{Status}"); + else + osu.Append($"{Reason}"); + osu.AppendASCII("\r\n"); + } else - sb.AppendFormat("{0} {1} {2}\r\n", m_httpVersion, (int)Status, - string.IsNullOrEmpty(Reason) ? Status.ToString() : Reason); + { + osu.AppendASCII($"{m_httpVersion} {(int)Status} "); + if (string.IsNullOrEmpty(Reason)) + osu.AppendASCII($"{Status}"); + else + osu.Append($"{Reason}"); + osu.AppendASCII("\r\n"); + } - sb.AppendFormat("Date: {0}\r\n", DateTime.Now.ToString("r")); + osu.AppendASCII($"Date: {DateTime.Now:r}\r\n"); - long len = 0; - if(m_body is not null) - len = m_body.Length; - if (RawBuffer is not null && RawBufferLen > 0) + long len = m_body is null ? 0 : m_body.Length; + if (RawBuffer is not null) len += RawBufferLen; - sb.AppendFormat("Content-Length: {0}\r\n", len); + osu.AppendASCII($"Content-Length: {len}\r\n"); if (m_headers["Content-Type"] is null) - sb.AppendFormat("Content-Type: {0}\r\n", m_contentType ?? DefaultContentType); + osu.AppendASCII($"Content-Type: {m_contentType ?? DefaultContentType}\r\n"); - switch(Status) + switch (Status) { case HttpStatusCode.OK: case HttpStatusCode.PartialContent: case HttpStatusCode.Accepted: case HttpStatusCode.Continue: case HttpStatusCode.Found: - { - int keepaliveS = m_context.TimeoutKeepAlive / 1000; - if (Connection == ConnectionType.KeepAlive && keepaliveS > 0 && m_context.MaxRequests > 0) { - sb.AppendFormat("Keep-Alive:timeout={0}, max={1}\r\n", keepaliveS, m_context.MaxRequests); - sb.Append("Connection: Keep-Alive\r\n"); + int keepaliveS = m_context.TimeoutKeepAlive / 1000; + if (Connection == ConnectionType.KeepAlive && keepaliveS > 0 && m_context.MaxRequests > 0) + { + osu.AppendASCII($"Keep-Alive:timeout={keepaliveS}, max={m_context.MaxRequests}\r\n"); + osu.AppendASCII("Connection: Keep-Alive\r\n"); + } + else + { + osu.AppendASCII("Connection: close\r\n"); + Connection = ConnectionType.Close; + } + break; } - else - { - sb.Append("Connection: close\r\n"); - Connection = ConnectionType.Close; - } - break; - } default: - sb.Append("Connection: close\r\n"); + osu.AppendASCII("Connection: close\r\n"); Connection = ConnectionType.Close; break; } @@ -284,7 +294,7 @@ namespace OSHttpServer for (int i = 0; i < m_headers.Count; ++i) { string headerName = m_headers.AllKeys[i]; - switch(headerName) + switch (headerName) { case "Connection": case "Content-Length": @@ -294,21 +304,27 @@ namespace OSHttpServer continue; } string[] values = m_headers.GetValues(i); - if (values is null) continue; - foreach (string value in values) - sb.AppendFormat("{0}: {1}\r\n", headerName, value); + if (values is not null) + { + foreach (string value in values) + { + osu.AppendASCII($"{headerName}: "); + osu.Append($"{value}"); + osu.AppendASCII("\r\n"); + } + } } - sb.Append("Server: OSWebServer\r\n"); + osu.AppendASCII("Server: OSWebServer\r\n"); foreach (ResponseCookie cookie in Cookies) - sb.AppendFormat("Set-Cookie: {0}\r\n", cookie); + osu.Append($"Set-Cookie: {cookie}\r\n"); - sb.Append("\r\n"); + osu.AppendASCII("\r\n"); m_headers.Clear(); - return Encoding.GetBytes(osStringBuilderCache.GetStringAndRelease(sb)); + m_headerBytes = osu; } public void Send() @@ -345,24 +361,20 @@ namespace OSHttpServer RawBufferLen = RawBuffer.Length - RawBufferStart; } - m_headerBytes = GetHeaders(); + if (RawBufferLen == 0) + RawBuffer = null; + + GetHeaders(); if (RawBuffer is not null && RawBufferLen > 0) { int tlen = m_headerBytes.Length + RawBufferLen; if(tlen < 8 * 1024) { - byte[] tmp = new byte[tlen]; - Buffer.BlockCopy(m_headerBytes, 0, tmp, 0, m_headerBytes.Length); - Buffer.BlockCopy(RawBuffer, RawBufferStart, tmp, m_headerBytes.Length, RawBufferLen); - m_headerBytes = null; - RawBuffer = tmp; - RawBufferStart = 0; - RawBufferLen = tlen; - } - - if (RawBufferLen == 0) + m_headerBytes.Append(RawBuffer, RawBufferStart, RawBufferLen); RawBuffer = null; + RawBufferLen = 0; + } } if (m_body is not null && m_body.Length == 0) @@ -384,11 +396,14 @@ namespace OSHttpServer { if (m_headerBytes is not null) { - byte[] b = m_headerBytes; - m_headerBytes = null; - - if (!m_context.SendAsyncStart(b, 0, b.Length)) + if (!m_context.SendAsyncStart(m_headerBytes.GetArray(), 0, m_headerBytes.Length)) { + if(m_headerBytes is not null) + { + OSUTF8Cached.Release(m_headerBytes); + m_headerBytes = null; + } + if (m_body is not null) { m_body.Dispose(); @@ -499,7 +514,13 @@ namespace OSHttpServer public void CheckSendNextAsyncContinue() { - if(m_headerBytes is null && RawBuffer is null && m_body is null) + if (m_headerBytes is not null) + { + OSUTF8Cached.Release(m_headerBytes); + m_headerBytes = null; + } + + if (m_headerBytes is null && RawBuffer is null && m_body is null) { Sent = true; m_context.EndSendResponse(requestID, Connection); @@ -512,6 +533,12 @@ namespace OSHttpServer public void Clear() { + if(m_headerBytes is not null) + { + OSUTF8Cached.Release(m_headerBytes); + m_headerBytes = null; + } + if(m_body is not null && m_body.CanRead) { m_body.Dispose(); diff --git a/OpenSim/Region/Application/runtimeconfig.template.json b/OpenSim/Region/Application/runtimeconfig.template.json index 5ca3137acd..772fa6058f 100644 --- a/OpenSim/Region/Application/runtimeconfig.template.json +++ b/OpenSim/Region/Application/runtimeconfig.template.json @@ -1,7 +1,11 @@ { - "configProperties": { - "System.GC.Server": false, - "System.Drawing.EnableUnixSupport": true, - "System.Globalization.UseNls": true, + "configProperties": { + "System.GC.Server": false, + "System.GC.HighMemoryPercent": 50, + "System.Drawing.EnableUnixSupport": true, + "System.Globalization.UseNls": true, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true, + "System.Runtime.TieredCompilation.QuickJit": false } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index d2524f1af2..a35c18cd4a 100755 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; +using System.Runtime.InteropServices; namespace OpenSim.Region.CoreModules.Asset @@ -352,10 +353,11 @@ namespace OpenSim.Region.CoreModules.Asset { lock(weakAssetReferencesLock) { - if(weakAssetReferences.TryGetValue(key , out WeakReference aref)) + ref WeakReference aref = ref CollectionsMarshal.GetValueRefOrAddDefault(weakAssetReferences, key, out bool ex); + if(ex) aref.Target = asset; else - weakAssetReferences[key] = new WeakReference(asset); + aref = new WeakReference(asset); } } @@ -463,20 +465,18 @@ namespace OpenSim.Region.CoreModules.Asset private AssetBase GetFromWeakReference(string id) { - AssetBase asset = null; - lock(weakAssetReferencesLock) { if (weakAssetReferences.TryGetValue(id, out WeakReference aref)) { - asset = aref.Target as AssetBase; - if(asset is null) - weakAssetReferences.Remove(id); - else + if (aref.Target is AssetBase asset) + { m_weakRefHits++; + return asset; + } } } - return asset; + return null; } /// @@ -823,6 +823,12 @@ namespace OpenSim.Region.CoreModules.Asset } } + lock (weakAssetReferencesLock) + { + weakAssetReferences = new Dictionary(); + m_weakRefHits=0; + } + lock (timerLock) { if (m_timerRunning) diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 624599cf82..795e0e64eb 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -1674,10 +1674,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles catch (Exception e) { m_log.Debug( - string.Format( - "[PROFILES]: Request using the OpenProfile API for user {0} to {1} failed", - properties.UserId, serverURI), - e); + $"[PROFILES]: Request using the OpenProfile API for user {properties.UserId} to {serverURI} failed: {e.Message}"); // Allow the return 'message' to say "JsonRpcRequest" and not "OpenProfile", because // the most likely reason that OpenProfile failed is that the remote server diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionGridServiceConnector.cs index a9516cd9bc..033ae2286d 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionGridServiceConnector.cs @@ -310,6 +310,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public GridRegion GetRegionByURI(UUID scopeID, RegionURI uri) { + if(!uri.IsValid) + return null; GridRegion rinfo = m_LocalGridService.GetRegionByURI(scopeID, uri); if (rinfo != null) { @@ -335,6 +337,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid return rinfo; } + public GridRegion GetLocalRegionByName(UUID scopeID, string name) + { + return null; + } + + public GridRegion GetLocalRegionByURI(UUID scopeID, RegionURI uri) + { + return null; + } + public List GetRegionsByName(UUID scopeID, string name, int maxNumber) { var ruri = new RegionURI(name, m_ThisGridInfo); diff --git a/OpenSim/Region/Framework/Scenes/LinksetData.cs b/OpenSim/Region/Framework/Scenes/LinksetData.cs index f450fc2a8f..4138c95417 100644 --- a/OpenSim/Region/Framework/Scenes/LinksetData.cs +++ b/OpenSim/Region/Framework/Scenes/LinksetData.cs @@ -26,11 +26,15 @@ */ using System; +using System.Buffers; using System.Collections.Generic; +using System.IO; using System.Runtime.CompilerServices; -//using log4net; using System.Text.Json; using System.Text.RegularExpressions; +using System.Xml; + +//using log4net; namespace OpenSim.Region.Framework.Scenes { @@ -442,13 +446,142 @@ namespace OpenSim.Region.Framework.Scenes } } - public string SerializeLinksetData() + public string ToJson() { lock (linksetDataLock) { return JsonSerializer.Serialize>(Data); } } + + public void ToXML(XmlTextWriter writer) + { + if (Data.Count < 1) + return; + using MemoryStream ms = new(m_MemoryUsed); + ToBin(ms); + if (ms.Length < 1) + return; + + writer.WriteStartElement("lnkstdt"); + writer.WriteBase64(ms.GetBuffer(), 0, (int)ms.Length); + writer.WriteEndElement(); + } + + public static LinksetData FromXML(ReadOnlySpan data) + { + if (data.Length < 8) + return null; + int minLength = ((data.Length * 3) + 3) / 4; + byte[] bindata = ArrayPool.Shared.Rent(minLength); + try + { + if (Convert.TryFromBase64Chars(data, bindata, out int bytesWritten)) + return FromBin(bindata); + } + catch + { + } + finally + { + ArrayPool.Shared.Return(bindata); + } + return null; + } + + public byte[] ToBin() + { + if(Data.Count < 1) + return null; + + using MemoryStream ms = new(m_MemoryUsed); + ToBin(ms); + return ms.Length > 0 ? ms.ToArray() : null; + } + + public void ToBin(MemoryStream ms) + { + try + { + using BinaryWriter bw = new BinaryWriter(ms, System.Text.Encoding.UTF8, true); + bw.Write((byte)1); // storage version + bw.Write7BitEncodedInt(m_MemoryLimit); + lock (linksetDataLock) + { + bw.Write7BitEncodedInt(Data.Count); + foreach (var kvp in Data) + { + bw.Write(kvp.Key); + bw.Write(kvp.Value.Value); + if(kvp.Value.IsProtected) + bw.Write(kvp.Value.Password); + else + bw.Write((byte)0); + } + } + return; + } + catch { } + ms.SetLength(0); + } + public static LinksetData FromBin(byte[] data) + { + if (data.Length < 8) + return null; + + try + { + using BinaryReader br = new BinaryReader(new MemoryStream(data)); + int version = br.Read7BitEncodedInt(); + int memoryLimit = br.Read7BitEncodedInt(); + if(memoryLimit < 0 || memoryLimit > 256 * 1024) + memoryLimit = 256 * 1024; + + int count = br.Read7BitEncodedInt(); + if(count == 0) + return null; + LinksetData ld = new LinksetData(memoryLimit); + for(int i = 0; i < count; i++) + { + string key = br.ReadString(); + if (key.Length == 0) + continue; + ld.m_MemoryUsed += key.Length; + + string value = br.ReadString(); + if(value.Length == 0) + continue; + ld.m_MemoryUsed += value.Length; + + string pass = br.ReadString(); + ld.m_MemoryUsed += pass.Length; + if(ld.m_MemoryUsed > memoryLimit) + break; + + if(pass.Length > 0) + { + ld.Data[key] = new LinksetDataEntry() + { + Value = value, + Password = pass + }; + } + else + { + ld.Data[key] = new LinksetDataEntry() + { + Value = value, + Password = null + }; + } + } + return ld; + } + catch + { + } + return null; + } } public class LinksetDataEntry diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index adb107320b..416e6babef 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1234,7 +1234,9 @@ namespace OpenSim.Region.Framework.Scenes } */ scriptedcontrols.Clear(); + // gc gets confused with this cycling ControllingClient = null; + GodController = null; // gc gets confused with this cycling } } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 75449a097c..6e4d021fc3 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -143,8 +143,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization string innerkeytxt = reader.ReadElementContentAsString(); sceneObject.RootPart.KeyframeMotion = KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(innerkeytxt)); } - else - sceneObject.RootPart.KeyframeMotion = null; + + if (reader.Name == "lnkstdt" && reader.NodeType == XmlNodeType.Element) + { + string innerlnkstdttxt = reader.ReadElementContentAsString(); + sceneObject.LinksetData = LinksetData.FromXML(innerlnkstdttxt.AsSpan()); + } // Script state may, or may not, exist. Not having any, is NOT // ever a problem. @@ -255,6 +259,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteEndElement(); } + sceneObject.LinksetData?.ToXML(writer); + if (doScriptStates) sceneObject.SaveScriptedState(writer); @@ -325,8 +331,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization XmlNodeList keymotion = doc.GetElementsByTagName("KeyframeMotion"); if (keymotion.Count > 0) sceneObject.RootPart.KeyframeMotion = KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(keymotion[0].InnerText)); - else - sceneObject.RootPart.KeyframeMotion = null; + + XmlNodeList keylinksetdata = doc.GetElementsByTagName("lnkstdt"); + if (keylinksetdata.Count > 0) + sceneObject.LinksetData = LinksetData.FromXML(keylinksetdata[0].InnerText.AsSpan()); // Script state may, or may not, exist. Not having any, is NOT // ever a problem. diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs index 0c423b3956..0edd54a2dd 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs @@ -224,25 +224,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine bool err = false; for(int i = 0; i < (int)ScriptEventCode.Size; i++) { - string mycode = "undefined"; - string oscode = "undefined"; - try - { - mycode = ((ScriptEventCode)i).ToString(); - Convert.ToInt64(mycode); - mycode = "undefined"; - } - catch { } - try - { - oscode = ((SceneScriptEvents)(1ul << i)).ToString(); - Convert.ToInt64(oscode); - oscode = "undefined"; - } - catch { } + string mycode = Enum.GetName(typeof(ScriptEventCode), i); + string oscode = Enum.GetName(typeof(SceneScriptEvents), 1UL << i); if(mycode != oscode) { - m_log.ErrorFormat("[YEngine]: {0} mycode={1}, oscode={2}", i, mycode, oscode); + m_log.ErrorFormat($"[YEngine]: {i} mycode={mycode}, oscode={oscode}"); err = true; } } diff --git a/OpenSim/Server/Handlers/Hypergrid/HypergridHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/HypergridHandlers.cs index c76d342b33..31c1ef8c42 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HypergridHandlers.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HypergridHandlers.cs @@ -65,16 +65,9 @@ namespace OpenSim.Server.Handlers.Hypergrid if (name == null) name = string.Empty; - UUID regionID = UUID.Zero; - string externalName = string.Empty; - string imageURL = string.Empty; - ulong regionHandle = 0; - string reason = string.Empty; - int sizeX = 256; - int sizeY = 256; - m_log.DebugFormat("[HG Handler]: XMLRequest to link to {0} from {1}", (name.Length == 0) ? "default region" : name, remoteClient.Address.ToString()); - bool success = m_GatekeeperService.LinkRegion(name, out regionID, out regionHandle, out externalName, out imageURL, out reason, out sizeX, out sizeY); + bool success = m_GatekeeperService.LinkLocalRegion(name, out UUID regionID, out ulong regionHandle, out string externalName, + out string imageURL, out string reason, out int sizeX, out int sizeY); Hashtable hash = new Hashtable(); hash["result"] = success.ToString(); diff --git a/OpenSim/Server/runtimeconfig.template.json b/OpenSim/Server/runtimeconfig.template.json index c95ce9e516..6d427663d0 100644 --- a/OpenSim/Server/runtimeconfig.template.json +++ b/OpenSim/Server/runtimeconfig.template.json @@ -1,7 +1,11 @@ { - "configProperties": { - "System.GC.Server": false, - "System.Drawing.EnableUnixSupport": true, - "System.Globalization.UseNls": true + "configProperties": { + "System.GC.Server": false, + "System.GC.HighMemoryPercent": 50, + "System.Drawing.EnableUnixSupport": true, + "System.Globalization.UseNls": true, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true, + "System.Runtime.TieredCompilation.QuickJit": false } } \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs index 32b95cabba..ec0c3bf8de 100644 --- a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs @@ -369,11 +369,20 @@ namespace OpenSim.Services.Connectors return rinfo; } + public GridRegion GetLocalRegionByName(UUID scopeID, string regionName) + { + return null; + } public GridRegion GetRegionByURI(UUID scopeID, RegionURI uri) { return null; } + public GridRegion GetLocalRegionByURI(UUID scopeID, RegionURI uri) + { + return null; + } + public List GetRegionsByName(UUID scopeID, string name, int maxNumber) { Dictionary sendData = new Dictionary(); diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 41da5ab912..194858bd3e 100755 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -546,7 +546,7 @@ namespace OpenSim.Services.GridService if (localGrid) { - if(uri.HasRegionName) + if (uri.HasRegionName) { RegionData rdata = m_Database.GetSpecific(uri.RegionName, scopeID); if (rdata != null) @@ -583,6 +583,40 @@ namespace OpenSim.Services.GridService return r; } + public GridRegion GetLocalRegionByName(UUID scopeID, string name) + { + var nameURI = new RegionURI(name); + return GetLocalRegionByURI(scopeID, nameURI); + } + + public GridRegion GetLocalRegionByURI(UUID scopeID, RegionURI uri) + { + if (!uri.IsValid) + return null; + + if (uri.HasHost) + { + if (!uri.ResolveDNS()) + return null; + if(!m_HypergridLinker.IsLocalGrid(uri.HostUrl)) + return null; + } + + if (uri.HasRegionName) + { + RegionData rdata = m_Database.GetSpecific(uri.RegionName, scopeID); + if (rdata != null) + return RegionData2RegionInfo(rdata); + } + else + { + List defregs = GetDefaultRegions(scopeID); + if (defregs != null) + return defregs[0]; + } + return null; + } + public List GetRegionsByName(UUID scopeID, string name, int maxNumber) { // m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index f0e45d0548..e5dbd6107b 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -222,7 +222,7 @@ namespace OpenSim.Services.HypergridService } } - public bool LinkRegion(string regionName, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason, out int sizeX, out int sizeY) + public bool LinkLocalRegion(string regionName, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason, out int sizeX, out int sizeY) { regionID = UUID.Zero; regionHandle = 0; @@ -251,7 +251,7 @@ namespace OpenSim.Services.HypergridService } else { - region = m_GridService.GetRegionByName(m_ScopeID, regionName); + region = m_GridService.GetLocalRegionByName(m_ScopeID, regionName); if (region is null) { reason = "Region not found"; diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index 8982810201..a6bfbc88a9 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -85,6 +85,9 @@ namespace OpenSim.Services.Interfaces GridRegion GetRegionByName(UUID scopeID, string regionName); GridRegion GetRegionByURI(UUID scopeID, RegionURI uri); + GridRegion GetLocalRegionByName(UUID scopeID, string regionName); + GridRegion GetLocalRegionByURI(UUID scopeID, RegionURI uri); + /// /// Get information about regions starting with the provided name. /// diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs index e0a63cabe1..bb0b165da4 100644 --- a/OpenSim/Services/Interfaces/IHypergridServices.cs +++ b/OpenSim/Services/Interfaces/IHypergridServices.cs @@ -36,7 +36,7 @@ namespace OpenSim.Services.Interfaces { public interface IGatekeeperService { - bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason, out int sizeX, out int sizeY); + bool LinkLocalRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason, out int sizeX, out int sizeY); /// /// Returns the region a Hypergrid visitor should enter. diff --git a/bin/OpenMetaverse.Rendering.Meshmerizer.dll b/bin/OpenMetaverse.Rendering.Meshmerizer.dll index 048a0f404c..dee4601730 100755 Binary files a/bin/OpenMetaverse.Rendering.Meshmerizer.dll and b/bin/OpenMetaverse.Rendering.Meshmerizer.dll differ diff --git a/bin/OpenMetaverse.StructuredData.dll b/bin/OpenMetaverse.StructuredData.dll index 66a3c003d0..64163d7746 100755 Binary files a/bin/OpenMetaverse.StructuredData.dll and b/bin/OpenMetaverse.StructuredData.dll differ diff --git a/bin/OpenMetaverse.dll b/bin/OpenMetaverse.dll index 1bdadf684f..f8c2b0a625 100755 Binary files a/bin/OpenMetaverse.dll and b/bin/OpenMetaverse.dll differ diff --git a/bin/OpenMetaverseTypes.dll b/bin/OpenMetaverseTypes.dll index 2530be809b..92be2a4c5d 100755 Binary files a/bin/OpenMetaverseTypes.dll and b/bin/OpenMetaverseTypes.dll differ diff --git a/bin/System.Drawing.Common.dll b/bin/System.Drawing.Common.dll deleted file mode 100644 index 7c9e87b4e1..0000000000 Binary files a/bin/System.Drawing.Common.dll and /dev/null differ diff --git a/bin/assets/TexturesAssetSet/5b53359e-59dd-d8a2-04c3-9e65134da47a.jp2 b/bin/assets/TexturesAssetSet/5b53359e-59dd-d8a2-04c3-9e65134da47a.jp2 new file mode 100644 index 0000000000..25ad750fa8 Binary files /dev/null and b/bin/assets/TexturesAssetSet/5b53359e-59dd-d8a2-04c3-9e65134da47a.jp2 differ diff --git a/bin/assets/TexturesAssetSet/85f28839-7a1c-b4e3-d71d-967792970a7b.jp2 b/bin/assets/TexturesAssetSet/85f28839-7a1c-b4e3-d71d-967792970a7b.jp2 new file mode 100644 index 0000000000..f6d617dc51 Binary files /dev/null and b/bin/assets/TexturesAssetSet/85f28839-7a1c-b4e3-d71d-967792970a7b.jp2 differ diff --git a/bin/assets/TexturesAssetSet/87e0e8f7-8729-1ea8-cfc9-8915773009db.jp2 b/bin/assets/TexturesAssetSet/87e0e8f7-8729-1ea8-cfc9-8915773009db.jp2 new file mode 100644 index 0000000000..f2647236b7 Binary files /dev/null and b/bin/assets/TexturesAssetSet/87e0e8f7-8729-1ea8-cfc9-8915773009db.jp2 differ diff --git a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml index dfd3c41131..9b115e607c 100644 --- a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml +++ b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml @@ -610,13 +610,6 @@ -
- - - - -
-
@@ -906,4 +899,28 @@
+
+ + + + + +
+ +
+ + + + + +
+ +
+ + + + + +
+ diff --git a/prebuild.xml b/prebuild.xml index f324aea385..0e1d64a786 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1,7 +1,7 @@ - + TRACE diff --git a/runprebuild.bat b/runprebuild.bat index e8cd98c35f..7eb3c5fa06 100755 --- a/runprebuild.bat +++ b/runprebuild.bat @@ -1,5 +1,7 @@ @echo OFF +copy bin\System.Drawing.Common.dll.win bin\System.Drawing.Common.dll + dotnet bin\prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml @echo Creating compile.bat @@ -8,7 +10,7 @@ rem To compile in debug mode rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem) rem @echo dotnet build --configuration Debug OpenSim.sln > compile.bat :done -copy bin\System.Drawing.Common.dll.win bin\System.Drawing.Common.dll + if exist "bin\addin-db-002" ( del /F/Q/S bin\addin-db-002 > NUL diff --git a/runprebuild.sh b/runprebuild.sh index 2c1d64a8a5..5f724617c2 100755 --- a/runprebuild.sh +++ b/runprebuild.sh @@ -18,10 +18,10 @@ case "$1" in *) + cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll dotnet bin/prebuild.dll /target vs2022 /targetframework net6_0 /excludedir = "obj | bin" /file prebuild.xml echo "dotnet build -c Release OpenSim.sln" > compile.sh chmod +x compile.sh - cp bin/System.Drawing.Common.dll.linux bin/System.Drawing.Common.dll ;;