Merge branch 'dynamic-attributes2'

user_profiles
Justin Clark-Casey (justincc) 2013-02-05 00:35:15 +00:00
commit 1fc9f282fa
12 changed files with 497 additions and 10 deletions

View File

@ -351,7 +351,7 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID)
ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice,
SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem,
ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches,
LinkNumber = @LinkNumber, MediaURL = @MediaURL
LinkNumber = @LinkNumber, MediaURL = @MediaURL, DynAttrs = @DynAttrs
WHERE UUID = @UUID
END
ELSE
@ -366,7 +366,7 @@ ELSE
PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX,
OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ,
ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA,
ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL
ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL, DynAttrs
) VALUES (
@UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask,
@EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX,
@ -376,7 +376,7 @@ ELSE
@PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX,
@OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ,
@ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA,
@ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL
@ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL, @DynAttrs
)
END";
@ -1692,6 +1692,11 @@ VALUES
if (!(primRow["MediaURL"] is System.DBNull))
prim.MediaUrl = (string)primRow["MediaURL"];
if (!(primRow["DynAttrs"] is System.DBNull))
prim.DynAttrs = DAMap.FromXml((string)primRow["DynAttrs"]);
else
prim.DynAttrs = new DAMap();
return prim;
}
@ -1749,7 +1754,6 @@ VALUES
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
}
return baseShape;
}
@ -2087,6 +2091,11 @@ VALUES
parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl));
if (prim.DynAttrs.Count > 0)
parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml()));
else
parameters.Add(_Database.CreateParameter("DynAttrs", null));
return parameters.ToArray();
}
@ -2143,7 +2152,6 @@ VALUES
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
}
return parameters.ToArray();
}

View File

@ -1148,3 +1148,11 @@ CREATE TABLE [dbo].[regionenvironment](
) ON [PRIMARY]
COMMIT
:VERSION 38 #---------------- Dynamic attributes
BEGIN TRANSACTION
ALTER TABLE prims ADD COLUMN DynAttrs TEXT;
COMMIT

View File

@ -171,7 +171,8 @@ namespace OpenSim.Data.MySQL
"ParticleSystem, ClickAction, Material, " +
"CollisionSound, CollisionSoundVolume, " +
"PassTouches, " +
"LinkNumber, MediaURL) values (" + "?UUID, " +
"LinkNumber, MediaURL, DynAttrs) " +
"values (?UUID, " +
"?CreationDate, ?Name, ?Text, " +
"?Description, ?SitName, ?TouchName, " +
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
@ -202,7 +203,8 @@ namespace OpenSim.Data.MySQL
"?SaleType, ?ColorR, ?ColorG, " +
"?ColorB, ?ColorA, ?ParticleSystem, " +
"?ClickAction, ?Material, ?CollisionSound, " +
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber, " +
"?MediaURL, ?DynAttrs)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
@ -219,7 +221,8 @@ namespace OpenSim.Data.MySQL
"PathTaperX, PathTaperY, PathTwist, " +
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
"ProfileCurve, ProfileHollow, Texture, " +
"ExtraParams, State, Media) values (?UUID, " +
"ExtraParams, State, Media) " +
"values (?UUID, " +
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
"?PCode, ?PathBegin, ?PathEnd, " +
"?PathScaleX, ?PathScaleY, " +
@ -1292,6 +1295,11 @@ namespace OpenSim.Data.MySQL
if (!(row["MediaURL"] is System.DBNull))
prim.MediaUrl = (string)row["MediaURL"];
if (!(row["DynAttrs"] is System.DBNull))
prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]);
else
prim.DynAttrs = new DAMap();
return prim;
}
@ -1637,6 +1645,11 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
if (prim.DynAttrs.Count > 0)
cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml());
else
cmd.Parameters.AddWithValue("DynAttrs", null);
}
/// <summary>

View File

@ -902,3 +902,11 @@ BEGIN;
CREATE TABLE `regionextra` (`RegionID` char(36) not null, `Name` varchar(32) not null, `value` text, primary key(`RegionID`, `Name`));
COMMIT;
:VERSION 46 #---------------- Dynamic attributes
BEGIN;
ALTER TABLE prims ADD COLUMN DynAttrs TEXT;
COMMIT;

View File

@ -575,3 +575,8 @@ CREATE TABLE `regionenvironment` (
);
COMMIT;
:VERSION 27
BEGIN;
ALTER TABLE prims ADD COLUMN DynAttrs TEXT;
COMMIT;

