store linksetdata in inventory and region mysql db ( others todo) UNTESTED

This commit is contained in:
UbitUmarov
2024-03-28 22:03:14 +00:00
parent e918888e30
commit 573af89389
4 changed files with 184 additions and 34 deletions

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

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.