mirror of
https://github.com/OpenSim-NGC/OpenSim-Sasquatch.git
synced 2024-11-21 14:29:10 -07:00
store linksetdata in inventory and region mysql db ( others todo) UNTESTED
This commit is contained in:
parent
e918888e30
commit
573af89389
4 changed files with 184 additions and 34 deletions
|
@ -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;
|
|
@ -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,139 @@ 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;
|
||||
var minLength = ((data.Length * 3) + 3) / 4;
|
||||
var 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.ToArray();
|
||||
}
|
||||
|
||||
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);
|
||||
bw.Write(kvp.Value.Password);
|
||||
}
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue