Merge branch 'opensim:master' into master

This commit is contained in:
AdilElFarissi
2024-04-08 07:17:51 +00:00
committed by GitHub
57 changed files with 643 additions and 421 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<RegionData> 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<RegionData> GetDefaultRegions(UUID scopeID)

View File

@@ -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<UUID, TerrainData> m_bakedterrains = new Dictionary<UUID, TerrainData>();
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)

View File

@@ -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);
}
/// <summary>
@@ -62,51 +59,38 @@ namespace OpenSim.Data.Null
/// <returns></returns>
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<string> fieldsLst = new List<string>(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<UserAccountData>();
}
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;
}

View File

@@ -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<string, object> oAuth = new Dictionary<string, object>();

View File

@@ -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<string, string>(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]));

View File

@@ -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<string>(data.Data.Keys).ToArray();

View File

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

View File

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

View File

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

View File

@@ -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<string>(data.Data.Keys).ToArray();
string[] values = new string[data.Data.Count];

View File

@@ -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;
}
/// <summary>

View File

@@ -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<string, KeyValuePair<string, UUID>> 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)

View File

@@ -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<AvatarAttachment>();
ref List<AvatarAttachment> atlst = ref CollectionsMarshal.GetValueRefOrAddDefault(m_attachments, attach.AttachPoint, out bool ex);
if(!ex)
{
atlst = new List<AvatarAttachment>() { 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<AvatarAttachment>();
m_attachments[attach.AttachPoint].Add(attach);
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>() { attach };
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<string> GetCategoryStatsReports(

View File

@@ -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;
}
/// <summary>

View File

@@ -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<T> loadedPlugins = new List<T>();
foreach (PluginExtensionNode node in AddinManager.GetExtensionNodes(ext))

View File

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

View File

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

View File

@@ -53,9 +53,9 @@ namespace OpenSim.Framework
public bool TryGet<T>(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);

View File

@@ -695,8 +695,8 @@ namespace OSHttpServer
m_stream.EndWrite(res);
ContextTimeoutManager.ContextLeaveActiveSend();
didleave = true;
m_currentResponse.CheckSendNextAsyncContinue();
didleave = true;
}
catch (Exception e)
{

View File

@@ -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;
/// <summary>
/// Initializes a new instance of the <see cref="IHttpResponse"/> 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();

View File

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

View File

@@ -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;
}
/// <summary>
@@ -823,6 +823,12 @@ namespace OpenSim.Region.CoreModules.Asset
}
}
lock (weakAssetReferencesLock)
{
weakAssetReferences = new Dictionary<string, WeakReference>();
m_weakRefHits=0;
}
lock (timerLock)
{
if (m_timerRunning)

View File

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

View File

@@ -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<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
{
var ruri = new RegionURI(name, m_ThisGridInfo);

View File

@@ -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<Dictionary<string, LinksetDataEntry>>(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<char> data)
{
if (data.Length < 8)
return null;
int minLength = ((data.Length * 3) + 3) / 4;
byte[] bindata = ArrayPool<byte>.Shared.Rent(minLength);
try
{
if (Convert.TryFromBase64Chars(data, bindata, out int bytesWritten))
return FromBin(bindata);
}
catch
{
}
finally
{
ArrayPool<byte>.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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
{
Dictionary<string, object> sendData = new Dictionary<string, object>();

View File

@@ -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<GridRegion> defregs = GetDefaultRegions(scopeID);
if (defregs != null)
return defregs[0];
}
return null;
}
public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
{
// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name);

View File

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

View File

@@ -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);
/// <summary>
/// Get information about regions starting with the provided name.
/// </summary>

View File

@@ -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);
/// <summary>
/// Returns the region a Hypergrid visitor should enter.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -610,13 +610,6 @@
<Key Name="fileName" Value="79504bf5-c3ec-0763-6563-d843de66d0a1.j2c" />
</Section>
<Section Name="Grass 2">
<Key Name="assetID" Value="6c4727b8-ac79-ba44-3b81-f9aa887b47eb"/>
<Key Name="name" Value="Grass 2"/>
<Key Name="assetType" Value="0" />
<Key Name="fileName" Value="6c4727b8-ac79-ba44-3b81-f9aa887b47eb.j2c" />
</Section>
<Section Name="Grass 3">
<Key Name="assetID" Value="99bd60a2-3250-efc9-2e39-2fbcadefbecc"/>
<Key Name="name" Value="Grass 3"/>
@@ -906,4 +899,28 @@
<Key Name = "fileName" Value = "32bfbcea-24b1-fb9d-1ef9-48a28a63730f.dat" />
</Section>
<Section Name = "DefaultObjectSpecular">
<Key Name = "assetID" Value = "87e0e8f7-8729-1ea8-cfc9-8915773009db" />
<Key Name = "name" Value = "DefaultObjectSpecular" />
<Key Name = "description" Value = "DefaultObjectSpecular" />
<Key Name = "assetType" Value = "0" />
<Key Name = "fileName" Value = "87e0e8f7-8729-1ea8-cfc9-8915773009db.jp2" />
</Section>
<Section Name = "DefaultObjectNormal">
<Key Name = "assetID" Value = "85f28839-7a1c-b4e3-d71d-967792970a7b" />
<Key Name = "name" Value = "DefaultObjectNormal" />
<Key Name = "description" Value = "DefaultObjectNormal" />
<Key Name = "assetType" Value = "0" />
<Key Name = "fileName" Value = "85f28839-7a1c-b4e3-d71d-967792970a7b.jp2" />
</Section>
<Section Name = "BlankObjectNormal">
<Key Name = "assetID" Value = "5b53359e-59dd-d8a2-04c3-9e65134da47a" />
<Key Name = "name" Value = "BlankObjectNormal" />
<Key Name = "description" Value = "BlankObjectNormal" />
<Key Name = "assetType" Value = "0" />
<Key Name = "fileName" Value = "5b53359e-59dd-d8a2-04c3-9e65134da47a.jp2" />
</Section>
</Nini>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" ?>
<Prebuild version="1.10" xmlns="http://dnpb.sourceforge.net/schemas/prebuild-1.10.xsd">
<!-- <Solution activeConfig="Debug" name="OpenSim" path="./" version="0.5.0-$Rev$" forceFrameworkVersion="v4_6"> -->
<Solution activeConfig="Debug" name="OpenSim" path="./" version="0.5.0-$Rev$" frameworkVersion="net6_0">
<Solution activeConfig="Release" name="OpenSim" path="./" version="0.5.0-$Rev$" frameworkVersion="net6_0">
<Configuration name="Debug" >
<Options>
<CompilerDefines>TRACE</CompilerDefines>

View File

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

View File

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