mirror of
https://github.com/opensim/opensim.git
synced 2026-08-12 12:25:42 +08:00
Merge branch 'opensim:master' into master
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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]));
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -695,8 +695,8 @@ namespace OSHttpServer
|
||||
m_stream.EndWrite(res);
|
||||
|
||||
ContextTimeoutManager.ContextLeaveActiveSend();
|
||||
didleave = true;
|
||||
m_currentResponse.CheckSendNextAsyncContinue();
|
||||
didleave = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user