View File

@ -1233,6 +1233,8 @@ namespace OpenSim.Data.SQLite
createCol(prims, "MediaURL", typeof(String));
createCol(prims, "DynAttrs", typeof(String));
// Add in contraints
prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] };
@ -1712,6 +1714,16 @@ namespace OpenSim.Data.SQLite
prim.MediaUrl = (string)row["MediaURL"];
}
if (!(row["DynAttrs"] is System.DBNull))
{
//m_log.DebugFormat("[SQLITE]: DynAttrs type [{0}]", row["DynAttrs"].GetType());
prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]);
}
else
{
prim.DynAttrs = new DAMap();
}
return prim;
}
@ -2133,6 +2145,11 @@ namespace OpenSim.Data.SQLite
row["VolumeDetect"] = 0;
row["MediaURL"] = prim.MediaUrl;
if (prim.DynAttrs.Count > 0)
row["DynAttrs"] = prim.DynAttrs.ToXml();
else
row["DynAttrs"] = null;
}
/// <summary>

260
OpenSim/Framework/DAMap.cs Normal file
View File

@ -0,0 +1,260 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Framework
{
/// <summary>
/// This class stores and retrieves dynamic attributes.
/// </summary>
/// <remarks>
/// Modules that want to use dynamic attributes need to do so in a private data store
/// which is accessed using a unique name. DAMap provides access to the data stores,
/// each of which is an OSDMap. Modules are free to store any type of data they want
/// within their data store. However, avoid storing large amounts of data because that
/// would slow down database access.
/// </remarks>
public class DAMap : IDictionary<string, OSDMap>, IXmlSerializable
{
private static readonly int MIN_STORE_NAME_LENGTH = 4;
protected OSDMap m_map;
public DAMap() { m_map = new OSDMap(); }
public XmlSchema GetSchema() { return null; }
public static DAMap FromXml(string rawXml)
{
DAMap map = new DAMap();
map.ReadXml(rawXml);
return map;
}
public void ReadXml(string rawXml)
{
// System.Console.WriteLine("Trying to deserialize [{0}]", rawXml);
lock (this)
m_map = (OSDMap)OSDParser.DeserializeLLSDXml(rawXml);
}
public void ReadXml(XmlReader reader)
{
ReadXml(reader.ReadInnerXml());
}
public string ToXml()
{
lock (this)
return OSDParser.SerializeLLSDXmlString(m_map);
}
public void WriteXml(XmlWriter writer)
{
writer.WriteRaw(ToXml());
}
public void CopyFrom(DAMap other)
{
// Deep copy
string data = null;
lock (other)
{
if (other.Count > 0)
{
data = OSDParser.SerializeLLSDXmlString(other.m_map);
}
}
lock (this)
{
if (data == null)
Clear();
else
m_map = (OSDMap)OSDParser.DeserializeLLSDXml(data);
}
}
/// <summary>
/// Returns the number of data stores.
/// </summary>
public int Count { get { lock (this) { return m_map.Count; } } }
public bool IsReadOnly { get { return false; } }
/// <summary>
/// Returns the names of the data stores.
/// </summary>
public ICollection<string> Keys { get { lock (this) { return m_map.Keys; } } }
/// <summary>
/// Returns all the data stores.
/// </summary>
public ICollection<OSDMap> Values
{
get
{
lock (this)
{
List<OSDMap> stores = new List<OSDMap>(m_map.Count);
foreach (OSD llsd in m_map.Values)
stores.Add((OSDMap)llsd);
return stores;
}
}
}
/// <summary>
/// Gets or sets one data store.
/// </summary>
/// <param name="key">Store name</param>
/// <returns></returns>
public OSDMap this[string key]
{
get
{
OSD llsd;
lock (this)
{
if (m_map.TryGetValue(key, out llsd))
return (OSDMap)llsd;
else
return null;
}
}
set
{
ValidateKey(key);
lock (this)
m_map[key] = value;
}
}
private static void ValidateKey(string key)
{
if (key.Length < MIN_STORE_NAME_LENGTH)
throw new Exception("Minimum store name length is " + MIN_STORE_NAME_LENGTH);
}
public bool ContainsKey(string key)
{
lock (this)
return m_map.ContainsKey(key);
}
public void Add(string key, OSDMap store)
{
ValidateKey(key);
lock (this)
m_map.Add(key, store);
}
public void Add(KeyValuePair<string, OSDMap> kvp)
{
lock (this)
m_map.Add(kvp.Key, kvp.Value);
}
public bool Remove(string key)
{
lock (this)
return m_map.Remove(key);
}
public bool TryGetValue(string key, out OSDMap store)
{
lock (this)
{
OSD llsd;
if (m_map.TryGetValue(key, out llsd))
{
store = (OSDMap)llsd;
return true;
}
else
{
store = null;
return false;
}
}
}
public void Clear()
{
lock (this)
m_map.Clear();
}
public bool Contains(KeyValuePair<string, OSDMap> kvp)
{
lock (this)
return m_map.ContainsKey(kvp.Key);
}
public void CopyTo(KeyValuePair<string, OSDMap>[] array, int index)
{
throw new NotImplementedException();
}
public bool Remove(KeyValuePair<string, OSDMap> kvp)
{
lock (this)
return m_map.Remove(kvp.Key);
}
public System.Collections.IDictionaryEnumerator GetEnumerator()
{
lock (this)
return m_map.GetEnumerator();
}
IEnumerator<KeyValuePair<string, OSDMap>> IEnumerable<KeyValuePair<string, OSDMap>>.GetEnumerator()
{
return null;
}
IEnumerator IEnumerable.GetEnumerator()
{
lock (this)
return m_map.GetEnumerator();
}
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
public class DAExampleModule : INonSharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly bool ENABLED = false; // enable for testing
protected Scene m_scene;
protected IDialogModule m_dialogMod;
public string Name { get { return "DAExample Module"; } }
public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source) {}
public void AddRegion(Scene scene)
{
if (ENABLED)
{
m_scene = scene;
m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove;
m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
}
}
public void RemoveRegion(Scene scene)
{
if (ENABLED)
{
m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
}
}
public void RegionLoaded(Scene scene) {}
public void Close()
{
RemoveRegion(m_scene);
}
protected bool OnSceneGroupMove(UUID groupId, Vector3 delta)
{
OSDMap attrs = null;
SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId);
if (!sop.DynAttrs.TryGetValue(Name, out attrs))
attrs = new OSDMap();
OSDInteger newValue;
if (!attrs.ContainsKey("moves"))
newValue = new OSDInteger(1);
else
newValue = new OSDInteger(((OSDInteger)attrs["moves"]).AsInteger() + 1);
attrs["moves"] = newValue;
sop.DynAttrs[Name] = attrs;
m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue));
return true;
}
}
}

