libsecondlife:
* Added a SerializableDictionary class, implements a generic Dictionary<,> that can be serialized to xml * Added all possible values for ObjectFlags to allow serializing * Added a few initial xml serialization attributes to prim-related classes and structures * Created ToXml() and FromXml() functions for PrimObject TestClient: * ExportCommand exports a single prim to an xml file * quit and login commands now work when no avatars are logged in git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@662 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
@@ -78,21 +78,32 @@ namespace libsecondlife
|
||||
public delegate void TeleportCallback(string message, TeleportStatus status);
|
||||
|
||||
/// <summary>
|
||||
/// Name Conversion for Teleport Status flag/bit
|
||||
/// Current teleport status
|
||||
/// </summary>
|
||||
public enum TeleportStatus
|
||||
{
|
||||
/// <summary></summary>
|
||||
None,
|
||||
/// <summary></summary>
|
||||
Start,
|
||||
/// <summary></summary>
|
||||
Progress,
|
||||
/// <summary></summary>
|
||||
Failed,
|
||||
/// <summary></summary>
|
||||
Finished
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special commands used in Instant Messages
|
||||
/// </summary>
|
||||
public enum InstantMessageDialog
|
||||
{
|
||||
/// <summary></summary>
|
||||
RequestTeleport = 22,
|
||||
/// <summary></summary>
|
||||
AcceptTeleport = 23,
|
||||
/// <summary></summary>
|
||||
DenyTeleport = 24
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using System.Text;
|
||||
using libsecondlife.Packets;
|
||||
|
||||
@@ -151,19 +152,26 @@ namespace libsecondlife
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public enum PCode
|
||||
{
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Prim")]
|
||||
Prim = 9,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Avatar")]
|
||||
Avatar = 47,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Grass")]
|
||||
Grass = 95,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("NewTree")]
|
||||
NewTree = 111,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("ParticleSystem")]
|
||||
ParticleSystem = 143,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Tree")]
|
||||
Tree = 255
|
||||
}
|
||||
|
||||
@@ -774,7 +782,7 @@ namespace libsecondlife
|
||||
string name = Helpers.FieldToString(block.NameValue);
|
||||
|
||||
// New prim spotted
|
||||
PrimObject prim = new PrimObject(Client);
|
||||
PrimObject prim = new PrimObject();
|
||||
|
||||
prim.Name = name;
|
||||
|
||||
@@ -1035,7 +1043,7 @@ namespace libsecondlife
|
||||
foreach (ObjectUpdateCompressedPacket.ObjectDataBlock block in update.ObjectData)
|
||||
{
|
||||
int i = 0;
|
||||
prim = new PrimObject(Client);
|
||||
prim = new PrimObject();
|
||||
|
||||
prim.Flags = (ObjectFlags)block.UpdateFlags;
|
||||
|
||||
|
||||
@@ -1,37 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace libsecondlife
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ParticleSystem
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public enum SourcePattern : byte
|
||||
{
|
||||
/// <summary></summary>
|
||||
[XmlEnum("None")]
|
||||
None = 0,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Drop")]
|
||||
Drop = 0x01,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Explode")]
|
||||
Explode = 0x02,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Angle")]
|
||||
Angle = 0x04,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("AngleCone")]
|
||||
AngleCone = 0x08,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("AngleConeEmpty")]
|
||||
AngleConeEmpty = 0x10
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Flags]
|
||||
[Flags, Serializable]
|
||||
public enum ParticleFlags : ushort
|
||||
{
|
||||
/// <summary></summary>
|
||||
@@ -57,48 +65,63 @@ namespace libsecondlife
|
||||
}
|
||||
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public uint PartStartRGBA;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public uint PartEndRGBA;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float PartMaxAge;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float SrcMaxAge;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float SrcAngleBegin;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float SrcAngleEnd;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public int SrcBurstPartCount;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float SrcBurstRadius;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float SrcBurstRate;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float SrcBurstSpeedMin;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float SrcBurstSpeedMax;
|
||||
/// <summary>Unknown</summary>
|
||||
[XmlAttribute]
|
||||
public uint Version;
|
||||
/// <summary>Unknown</summary>
|
||||
[XmlAttribute]
|
||||
public uint StartTick;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public SourcePattern SrcPattern;
|
||||
/// <summary>Various options that describe the behavior of this system</summary>
|
||||
[XmlAttribute]
|
||||
public ParticleFlags PartFlags;
|
||||
/// <summary></summary>
|
||||
public LLVector3 PartStartScale = LLVector3.Zero;
|
||||
/// <summary></summary>
|
||||
public LLVector3 PartEndScale = LLVector3.Zero;
|
||||
/// <summary></summary>
|
||||
public float PartMaxAge;
|
||||
/// <summary></summary>
|
||||
public float SrcMaxAge;
|
||||
/// <summary></summary>
|
||||
public LLVector3 SrcAccel = LLVector3.Zero;
|
||||
/// <summary></summary>
|
||||
public float SrcAngleBegin;
|
||||
/// <summary></summary>
|
||||
public float SrcAngleEnd;
|
||||
/// <summary></summary>
|
||||
public int SrcBurstPartCount;
|
||||
/// <summary></summary>
|
||||
public float SrcBurstRadius;
|
||||
/// <summary></summary>
|
||||
public float SrcBurstRate;
|
||||
/// <summary></summary>
|
||||
public float SrcBurstSpeedMin;
|
||||
/// <summary></summary>
|
||||
public float SrcBurstSpeedMax;
|
||||
/// <summary></summary>
|
||||
public LLVector3 SrcOmega = LLVector3.Zero;
|
||||
/// <summary></summary>
|
||||
public LLUUID SrcTargetKey = LLUUID.Zero;
|
||||
/// <summary>Texture that will be applied to the particles</summary>
|
||||
public LLUUID SrcTexture = LLUUID.Zero;
|
||||
/// <summary></summary>
|
||||
public SourcePattern SrcPattern;
|
||||
/// <summary>Various options that describe the behavior of this system</summary>
|
||||
public ParticleFlags PartFlags;
|
||||
/// <summary>Unknown</summary>
|
||||
public uint Version;
|
||||
/// <summary>Unknown</summary>
|
||||
public uint StartTick;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -116,6 +139,10 @@ namespace libsecondlife
|
||||
FromBytes(data, pos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
byte[] bytes = new byte[0];
|
||||
@@ -145,7 +172,7 @@ namespace libsecondlife
|
||||
|
||||
SrcMaxAge = (data[i++] + (data[i++] << 8)) / 256.0f;
|
||||
|
||||
//Unknown
|
||||
// TODO: Unknown
|
||||
i += 2;
|
||||
|
||||
SrcAngleBegin = (data[i++] / 100.0f) * (float)Math.PI;
|
||||
@@ -176,7 +203,7 @@ namespace libsecondlife
|
||||
|
||||
PartMaxAge = (data[i++] + (data[i++] << 8)) / 256.0f;
|
||||
|
||||
//Unknown
|
||||
// TODO: Unknown
|
||||
i += 2;
|
||||
|
||||
PartStartRGBA = (uint)(data[i++] + (data[i++] << 8) +
|
||||
|
||||
@@ -26,13 +26,14 @@
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace libsecondlife
|
||||
{
|
||||
/// <summary>
|
||||
/// Primary parameters for primitives such as Physics Enabled or Phantom
|
||||
/// </summary>
|
||||
[Flags]
|
||||
[Flags, Serializable]
|
||||
public enum ObjectFlags
|
||||
{
|
||||
/// <summary>None of the primary flags are enabled</summary>
|
||||
@@ -41,16 +42,41 @@ namespace libsecondlife
|
||||
Physics = 1 << 0,
|
||||
/// <summary></summary>
|
||||
CreateSelected = 1 << 1,
|
||||
/// <summary></summary>
|
||||
Unknown1 = 1 << 2,
|
||||
Unknown2 = 1 << 3,
|
||||
Unknown3 = 1 << 4,
|
||||
Unknown4 = 1 << 5,
|
||||
Script = 1 << 6,
|
||||
/// <summary>Whether this object contains an active touch script</summary>
|
||||
Touch = 1 << 7,
|
||||
Unknown5 = 1 << 8,
|
||||
/// <summary>Whether this object can receive payments</summary>
|
||||
Money = 1 << 9,
|
||||
/// <summary>Whether this object is phantom (no collisions)</summary>
|
||||
Phantom = 1 << 10,
|
||||
Unknown6 = 1 << 11,
|
||||
Unknown7 = 1 << 12,
|
||||
Unknown8 = 1 << 13,
|
||||
Unknown9 = 1 << 14,
|
||||
Unknown10 = 1 << 15,
|
||||
Unknown11 = 1 << 16,
|
||||
Unknown12 = 1 << 17,
|
||||
Unknown13 = 1 << 18,
|
||||
Unknown14 = 1 << 19,
|
||||
Unknown15 = 1 << 20,
|
||||
Unknown16 = 1 << 21,
|
||||
Unknown17 = 1 << 22,
|
||||
Unknown18 = 1 << 23,
|
||||
Unknown19 = 1 << 24,
|
||||
Unknown20 = 1 << 25,
|
||||
Unknown21 = 1 << 26,
|
||||
Unknown22 = 1 << 27,
|
||||
Unknown23 = 1 << 28,
|
||||
Unknown24 = 1 << 29,
|
||||
/// <summary>Whether this object is temporary</summary>
|
||||
Temp = 1 << 30
|
||||
Temp = 1 << 30,
|
||||
Unknown25 = 1 << 31,
|
||||
Unknown26 = 1 << 32
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -58,132 +84,134 @@ namespace libsecondlife
|
||||
/// been added after the original ObjectFlags that has all eight bits
|
||||
/// reserved already
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public enum ExtraParamType : ushort
|
||||
{
|
||||
/// <summary>Whether this object has flexible parameters</summary>
|
||||
[XmlEnum("Flexible")]
|
||||
Flexible = 0x10,
|
||||
/// <summary>Whether this object has light parameters</summary>
|
||||
[XmlEnum("Light")]
|
||||
Light = 0x20
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class PrimObject
|
||||
[Serializable]
|
||||
public class PrimObject
|
||||
{
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public int PathTwistBegin = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float PathEnd = 0;
|
||||
/// <summary></summary>
|
||||
public float ProfileBegin = 0;
|
||||
[XmlAttribute]
|
||||
public float ProfileBegin = 0;
|
||||
/// <summary></summary>
|
||||
public float PathRadiusOffset = 0;
|
||||
[XmlAttribute]
|
||||
public float PathRadiusOffset = 0;
|
||||
/// <summary></summary>
|
||||
public float PathSkew = 0;
|
||||
[XmlAttribute]
|
||||
public float PathSkew = 0;
|
||||
/// <summary></summary>
|
||||
public LLVector3 Position = LLVector3.Zero;
|
||||
/// <summary> </summary>
|
||||
public ulong RegionHandle;
|
||||
[XmlAttribute]
|
||||
public uint ProfileCurve = 0;
|
||||
/// <summary></summary>
|
||||
public uint ProfileCurve = 0;
|
||||
[XmlAttribute]
|
||||
public float PathScaleX = 0;
|
||||
/// <summary></summary>
|
||||
public float PathScaleX = 0;
|
||||
[XmlAttribute]
|
||||
public float PathScaleY = 0;
|
||||
/// <summary></summary>
|
||||
public float PathScaleY = 0;
|
||||
[XmlAttribute]
|
||||
public uint LocalID = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public uint ParentID = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public uint Material = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public string Name = "";
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public string Description = "";
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float PathShearX = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float PathShearY = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float PathTaperX = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float PathTaperY = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float ProfileEnd = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float PathBegin = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public uint PathCurve = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public int PathTwist = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public uint ProfileHollow = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public float PathRevolutions = 0;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public uint State;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public string Text;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public ObjectManager.PCode PCode = ObjectManager.PCode.Prim;
|
||||
/// <summary></summary>
|
||||
[XmlAttribute]
|
||||
public ulong RegionHandle;
|
||||
/// <summary></summary>
|
||||
public LLUUID ID = LLUUID.Zero;
|
||||
/// <summary></summary>
|
||||
public uint LocalID = 0;
|
||||
/// <summary></summary>
|
||||
public uint ParentID = 0;
|
||||
/// <summary></summary>
|
||||
public LLUUID GroupID = LLUUID.Zero;
|
||||
/// <summary></summary>
|
||||
public uint Material = 0;
|
||||
/// <summary></summary>
|
||||
public string Name = "";
|
||||
/// <summary></summary>
|
||||
public string Description = "";
|
||||
/// <summary></summary>
|
||||
public float PathShearX = 0;
|
||||
/// <summary></summary>
|
||||
public float PathShearY = 0;
|
||||
/// <summary></summary>
|
||||
public float PathTaperX = 0;
|
||||
/// <summary></summary>
|
||||
public float PathTaperY = 0;
|
||||
/// <summary></summary>
|
||||
public float ProfileEnd = 0;
|
||||
/// <summary></summary>
|
||||
public float PathBegin = 0;
|
||||
/// <summary></summary>
|
||||
public uint PathCurve = 0;
|
||||
public LLVector3 Position = LLVector3.Zero;
|
||||
/// <summary></summary>
|
||||
public LLVector3 Scale = LLVector3.Zero;
|
||||
/// <summary></summary>
|
||||
public int PathTwist = 0;
|
||||
/// <summary></summary>
|
||||
public uint ProfileHollow = 0;
|
||||
/// <summary></summary>
|
||||
public float PathRevolutions = 0;
|
||||
/// <summary></summary>
|
||||
public LLQuaternion Rotation = LLQuaternion.Identity;
|
||||
/// <summary></summary>
|
||||
public uint State;
|
||||
/// <summary></summary>
|
||||
public string Text;
|
||||
/// <summary></summary>
|
||||
public ObjectManager.PCode PCode;
|
||||
/// <summary></summary>
|
||||
public ObjectFlags Flags;
|
||||
/// <summary></summary>
|
||||
public TextureEntry Textures;
|
||||
public TextureEntry Textures = new TextureEntry();
|
||||
/// <summary></summary>
|
||||
public TextureAnimation TextureAnim;
|
||||
public TextureAnimation TextureAnim = new TextureAnimation();
|
||||
/// <summary></summary>
|
||||
public PrimFlexibleData Flexible;
|
||||
public PrimFlexibleData Flexible = new PrimFlexibleData();
|
||||
/// <summary></summary>
|
||||
public PrimLightData Light;
|
||||
public PrimLightData Light = new PrimLightData();
|
||||
/// <summary></summary>
|
||||
public ParticleSystem ParticleSys;
|
||||
|
||||
private SecondLife Client;
|
||||
public ParticleSystem ParticleSys = new ParticleSystem();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public PrimObject(SecondLife client)
|
||||
public PrimObject()
|
||||
{
|
||||
Client = client;
|
||||
PCode = ObjectManager.PCode.Prim;
|
||||
Flexible = new PrimFlexibleData();
|
||||
Light = new PrimLightData();
|
||||
ParticleSys = new ParticleSystem();
|
||||
Textures = new TextureEntry();
|
||||
TextureAnim = new TextureAnimation();
|
||||
Flexible = new PrimFlexibleData();
|
||||
Light = new PrimLightData();
|
||||
ParticleSys = new ParticleSystem();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
public PrimObject(SecondLife client, LLUUID texture)
|
||||
{
|
||||
Client = client;
|
||||
PCode = ObjectManager.PCode.Prim;
|
||||
Textures = new TextureEntry();
|
||||
Textures.DefaultTexture.TextureID = texture;
|
||||
}
|
||||
|
||||
public GridRegion GridRegion
|
||||
{
|
||||
get { return Client.Grid.RegionsByHandle[RegionHandle]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -470,11 +498,24 @@ namespace libsecondlife
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public void ToXml(XmlWriter xmlWriter)
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(PrimObject));
|
||||
serializer.Serialize(xmlWriter, this);
|
||||
}
|
||||
|
||||
public static PrimObject FromXml(XmlReader xmlReader)
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(PrimObject));
|
||||
return (PrimObject)serializer.Deserialize(xmlReader);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PrimFlexibleData
|
||||
{
|
||||
/// <summary></summary>
|
||||
@@ -546,6 +587,7 @@ namespace libsecondlife
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PrimLightData
|
||||
{
|
||||
/// <summary></summary>
|
||||
|
||||
101
libsecondlife-cs/SerializableDictionary.cs
Normal file
101
libsecondlife-cs/SerializableDictionary.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Adapted from code by Paul Welter at
|
||||
* http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx
|
||||
*
|
||||
* - 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.
|
||||
* - Neither the name of the Second Life Reverse Engineering Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
[XmlRoot("dictionary")]
|
||||
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
|
||||
{
|
||||
#region IXmlSerializable Members
|
||||
|
||||
public System.Xml.Schema.XmlSchema GetSchema()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ReadXml(System.Xml.XmlReader reader)
|
||||
{
|
||||
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
|
||||
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
|
||||
|
||||
bool wasEmpty = reader.IsEmptyElement;
|
||||
reader.Read();
|
||||
|
||||
if (wasEmpty)
|
||||
return;
|
||||
|
||||
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
|
||||
{
|
||||
reader.ReadStartElement("item");
|
||||
|
||||
reader.ReadStartElement("key");
|
||||
TKey key = (TKey)keySerializer.Deserialize(reader);
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("value");
|
||||
TValue value = (TValue)valueSerializer.Deserialize(reader);
|
||||
reader.ReadEndElement();
|
||||
|
||||
this.Add(key, value);
|
||||
|
||||
reader.ReadEndElement();
|
||||
reader.MoveToContent();
|
||||
}
|
||||
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
|
||||
public void WriteXml(System.Xml.XmlWriter writer)
|
||||
{
|
||||
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
|
||||
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
|
||||
|
||||
foreach (TKey key in this.Keys)
|
||||
{
|
||||
writer.WriteStartElement("item");
|
||||
|
||||
writer.WriteStartElement("key");
|
||||
keySerializer.Serialize(writer, key);
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("value");
|
||||
TValue value = this[key];
|
||||
valueSerializer.Serialize(writer, value);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
|
||||
namespace libsecondlife
|
||||
@@ -36,23 +36,59 @@ namespace libsecondlife
|
||||
/// </summary>
|
||||
public enum Bumpiness
|
||||
{
|
||||
/// <summary></summary>
|
||||
[XmlEnum("None")]
|
||||
None = 0,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Brightness")]
|
||||
Brightness = 1,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Darkness")]
|
||||
Darkness = 2,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Woodgrain")]
|
||||
Woodgrain = 3,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Bark")]
|
||||
Bark = 4,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Bricks")]
|
||||
Bricks = 5,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Checker")]
|
||||
Checker = 6,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Concrete")]
|
||||
Concrete = 7,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Crustytile")]
|
||||
Crustytile = 8,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Cutstone")]
|
||||
Cutstone = 9,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Discs")]
|
||||
Discs = 10,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Gravel")]
|
||||
Gravel = 11,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Petridish")]
|
||||
Petridish = 12,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Siding")]
|
||||
Siding = 13,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Stonetile")]
|
||||
Stonetile = 14,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Stucco")]
|
||||
Stucco = 15,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Suction")]
|
||||
Suction = 16,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Weave")]
|
||||
Weave = 17
|
||||
}
|
||||
|
||||
@@ -61,9 +97,17 @@ namespace libsecondlife
|
||||
/// </summary>
|
||||
public enum Shininess
|
||||
{
|
||||
/// <summary></summary>
|
||||
[XmlEnum("None")]
|
||||
None = 0,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Low")]
|
||||
Low = 0x40,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Medium")]
|
||||
Medium = 0x80,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("High")]
|
||||
High = 0xC0
|
||||
}
|
||||
|
||||
@@ -72,33 +116,35 @@ namespace libsecondlife
|
||||
/// </summary>
|
||||
public enum Mapping
|
||||
{
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Default")]
|
||||
Default = 0,
|
||||
/// <summary></summary>
|
||||
[XmlEnum("Planar")]
|
||||
Planar = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TextureEntry
|
||||
{
|
||||
/// <summary></summary>
|
||||
public TextureEntryFace DefaultTexture;
|
||||
public TextureEntryFace DefaultTexture = null;
|
||||
/// <summary></summary>
|
||||
public Dictionary<uint, TextureEntryFace> FaceTextures;
|
||||
public SerializableDictionary<uint, TextureEntryFace> FaceTextures =
|
||||
new SerializableDictionary<uint,TextureEntryFace>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public TextureEntry()
|
||||
{
|
||||
FaceTextures = new Dictionary<uint, TextureEntryFace>();
|
||||
//DefaultTexture = new TextureEntryFace(null);
|
||||
DefaultTexture = null;
|
||||
}
|
||||
|
||||
public TextureEntry(LLUUID textureID)
|
||||
{
|
||||
FaceTextures = new Dictionary<uint, TextureEntryFace>();
|
||||
DefaultTexture = new TextureEntryFace(null);
|
||||
DefaultTexture.TextureID = textureID;
|
||||
}
|
||||
@@ -367,7 +413,7 @@ namespace libsecondlife
|
||||
{
|
||||
short value = (short)(byteArray[pos] | (byteArray[pos + 1] << 8));
|
||||
float QV = (float)value;
|
||||
float QF = upper / 32767.0F;
|
||||
float QF = upper / 32767.0f;
|
||||
return (float)(QV * QF);
|
||||
}
|
||||
|
||||
@@ -379,37 +425,37 @@ namespace libsecondlife
|
||||
|
||||
private short RepeatShort(float value)
|
||||
{
|
||||
return QuantizeSigned(value - 1.0F, 101.0F);
|
||||
return QuantizeSigned(value - 1.0f, 101.0f);
|
||||
}
|
||||
|
||||
private short OffsetShort(float value)
|
||||
{
|
||||
return QuantizeSigned(value, 1.0F);
|
||||
return QuantizeSigned(value, 1.0f);
|
||||
}
|
||||
|
||||
private short RotationShort(float value)
|
||||
{
|
||||
return QuantizeSigned(value, 359.995F);
|
||||
return QuantizeSigned(value, 359.995f);
|
||||
}
|
||||
|
||||
private float RepeatFloat(byte[] data, int pos)
|
||||
{
|
||||
return DequantizeSigned(data, pos, 101.0F) + 1.0F;
|
||||
return DequantizeSigned(data, pos, 101.0f) + 1.0f;
|
||||
}
|
||||
|
||||
private float OffsetFloat(byte[] data, int pos)
|
||||
{
|
||||
return DequantizeSigned(data, pos, 1.0F);
|
||||
return DequantizeSigned(data, pos, 1.0f);
|
||||
}
|
||||
|
||||
private float RotationFloat(byte[] data, int pos)
|
||||
{
|
||||
return DequantizeSigned(data, pos, 359.995F);
|
||||
return DequantizeSigned(data, pos, 359.995f);
|
||||
}
|
||||
|
||||
private void FromBytes(byte[] data, int pos, int length)
|
||||
{
|
||||
FaceTextures = new Dictionary<uint, TextureEntryFace>();
|
||||
FaceTextures = new SerializableDictionary<uint, TextureEntryFace>();
|
||||
DefaultTexture = new TextureEntryFace(null);
|
||||
|
||||
if (length <= 0)
|
||||
@@ -542,6 +588,7 @@ namespace libsecondlife
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TextureEntryFace
|
||||
{
|
||||
[Flags]
|
||||
@@ -560,6 +607,13 @@ namespace libsecondlife
|
||||
All = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public TextureEntryFace()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -757,10 +811,10 @@ namespace libsecondlife
|
||||
private byte _Flags2;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TextureAnimation
|
||||
{
|
||||
/// <summary></summary>
|
||||
@@ -830,4 +884,138 @@ namespace libsecondlife
|
||||
Rate = BitConverter.ToSingle(data, i + 8);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A serializable dictionary of TextureEntryFace objects, indexed by
|
||||
/// the prim face they are mapped to
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Faces : System.Collections.DictionaryBase, System.Xml.Serialization.IXmlSerializable
|
||||
{
|
||||
private const string NS = "http://www.libsecondlife.org/";
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public Faces()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual TextureEntryFace this[uint key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TextureEntryFace)this.Dictionary[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Dictionary[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Add(uint key, TextureEntryFace value)
|
||||
{
|
||||
this.Dictionary.Add(key, value);
|
||||
}
|
||||
|
||||
public virtual bool Contains(uint key)
|
||||
{
|
||||
return this.Dictionary.Contains(key);
|
||||
}
|
||||
|
||||
public virtual bool ContainsKey(uint key)
|
||||
{
|
||||
return this.Dictionary.Contains(key);
|
||||
}
|
||||
|
||||
public virtual bool ContainsValue(TextureEntryFace value)
|
||||
{
|
||||
foreach (TextureEntryFace item in this.Dictionary.Values)
|
||||
{
|
||||
if (item == value)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void Remove(uint key)
|
||||
{
|
||||
this.Dictionary.Remove(key);
|
||||
}
|
||||
|
||||
public virtual System.Collections.ICollection Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Dictionary.Keys;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual System.Collections.ICollection Values
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Dictionary.Values;
|
||||
}
|
||||
}
|
||||
|
||||
void System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter w)
|
||||
{
|
||||
System.Xml.Serialization.XmlSerializer keySer =
|
||||
new System.Xml.Serialization.XmlSerializer(typeof(uint));
|
||||
System.Xml.Serialization.XmlSerializer valueSer =
|
||||
new System.Xml.Serialization.XmlSerializer(typeof(TextureEntryFace));
|
||||
w.WriteStartElement("dictionary", NS);
|
||||
foreach (object key in Dictionary.Keys)
|
||||
{
|
||||
w.WriteStartElement("item", NS);
|
||||
|
||||
w.WriteStartElement("key", NS);
|
||||
keySer.Serialize(w, key);
|
||||
w.WriteEndElement();
|
||||
|
||||
w.WriteStartElement("value", NS);
|
||||
object value = Dictionary[key];
|
||||
valueSer.Serialize(w, value);
|
||||
w.WriteEndElement();
|
||||
|
||||
w.WriteEndElement();
|
||||
}
|
||||
w.WriteEndElement();
|
||||
}
|
||||
|
||||
void System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader r)
|
||||
{
|
||||
System.Xml.Serialization.XmlSerializer keySer =
|
||||
new System.Xml.Serialization.XmlSerializer(typeof(string));
|
||||
System.Xml.Serialization.XmlSerializer valueSer =
|
||||
new System.Xml.Serialization.XmlSerializer(typeof(TextureEntryFace));
|
||||
|
||||
r.Read();
|
||||
r.ReadStartElement("dictionary", NS);
|
||||
while (r.NodeType != System.Xml.XmlNodeType.EndElement)
|
||||
{
|
||||
r.ReadStartElement("item", NS);
|
||||
|
||||
r.ReadStartElement("key", NS);
|
||||
object key = keySer.Deserialize(r);
|
||||
r.ReadEndElement();
|
||||
|
||||
r.ReadStartElement("value", NS);
|
||||
object value = valueSer.Deserialize(r);
|
||||
r.ReadEndElement();
|
||||
|
||||
Dictionary.Add(key, value);
|
||||
|
||||
r.ReadEndElement();
|
||||
r.MoveToContent();
|
||||
}
|
||||
r.ReadEndElement();
|
||||
}
|
||||
|
||||
System.Xml.Schema.XmlSchema System.Xml.Serialization.IXmlSerializable.GetSchema()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace libsecondlife
|
||||
{
|
||||
@@ -33,6 +34,7 @@ namespace libsecondlife
|
||||
/// A 128-bit Universally Unique Identifier, used throughout the Second
|
||||
/// Life networking protocol
|
||||
/// </summary>
|
||||
[XmlRoot("uuid")]
|
||||
public class LLUUID
|
||||
{
|
||||
/// <summary>Get a byte array of the 16 raw bytes making up the UUID</summary>
|
||||
@@ -265,6 +267,7 @@ namespace libsecondlife
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[XmlRoot("vector3")]
|
||||
public class LLVector3
|
||||
{
|
||||
/// <summary></summary>
|
||||
@@ -451,6 +454,7 @@ namespace libsecondlife
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[XmlRoot("vector3d")]
|
||||
public class LLVector3d
|
||||
{
|
||||
/// <summary></summary>
|
||||
@@ -538,6 +542,7 @@ namespace libsecondlife
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[XmlRoot("vector4")]
|
||||
public class LLVector4
|
||||
{
|
||||
/// <summary></summary>
|
||||
@@ -618,6 +623,7 @@ namespace libsecondlife
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[XmlRoot("quaternion")]
|
||||
public class LLQuaternion
|
||||
{
|
||||
/// <summary></summary>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using libsecondlife;
|
||||
using libsecondlife.Packets;
|
||||
|
||||
namespace libsecondlife.TestClient
|
||||
{
|
||||
public class ExportCommand : Command
|
||||
{
|
||||
public ExportCommand()
|
||||
{
|
||||
Name = "export";
|
||||
Description = "Exports an object to an xml file. Usage: export uuid outputfile.xml";
|
||||
}
|
||||
|
||||
public override string Execute(SecondLife Client, string[] args, LLUUID fromAgentID)
|
||||
{
|
||||
if (args.Length != 2)
|
||||
return "Usage: export uuid outputfile.xml";
|
||||
|
||||
LLUUID id;
|
||||
string file = args[1];
|
||||
|
||||
try
|
||||
{
|
||||
id = new LLUUID(args[0]);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return "Usage: export uuid outputfile.xml";
|
||||
}
|
||||
|
||||
foreach (PrimObject prim in TestClient.Prims.Values)
|
||||
{
|
||||
if (prim.ID == id)
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlWriter writer = XmlWriter.Create(file);
|
||||
prim.ToXml(writer);
|
||||
writer.Close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
string ret = "Failed to write to " + file + ":" + e.ToString();
|
||||
if (ret.Length > 1000)
|
||||
{
|
||||
ret = ret.Remove(1000);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
return "Couldn't find UUID " + id.ToString() + " in the " + TestClient.Prims.Count +
|
||||
"objects currently indexed";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,33 +186,49 @@ Begin:
|
||||
|
||||
if (Commands.ContainsKey(firstToken))
|
||||
{
|
||||
foreach (SecondLife client in Clients.Values)
|
||||
if (firstToken == "login")
|
||||
{
|
||||
if (client.Network.Connected)
|
||||
// Special login case: Only call it once, and allow it with
|
||||
// no logged in avatars
|
||||
string[] args = new string[tokens.Length - 1];
|
||||
Array.Copy(tokens, 1, args, 0, args.Length);
|
||||
string response = Commands["login"].Execute(null, args, null);
|
||||
|
||||
if (response.Length > 0)
|
||||
{
|
||||
string[] args = new string[tokens.Length - 1];
|
||||
Array.Copy(tokens, 1, args, 0, args.Length);
|
||||
string response = Commands[firstToken].Execute(client, args, fromAgentID);
|
||||
|
||||
if (response.Length > 0)
|
||||
{
|
||||
if (fromAgentID != null && client.Network.Connected)
|
||||
client.Self.InstantMessage(fromAgentID, response, imSessionID);
|
||||
Console.WriteLine(response);
|
||||
}
|
||||
|
||||
if (firstToken == "login")
|
||||
{
|
||||
// Special login case: Only call it once
|
||||
break;
|
||||
}
|
||||
Console.WriteLine(response);
|
||||
}
|
||||
|
||||
if (avatars != Clients.Count)
|
||||
}
|
||||
else if (firstToken == "quit")
|
||||
{
|
||||
// Special quit case: This allows us to quit even when there
|
||||
// are zero avatars logged in
|
||||
Commands["quit"].Execute(null, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (SecondLife client in Clients.Values)
|
||||
{
|
||||
// The dictionary size changed, start over since the
|
||||
// foreach is shot
|
||||
goto Begin;
|
||||
if (client.Network.Connected)
|
||||
{
|
||||
string[] args = new string[tokens.Length - 1];
|
||||
Array.Copy(tokens, 1, args, 0, args.Length);
|
||||
string response = Commands[firstToken].Execute(client, args, fromAgentID);
|
||||
|
||||
if (response.Length > 0)
|
||||
{
|
||||
if (fromAgentID != null && client.Network.Connected)
|
||||
client.Self.InstantMessage(fromAgentID, response, imSessionID);
|
||||
Console.WriteLine(response);
|
||||
}
|
||||
}
|
||||
|
||||
if (avatars != Clients.Count)
|
||||
{
|
||||
// The dictionary size changed, start over since the
|
||||
// foreach is shot
|
||||
goto Begin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<Compile Include="Arguments.cs" />
|
||||
<Compile Include="Command.cs" />
|
||||
<Compile Include="Commands\BalanceCommand.cs" />
|
||||
<Compile Include="Commands\ExportCommand.cs" />
|
||||
<Compile Include="Commands\LoadCommand.cs" />
|
||||
<Compile Include="Commands\LoginCommand.cs" />
|
||||
<Compile Include="Commands\LogoutCommand.cs" />
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
<Compile Include="SecondLife.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SerializableDictionary.cs" />
|
||||
<Compile Include="Textures.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
Reference in New Issue
Block a user