From 60df76314f89d8a489a7f8a3182277cf1a52925c Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 3 Aug 2010 15:45:49 +0100 Subject: [PATCH] serialize media textures to inventory with a largely osd representation rather than .net auto-serialization THIS WILL BREAK ANY EXISTING MEDIA TEXTURE SERIALIZATIONS. If you're testing this, please start with new databases. This makes media textures serialized in the same way, which is probably better in the long term. --- OpenSim/Framework/PrimitiveBaseShape.cs | 90 ++++++++++++++++++- .../World/Media/Moap/MoapModule.cs | 8 +- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 03ddb3394e..de7e42d700 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -29,7 +29,10 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; +using System.IO; using System.Reflection; +using System.Xml; +using System.Xml.Schema; using System.Xml.Serialization; using log4net; using OpenMetaverse; @@ -183,7 +186,7 @@ namespace OpenSim.Framework /// Entries to store media textures on each face /// /// Do not change this value directly - always do it through an IMoapModule. - public List Media { get; set; } + public MediaList Media { get; set; } public PrimitiveBaseShape() { @@ -1221,5 +1224,86 @@ namespace OpenSim.Framework return prim; } - } -} + + public class MediaList : List, IXmlSerializable + { + public const string MEDIA_TEXTURE_TYPE = "sl"; + + public MediaList() : base() {} + public MediaList(IEnumerable collection) : base(collection) {} + public MediaList(int capacity) : base(capacity) {} + + public XmlSchema GetSchema() + { + return null; + } + + public void WriteXml(XmlWriter writer) + { + lock (this) + { + using (StringWriter sw = new StringWriter()) + { + using (XmlTextWriter xtw = new XmlTextWriter(sw)) + { + xtw.WriteStartElement("osmedia"); + xtw.WriteAttributeString("type", MEDIA_TEXTURE_TYPE); + xtw.WriteAttributeString("major_version", "0"); + xtw.WriteAttributeString("minor_version", "1"); + + OSDArray meArray = new OSDArray(); + foreach (MediaEntry me in this) + { + OSD osd = (null == me ? new OSD() : me.GetOSD()); + meArray.Add(osd); + } + + xtw.WriteStartElement("osdata"); + xtw.WriteRaw(OSDParser.SerializeLLSDXmlString(meArray)); + xtw.WriteEndElement(); + + xtw.WriteEndElement(); + + xtw.Flush(); + writer.WriteRaw(sw.ToString()); + } + } + } + } + + public void ReadXml(XmlReader reader) + { + if (reader.IsEmptyElement) + return; + + string rawXml = reader.ReadInnerXml(); + using (StringReader sr = new StringReader(rawXml)) + { + using (XmlTextReader xtr = new XmlTextReader(sr)) + { + xtr.MoveToContent(); + + string type = xtr.GetAttribute("type"); + //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type); + + if (type != MEDIA_TEXTURE_TYPE) + return; + + xtr.ReadStartElement("osmedia"); + + OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); + + List mediaEntries = new List(); + foreach (OSD osdMe in osdMeArray) + { + MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); + Add(me); + } + + xtr.ReadEndElement(); + } + } + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index e9d723bc98..339a979f75 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -219,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); - List mediaEntries = new List(); + PrimitiveBaseShape.MediaList mediaEntries = new PrimitiveBaseShape.MediaList(); foreach (OSD osdMe in osdMeArray) { MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); @@ -270,7 +270,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap { if (original.Shape.Media != null) { - List dupeMedia = new List(); + PrimitiveBaseShape.MediaList dupeMedia = new PrimitiveBaseShape.MediaList(); foreach (MediaEntry me in original.Shape.Media) { @@ -315,7 +315,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap CheckFaceParam(part, face); if (null == part.Shape.Media) - part.Shape.Media = new List(new MediaEntry[part.GetNumberOfSides()]); + part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]); part.Shape.Media[face] = me; UpdateMediaUrl(part, UUID.Zero); @@ -439,7 +439,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (null == media) { // m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name); - part.Shape.Media = new List(omu.FaceMedia); + part.Shape.Media = new PrimitiveBaseShape.MediaList(omu.FaceMedia); for (int i = 0; i < omu.FaceMedia.Length; i++) {