View File

@ -35,6 +35,7 @@ using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common;
using OpenMetaverse.StructuredData;
namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
{
@ -143,6 +144,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
<Flags>None</Flags>
<CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound>
<CollisionSoundVolume>0</CollisionSoundVolume>
<DynAttrs><llsd><map><key>MyStore</key><map><key>the answer</key><integer>42</integer></map></map></llsd></DynAttrs>
</SceneObjectPart>
</RootPart>
<OtherParts />
@ -331,6 +333,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
<EveryoneMask>0</EveryoneMask>
<NextOwnerMask>2147483647</NextOwnerMask>
<Flags>None</Flags>
<DynAttrs><llsd><map><key>MyStore</key><map><key>last words</key><string>Rosebud</string></map></map></llsd></DynAttrs>
<SitTargetAvatar><UUID>00000000-0000-0000-0000-000000000000</UUID></SitTargetAvatar>
</SceneObjectPart>
<OtherParts />
@ -359,6 +362,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790")));
Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d")));
Assert.That(rootPart.Name, Is.EqualTo("PrimMyRide"));
OSDMap store = rootPart.DynAttrs["MyStore"];
Assert.AreEqual(42, store["the answer"].AsInteger());
// TODO: Check other properties
}
@ -409,6 +414,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
rp.CreatorID = rpCreatorId;
rp.Shape = shape;
string daStoreName = "MyStore";
string daKey = "foo";
string daValue = "bar";
OSDMap myStore = new OSDMap();
myStore.Add(daKey, daValue);
rp.DynAttrs = new DAMap();
rp.DynAttrs[daStoreName] = myStore;
SceneObjectGroup so = new SceneObjectGroup(rp);
// Need to add the object to the scene so that the request to get script state succeeds
@ -424,6 +437,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
UUID uuid = UUID.Zero;
string name = null;
UUID creatorId = UUID.Zero;
DAMap daMap = null;
while (xtr.Read() && xtr.Name != "SceneObjectPart")
{
@ -449,6 +463,10 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
creatorId = UUID.Parse(xtr.ReadElementString("UUID"));
xtr.ReadEndElement();
break;
case "DynAttrs":
daMap = new DAMap();
daMap.ReadXml(xtr);
break;
}
}
@ -462,6 +480,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
Assert.That(uuid, Is.EqualTo(rpUuid));
Assert.That(name, Is.EqualTo(rpName));
Assert.That(creatorId, Is.EqualTo(rpCreatorId));
Assert.NotNull(daMap);
Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString());
}
[Test]
@ -476,6 +496,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946")));
Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("b46ef588-411e-4a8b-a284-d7dcfe8e74ef")));
Assert.That(rootPart.Name, Is.EqualTo("PrimFun"));
OSDMap store = rootPart.DynAttrs["MyStore"];
Assert.AreEqual("Rosebud", store["last words"].AsString());
// TODO: Check other properties
}
@ -500,6 +522,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
rp.CreatorID = rpCreatorId;
rp.Shape = shape;
string daStoreName = "MyStore";
string daKey = "foo";
string daValue = "bar";
OSDMap myStore = new OSDMap();
myStore.Add(daKey, daValue);
rp.DynAttrs = new DAMap();
rp.DynAttrs[daStoreName] = myStore;
SceneObjectGroup so = new SceneObjectGroup(rp);
// Need to add the object to the scene so that the request to get script state succeeds
@ -516,6 +546,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
UUID uuid = UUID.Zero;
string name = null;
UUID creatorId = UUID.Zero;
DAMap daMap = null;
while (xtr.Read() && xtr.Name != "SceneObjectPart")
{
@ -537,6 +568,10 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
creatorId = UUID.Parse(xtr.ReadElementString("Guid"));
xtr.ReadEndElement();
break;
case "DynAttrs":
daMap = new DAMap();
daMap.ReadXml(xtr);
break;
}
}
@ -549,6 +584,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
Assert.That(uuid, Is.EqualTo(rpUuid));
Assert.That(name, Is.EqualTo(rpName));
Assert.That(creatorId, Is.EqualTo(rpCreatorId));
Assert.NotNull(daMap);
Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString());
}
}
}

