Exemplo n.º 1
0
        public static PrimObject LoadPrim(XmlTextReader reader)
        {
            PrimObject obj = new PrimObject();
            obj.Shape = new PrimObject.ShapeBlock();
            obj.Inventory = new PrimObject.InventoryBlock();

            reader.ReadStartElement("SceneObjectPart");

            if (reader.Name == "AllowedDrop")
                obj.AllowedDrop = reader.ReadElementContentAsBoolean("AllowedDrop", String.Empty);
            else
                obj.AllowedDrop = true;

            obj.CreatorID = ReadUUID(reader, "CreatorID");
            obj.FolderID = ReadUUID(reader, "FolderID");
            obj.Inventory.Serial = reader.ReadElementContentAsInt("InventorySerial", String.Empty);

            #region Task Inventory

            List<PrimObject.InventoryBlock.ItemBlock> invItems = new List<PrimObject.InventoryBlock.ItemBlock>();

            reader.ReadStartElement("TaskInventory", String.Empty);
            while (reader.Name == "TaskInventoryItem")
            {
                PrimObject.InventoryBlock.ItemBlock item = new PrimObject.InventoryBlock.ItemBlock();
                reader.ReadStartElement("TaskInventoryItem", String.Empty);

                item.AssetID = ReadUUID(reader, "AssetID");
                item.PermsBase = (uint)reader.ReadElementContentAsInt("BasePermissions", String.Empty);
                item.CreationDate = Utils.UnixTimeToDateTime((uint)reader.ReadElementContentAsInt("CreationDate", String.Empty));
                item.CreatorID = ReadUUID(reader, "CreatorID");
                item.Description = reader.ReadElementContentAsString("Description", String.Empty);
                item.PermsEveryone = (uint)reader.ReadElementContentAsInt("EveryonePermissions", String.Empty);
                item.Flags = reader.ReadElementContentAsInt("Flags", String.Empty);
                item.GroupID = ReadUUID(reader, "GroupID");
                item.PermsGroup = (uint)reader.ReadElementContentAsInt("GroupPermissions", String.Empty);
                item.InvType = (InventoryType)reader.ReadElementContentAsInt("InvType", String.Empty);
                item.ID = ReadUUID(reader, "ItemID");
                UUID oldItemID = ReadUUID(reader, "OldItemID"); // TODO: Is this useful?
                item.LastOwnerID = ReadUUID(reader, "LastOwnerID");
                item.Name = reader.ReadElementContentAsString("Name", String.Empty);
                item.PermsNextOwner = (uint)reader.ReadElementContentAsInt("NextPermissions", String.Empty);
                item.OwnerID = ReadUUID(reader, "OwnerID");
                item.PermsOwner = (uint)reader.ReadElementContentAsInt("CurrentPermissions", String.Empty);
                UUID parentID = ReadUUID(reader, "ParentID");
                UUID parentPartID = ReadUUID(reader, "ParentPartID");
                item.PermsGranterID = ReadUUID(reader, "PermsGranter");
                item.PermsBase = (uint)reader.ReadElementContentAsInt("PermsMask", String.Empty);
                item.Type = (AssetType)reader.ReadElementContentAsInt("Type", String.Empty);

                reader.ReadEndElement();
                invItems.Add(item);
            }
            if (reader.NodeType == XmlNodeType.EndElement)
                reader.ReadEndElement();

            obj.Inventory.Items = invItems.ToArray();

            #endregion Task Inventory

            PrimFlags flags = (PrimFlags)reader.ReadElementContentAsInt("ObjectFlags", String.Empty);
            obj.UsePhysics = (flags & PrimFlags.Physics) != 0;
            obj.Phantom = (flags & PrimFlags.Phantom) != 0;
            obj.DieAtEdge = (flags & PrimFlags.DieAtEdge) != 0;
            obj.ReturnAtEdge = (flags & PrimFlags.ReturnAtEdge) != 0;
            obj.Temporary = (flags & PrimFlags.Temporary) != 0;
            obj.Sandbox = (flags & PrimFlags.Sandbox) != 0;

            obj.ID = ReadUUID(reader, "UUID");
            obj.LocalID = (uint)reader.ReadElementContentAsLong("LocalId", String.Empty);
            obj.Name = reader.ReadElementString("Name");
            obj.Material = reader.ReadElementContentAsInt("Material", String.Empty);

            if (reader.Name == "PassTouches")
                obj.PassTouches = reader.ReadElementContentAsBoolean("PassTouches", String.Empty);
            else
                obj.PassTouches = false;

            obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty);
            obj.RemoteScriptAccessPIN = reader.ReadElementContentAsInt("ScriptAccessPin", String.Empty);

            if (reader.Name == "PlaySoundSlavePrims")
                reader.ReadInnerXml();
            if (reader.Name == "LoopSoundSlavePrims")
                reader.ReadInnerXml();

            Vector3 groupPosition = ReadVector(reader, "GroupPosition");
            Vector3 offsetPosition = ReadVector(reader, "OffsetPosition");
            obj.Rotation = ReadQuaternion(reader, "RotationOffset");
            obj.Velocity = ReadVector(reader, "Velocity");
            if (reader.Name == "RotationalVelocity")
                ReadVector(reader, "RotationalVelocity");
            obj.AngularVelocity = ReadVector(reader, "AngularVelocity");
            obj.Acceleration = ReadVector(reader, "Acceleration");
            obj.Description = reader.ReadElementString("Description");
            reader.ReadStartElement("Color");
            if (reader.Name == "R")
            {
                obj.TextColor.R = reader.ReadElementContentAsFloat("R", String.Empty);
                obj.TextColor.G = reader.ReadElementContentAsFloat("G", String.Empty);
                obj.TextColor.B = reader.ReadElementContentAsFloat("B", String.Empty);
                obj.TextColor.A = reader.ReadElementContentAsFloat("A", String.Empty);
                reader.ReadEndElement();
            }
            obj.Text = reader.ReadElementString("Text", String.Empty);
            obj.SitName = reader.ReadElementString("SitName", String.Empty);
            obj.TouchName = reader.ReadElementString("TouchName", String.Empty);

            obj.LinkNumber = reader.ReadElementContentAsInt("LinkNum", String.Empty);
            obj.ClickAction = reader.ReadElementContentAsInt("ClickAction", String.Empty);

            reader.ReadStartElement("Shape");
            obj.Shape.ProfileCurve = reader.ReadElementContentAsInt("ProfileCurve", String.Empty);

            byte[] teData = Convert.FromBase64String(reader.ReadElementString("TextureEntry"));
            obj.Textures = new Primitive.TextureEntry(teData, 0, teData.Length);

            reader.ReadInnerXml(); // ExtraParams

            obj.Shape.PathBegin = Primitive.UnpackBeginCut((ushort)reader.ReadElementContentAsInt("PathBegin", String.Empty));
            obj.Shape.PathCurve = reader.ReadElementContentAsInt("PathCurve", String.Empty);
            obj.Shape.PathEnd = Primitive.UnpackEndCut((ushort)reader.ReadElementContentAsInt("PathEnd", String.Empty));
            obj.Shape.PathRadiusOffset = Primitive.UnpackPathTwist((sbyte)reader.ReadElementContentAsInt("PathRadiusOffset", String.Empty));
            obj.Shape.PathRevolutions = Primitive.UnpackPathRevolutions((byte)reader.ReadElementContentAsInt("PathRevolutions", String.Empty));
            obj.Shape.PathScaleX = Primitive.UnpackPathScale((byte)reader.ReadElementContentAsInt("PathScaleX", String.Empty));
            obj.Shape.PathScaleY = Primitive.UnpackPathScale((byte)reader.ReadElementContentAsInt("PathScaleY", String.Empty));
            obj.Shape.PathShearX = Primitive.UnpackPathShear((sbyte)reader.ReadElementContentAsInt("PathShearX", String.Empty));
            obj.Shape.PathShearY = Primitive.UnpackPathShear((sbyte)reader.ReadElementContentAsInt("PathShearY", String.Empty));
            obj.Shape.PathSkew = Primitive.UnpackPathTwist((sbyte)reader.ReadElementContentAsInt("PathSkew", String.Empty));
            obj.Shape.PathTaperX = Primitive.UnpackPathTaper((sbyte)reader.ReadElementContentAsInt("PathTaperX", String.Empty));
            obj.Shape.PathTaperY = Primitive.UnpackPathShear((sbyte)reader.ReadElementContentAsInt("PathTaperY", String.Empty));
            obj.Shape.PathTwist = Primitive.UnpackPathTwist((sbyte)reader.ReadElementContentAsInt("PathTwist", String.Empty));
            obj.Shape.PathTwistBegin = Primitive.UnpackPathTwist((sbyte)reader.ReadElementContentAsInt("PathTwistBegin", String.Empty));
            obj.PCode = reader.ReadElementContentAsInt("PCode", String.Empty);
            obj.Shape.ProfileBegin = Primitive.UnpackBeginCut((ushort)reader.ReadElementContentAsInt("ProfileBegin", String.Empty));
            obj.Shape.ProfileEnd = Primitive.UnpackEndCut((ushort)reader.ReadElementContentAsInt("ProfileEnd", String.Empty));
            obj.Shape.ProfileHollow = Primitive.UnpackProfileHollow((ushort)reader.ReadElementContentAsInt("ProfileHollow", String.Empty));
            obj.Scale = ReadVector(reader, "Scale");
            obj.State = (byte)reader.ReadElementContentAsInt("State", String.Empty);

            ProfileShape profileShape = (ProfileShape)Enum.Parse(typeof(ProfileShape), reader.ReadElementString("ProfileShape"));
            HoleType holeType = (HoleType)Enum.Parse(typeof(HoleType), reader.ReadElementString("HollowShape"));
            obj.Shape.ProfileCurve = (int)profileShape | (int)holeType;

            UUID sculptTexture = ReadUUID(reader, "SculptTexture");
            SculptType sculptType = (SculptType)reader.ReadElementContentAsInt("SculptType", String.Empty);
            if (sculptTexture != UUID.Zero)
            {
                obj.Sculpt = new PrimObject.SculptBlock();
                obj.Sculpt.Texture = sculptTexture;
                obj.Sculpt.Type = (int)sculptType;
            }

            PrimObject.FlexibleBlock flexible = new PrimObject.FlexibleBlock();
            PrimObject.LightBlock light = new PrimObject.LightBlock();

            reader.ReadInnerXml(); // SculptData

            flexible.Softness = reader.ReadElementContentAsInt("FlexiSoftness", String.Empty);
            flexible.Tension = reader.ReadElementContentAsFloat("FlexiTension", String.Empty);
            flexible.Drag = reader.ReadElementContentAsFloat("FlexiDrag", String.Empty);
            flexible.Gravity = reader.ReadElementContentAsFloat("FlexiGravity", String.Empty);
            flexible.Wind = reader.ReadElementContentAsFloat("FlexiWind", String.Empty);
            flexible.Force.X = reader.ReadElementContentAsFloat("FlexiForceX", String.Empty);
            flexible.Force.Y = reader.ReadElementContentAsFloat("FlexiForceY", String.Empty);
            flexible.Force.Z = reader.ReadElementContentAsFloat("FlexiForceZ", String.Empty);

            light.Color.R = reader.ReadElementContentAsFloat("LightColorR", String.Empty);
            light.Color.G = reader.ReadElementContentAsFloat("LightColorG", String.Empty);
            light.Color.B = reader.ReadElementContentAsFloat("LightColorB", String.Empty);
            light.Color.A = reader.ReadElementContentAsFloat("LightColorA", String.Empty);
            light.Radius = reader.ReadElementContentAsFloat("LightRadius", String.Empty);
            light.Cutoff = reader.ReadElementContentAsFloat("LightCutoff", String.Empty);
            light.Falloff = reader.ReadElementContentAsFloat("LightFalloff", String.Empty);
            light.Intensity = reader.ReadElementContentAsFloat("LightIntensity", String.Empty);

            bool hasFlexi = reader.ReadElementContentAsBoolean("FlexiEntry", String.Empty);
            bool hasLight = reader.ReadElementContentAsBoolean("LightEntry", String.Empty);
            reader.ReadInnerXml(); // SculptEntry

            if (hasFlexi)
                obj.Flexible = flexible;
            if (hasLight)
                obj.Light = light;

            reader.ReadEndElement();

            obj.Scale = ReadVector(reader, "Scale"); // Yes, again
            reader.ReadInnerXml(); // UpdateFlag

            reader.ReadInnerXml(); // SitTargetOrientation
            reader.ReadInnerXml(); // SitTargetPosition
            obj.SitOffset = ReadVector(reader, "SitTargetPositionLL");
            obj.SitRotation = ReadQuaternion(reader, "SitTargetOrientationLL");
            obj.ParentID = (uint)reader.ReadElementContentAsLong("ParentID", String.Empty);
            obj.CreationDate = Utils.UnixTimeToDateTime(reader.ReadElementContentAsInt("CreationDate", String.Empty));
            int category = reader.ReadElementContentAsInt("Category", String.Empty);
            obj.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty);
            obj.SaleType = reader.ReadElementContentAsInt("ObjectSaleType", String.Empty);
            int ownershipCost = reader.ReadElementContentAsInt("OwnershipCost", String.Empty);
            obj.GroupID = ReadUUID(reader, "GroupID");
            obj.OwnerID = ReadUUID(reader, "OwnerID");
            obj.LastOwnerID = ReadUUID(reader, "LastOwnerID");
            obj.PermsBase = (uint)reader.ReadElementContentAsInt("BaseMask", String.Empty);
            obj.PermsOwner = (uint)reader.ReadElementContentAsInt("OwnerMask", String.Empty);
            obj.PermsGroup = (uint)reader.ReadElementContentAsInt("GroupMask", String.Empty);
            obj.PermsEveryone = (uint)reader.ReadElementContentAsInt("EveryoneMask", String.Empty);
            obj.PermsNextOwner = (uint)reader.ReadElementContentAsInt("NextOwnerMask", String.Empty);

            reader.ReadInnerXml(); // Flags

            obj.CollisionSound = ReadUUID(reader, "CollisionSound");
            obj.CollisionSoundVolume = reader.ReadElementContentAsFloat("CollisionSoundVolume", String.Empty);

            reader.ReadEndElement();

            if (obj.ParentID == 0)
                obj.Position = groupPosition;
            else
                obj.Position = offsetPosition;

            return obj;
        }