View File

@ -37,6 +37,7 @@ using System.Xml.Serialization;
using log4net;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes.Scripting;
@ -124,6 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Dynamic attributes can be created and deleted as required.
/// </summary>
public DAMap DynAttrs { get; set; }
/// <value>
/// Is this a root part?
/// </value>
@ -335,6 +341,7 @@ namespace OpenSim.Region.Framework.Scenes
m_particleSystem = Utils.EmptyBytes;
Rezzed = DateTime.UtcNow;
Description = String.Empty;
DynAttrs = new DAMap();
// Prims currently only contain a single folder (Contents). From looking at the Second Life protocol,
// this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
@ -1618,6 +1625,8 @@ namespace OpenSim.Region.Framework.Scenes
Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
dupe.Shape.ExtraParams = extraP;
dupe.DynAttrs.CopyFrom(DynAttrs);
if (userExposed)
{
/*

View File

@ -359,6 +359,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound);
m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume);
m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl);
m_SOPXmlProcessors.Add("DynAttrs", ProcessDynAttrs);
m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation);
m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
m_SOPXmlProcessors.Add("PayPrice0", ProcessPayPrice0);
@ -722,6 +723,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty);
}
private static void ProcessDynAttrs(SceneObjectPart obj, XmlTextReader reader)
{
obj.DynAttrs.ReadXml(reader);
}
private static void ProcessTextureAnimation(SceneObjectPart obj, XmlTextReader reader)
{
obj.TextureAnimation = Convert.FromBase64String(reader.ReadElementContentAsString("TextureAnimation", String.Empty));
@ -1235,6 +1241,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString());
if (sop.MediaUrl != null)
writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
if (sop.DynAttrs.Count > 0)
{
writer.WriteStartElement("DynAttrs");
sop.DynAttrs.WriteXml(writer);
writer.WriteEndElement();
}
WriteBytes(writer, "TextureAnimation", sop.TextureAnimation);
WriteBytes(writer, "ParticleSystem", sop.ParticleSystem);
writer.WriteElementString("PayPrice0", sop.PayPrice[0].ToString());

View File

@ -3023,6 +3023,7 @@
<Reference name="System.Drawing"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="OpenSim.Data"/>
<Reference name="OpenSim.Data.Null"/>
<Reference name="OpenSim.Framework"/>