Exemplo n.º 2
0
        public static PrimObject LoadPrim(XmlTextReader reader)
        {
            PrimObject obj = new PrimObject();
            obj.Shape = new PrimObject.ShapeBlock();
            obj.Inventory = new PrimObject.InventoryBlock();

            reader.ReadStartElement("SceneObjectPart");
            obj.CreatorIdentity = ReadUUID(reader, "CreatorID").ToString();
            //warning CS0219: The variable `folderID' is assigned but its value is never used
            //UUID folderID = ReadUUID(reader, "FolderID");
            obj.Inventory.Serial = reader.ReadElementContentAsInt("InventorySerial", String.Empty);
            
            // FIXME: Parse TaskInventory
            obj.Inventory.Items = new PrimObject.InventoryBlock.ItemBlock[0];
            reader.ReadInnerXml();

            PrimFlags flags = (PrimFlags)reader.ReadElementContentAsInt("ObjectFlags", String.Empty);
            obj.UsePhysics = (flags & PrimFlags.Physics) != 0;
            obj.Phantom = (flags & PrimFlags.Phantom) != 0;
            obj.DieAtEdge = (flags & PrimFlags.DieAtEdge) != 0;
            obj.ReturnAtEdge = (flags & PrimFlags.ReturnAtEdge) != 0;
            obj.Temporary = (flags & PrimFlags.Temporary) != 0;
            obj.Sandbox = (flags & PrimFlags.Sandbox) != 0;

            obj.ID = ReadUUID(reader, "UUID");
            obj.LocalID = (uint)reader.ReadElementContentAsLong("LocalId", String.Empty);
            obj.Name = reader.ReadElementString("Name");
            obj.Material = reader.ReadElementContentAsInt("Material", String.Empty);
            
            reader.ReadInnerXml(); // RegionHandle

            obj.RemoteScriptAccessPIN = reader.ReadElementContentAsInt("ScriptAccessPin", String.Empty);

            Vector3 groupPosition = ReadVector(reader, "GroupPosition");
            Vector3 offsetPosition = ReadVector(reader, "OffsetPosition");
            obj.Rotation = ReadQuaternion(reader, "RotationOffset");
            obj.Velocity = ReadVector(reader, "Velocity");
            //warning CS0219: The variable `rotationalVelocity' is assigned but its value is never used
            //Vector3 rotationalVelocity = ReadVector(reader, "RotationalVelocity");
            obj.AngularVelocity = ReadVector(reader, "AngularVelocity");
            obj.Acceleration = ReadVector(reader, "Acceleration");
            obj.Description = reader.ReadElementString("Description");
            reader.ReadStartElement("Color");
            if (reader.Name == "R")
            {
                obj.TextColor.R = reader.ReadElementContentAsFloat("R", String.Empty);
                obj.TextColor.G = reader.ReadElementContentAsFloat("G", String.Empty);
                obj.TextColor.B = reader.ReadElementContentAsFloat("B", String.Empty);
                obj.TextColor.A = reader.ReadElementContentAsFloat("A", String.Empty);
                reader.ReadEndElement();
            }
            obj.Text = reader.ReadElementString("Text", String.Empty);
            obj.SitName = reader.ReadElementString("SitName", String.Empty);
            obj.TouchName = reader.ReadElementString("TouchName", String.Empty);

            obj.LinkNumber = reader.ReadElementContentAsInt("LinkNum", String.Empty);
            obj.ClickAction = reader.ReadElementContentAsInt("ClickAction", String.Empty);
            
            reader.ReadStartElement("Shape");
            obj.Shape.ProfileCurve = reader.ReadElementContentAsInt("ProfileCurve", String.Empty);

            byte[] teData = Convert.FromBase64String(reader.ReadElementString("TextureEntry"));
            Primitive.TextureEntry te = new Primitive.TextureEntry(teData, 0, teData.Length);
            obj.Faces = FromTextureEntry(te);

            reader.ReadInnerXml(); // ExtraParams

            obj.Shape.PathBegin = Primitive.UnpackBeginCut((ushort)reader.ReadElementContentAsInt("PathBegin", String.Empty));
            obj.Shape.PathCurve = reader.ReadElementContentAsInt("PathCurve", String.Empty);
            obj.Shape.PathEnd = Primitive.UnpackEndCut((ushort)reader.ReadElementContentAsInt("PathEnd", String.Empty));
            obj.Shape.PathRadiusOffset = Primitive.UnpackPathTwist((sbyte)reader.ReadElementContentAsInt("PathRadiusOffset", String.Empty));
            obj.Shape.PathRevolutions = Primitive.UnpackPathRevolutions((byte)reader.ReadElementContentAsInt("PathRevolutions", String.Empty));
            obj.Shape.PathScaleX = Primitive.UnpackPathScale((byte)reader.ReadElementContentAsInt("PathScaleX", String.Empty));
            obj.Shape.PathScaleY = Primitive.UnpackPathScale((byte)reader.ReadElementContentAsInt("PathScaleY", String.Empty));
            obj.Shape.PathShearX = Primitive.UnpackPathShear((sbyte)reader.ReadElementContentAsInt("PathShearX", String.Empty));
            obj.Shape.PathShearY = Primitive.UnpackPathShear((sbyte)reader.ReadElementContentAsInt("PathShearY", String.Empty));
            obj.Shape.PathSkew = Primitive.UnpackPathTwist((sbyte)reader.ReadElementContentAsInt("PathSkew", String.Empty));
            obj.Shape.PathTaperX = Primitive.UnpackPathTaper((sbyte)reader.ReadElementContentAsInt("PathTaperX", String.Empty));
            obj.Shape.PathTaperY = Primitive.UnpackPathShear((sbyte)reader.ReadElementContentAsInt("PathTaperY", String.Empty));
            obj.Shape.PathTwist = Primitive.UnpackPathTwist((sbyte)reader.ReadElementContentAsInt("PathTwist", String.Empty));
            obj.Shape.PathTwistBegin = Primitive.UnpackPathTwist((sbyte)reader.ReadElementContentAsInt("PathTwistBegin", String.Empty));
            obj.PCode = reader.ReadElementContentAsInt("PCode", String.Empty);
            obj.Shape.ProfileBegin = Primitive.UnpackBeginCut((ushort)reader.ReadElementContentAsInt("ProfileBegin", String.Empty));
            obj.Shape.ProfileEnd = Primitive.UnpackEndCut((ushort)reader.ReadElementContentAsInt("ProfileEnd", String.Empty));
            obj.Shape.ProfileHollow = Primitive.UnpackProfileHollow((ushort)reader.ReadElementContentAsInt("ProfileHollow", String.Empty));
            obj.Scale = ReadVector(reader, "Scale");
            obj.State = (byte)reader.ReadElementContentAsInt("State", String.Empty);

            ProfileShape profileShape = (ProfileShape)Enum.Parse(typeof(ProfileShape), reader.ReadElementString("ProfileShape"));
            HoleType holeType = (HoleType)Enum.Parse(typeof(HoleType), reader.ReadElementString("HollowShape"));
            obj.Shape.ProfileCurve = (int)profileShape | (int)holeType;

            UUID sculptTexture = ReadUUID(reader, "SculptTexture");
            SculptType sculptType = (SculptType)reader.ReadElementContentAsInt("SculptType", String.Empty);
            if (sculptTexture != UUID.Zero)
            {
                obj.Sculpt = new PrimObject.SculptBlock();
                obj.Sculpt.Texture = sculptTexture;
                obj.Sculpt.Type = (int)sculptType;
            }

            PrimObject.FlexibleBlock flexible = new PrimObject.FlexibleBlock();
            PrimObject.LightBlock light = new PrimObject.LightBlock();

            reader.ReadInnerXml(); // SculptData

            flexible.Softness = reader.ReadElementContentAsInt("FlexiSoftness", String.Empty);
            flexible.Tension = reader.ReadElementContentAsFloat("FlexiTension", String.Empty);
            flexible.Drag = reader.ReadElementContentAsFloat("FlexiDrag", String.Empty);
            flexible.Gravity = reader.ReadElementContentAsFloat("FlexiGravity", String.Empty);
            flexible.Wind = reader.ReadElementContentAsFloat("FlexiWind", String.Empty);
            flexible.Force.X = reader.ReadElementContentAsFloat("FlexiForceX", String.Empty);
            flexible.Force.Y = reader.ReadElementContentAsFloat("FlexiForceY", String.Empty);
            flexible.Force.Z = reader.ReadElementContentAsFloat("FlexiForceZ", String.Empty);

            light.Color.R = reader.ReadElementContentAsFloat("LightColorR", String.Empty);
            light.Color.G = reader.ReadElementContentAsFloat("LightColorG", String.Empty);
            light.Color.B = reader.ReadElementContentAsFloat("LightColorB", String.Empty);
            light.Color.A = reader.ReadElementContentAsFloat("LightColorA", String.Empty);
            light.Radius = reader.ReadElementContentAsFloat("LightRadius", String.Empty);
            light.Cutoff = reader.ReadElementContentAsFloat("LightCutoff", String.Empty);
            light.Falloff = reader.ReadElementContentAsFloat("LightFalloff", String.Empty);
            light.Intensity = reader.ReadElementContentAsFloat("LightIntensity", String.Empty);

            reader.ReadInnerXml(); // FlexiTension
            reader.ReadInnerXml(); // FlexiDrag
            reader.ReadInnerXml(); // FlexiGravity
            reader.ReadInnerXml(); // FlexiWind
            reader.ReadInnerXml(); // FlexiForceX
            reader.ReadInnerXml(); // FlexiForceY
            reader.ReadInnerXml(); // FlexiForceZ
            reader.ReadInnerXml(); // LightColorR
            reader.ReadInnerXml(); // LightColorG
            reader.ReadInnerXml(); // LightColorB
            reader.ReadInnerXml(); // LightColorA
            reader.ReadInnerXml(); // LightRadius
            reader.ReadInnerXml(); // LightCutoff
            reader.ReadInnerXml(); // LightFalloff
            reader.ReadInnerXml(); // LightIntensity
            bool hasFlexi = reader.ReadElementContentAsBoolean("FlexiEntry", String.Empty);
            bool hasLight = reader.ReadElementContentAsBoolean("LightEntry", String.Empty);
            reader.ReadInnerXml(); // SculptEntry

            if (hasFlexi)
                obj.Flexible = flexible;
            if (hasLight)
                obj.Light = light;

            reader.ReadEndElement();

            obj.Scale = ReadVector(reader, "Scale"); // Yes, again
            reader.ReadInnerXml(); // UpdateFlag

            reader.ReadInnerXml(); // SitTargetOrientation
            reader.ReadInnerXml(); // SitTargetPosition
            obj.SitOffset = ReadVector(reader, "SitTargetPositionLL");
            obj.SitRotation = ReadQuaternion(reader, "SitTargetOrientationLL");
            obj.ParentID = (uint)reader.ReadElementContentAsLong("ParentID", String.Empty);
            obj.CreationDate = Utils.UnixTimeToDateTime(reader.ReadElementContentAsInt("CreationDate", String.Empty));
            //obj.Category = reader.ReadElementContentAsInt("Category", String.Empty);
            //warning CS0219: The variable `category' is assigned but its value is never used
            //int category = reader.ReadElementContentAsInt("Category", String.Empty);
            obj.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty);
            obj.SaleType = reader.ReadElementContentAsInt("ObjectSaleType", String.Empty);
            //warning CS0219: The variable `ownershipCost' is assigned but its value is never used
            //int ownershipCost = reader.ReadElementContentAsInt("OwnershipCost", String.Empty);
            obj.GroupIdentity = ReadUUID(reader, "GroupID").ToString();
            obj.OwnerIdentity = ReadUUID(reader, "OwnerID").ToString();
            obj.LastOwnerIdentity = ReadUUID(reader, "LastOwnerID").ToString();
            obj.PermsBase = (uint)reader.ReadElementContentAsInt("BaseMask", String.Empty);
            obj.PermsOwner = (uint)reader.ReadElementContentAsInt("OwnerMask", String.Empty);
            obj.PermsGroup = (uint)reader.ReadElementContentAsInt("GroupMask", String.Empty);
            obj.PermsEveryone = (uint)reader.ReadElementContentAsInt("EveryoneMask", String.Empty);
            obj.PermsNextOwner = (uint)reader.ReadElementContentAsInt("NextOwnerMask", String.Empty);

            reader.ReadInnerXml(); // Flags
            reader.ReadInnerXml(); // CollisionSound
            reader.ReadInnerXml(); // CollisionSoundVolume

            reader.ReadEndElement();

            if (obj.ParentID == 0)
                obj.Position = groupPosition;
            else
                obj.Position = offsetPosition;

            return obj;
        }