diff --git a/OpenMetaverse.StructuredData/StructuredData.cs b/OpenMetaverse.StructuredData/StructuredData.cs index 87d253cb..dc89e348 100644 --- a/OpenMetaverse.StructuredData/StructuredData.cs +++ b/OpenMetaverse.StructuredData/StructuredData.cs @@ -101,6 +101,7 @@ namespace OpenMetaverse.StructuredData public virtual Vector4 AsVector4() { return Vector4.Zero; } public virtual Quaternion AsQuaternion() { return Quaternion.Identity; } public virtual Color4 AsColor4() { return Color4.Black; } + public virtual OSD Copy() { return new OSD(); } public override string ToString() { return "undef"; } @@ -289,6 +290,20 @@ namespace OpenMetaverse.StructuredData else return Quaternion.Identity; } + else if (type == typeof(OSDArray)) + { + OSDArray newArray = new OSDArray(); + foreach (OSD o in (OSDArray)value) + newArray.Add(o); + return newArray; + } + else if (type == typeof(OSDMap)) + { + OSDMap newMap = new OSDMap(); + foreach (KeyValuePair o in (OSDMap)value) + newMap.Add(o); + return newMap; + } else { return null; @@ -418,6 +433,7 @@ namespace OpenMetaverse.StructuredData public override double AsReal() { return value ? 1d : 0d; } public override string AsString() { return value ? "1" : "0"; } public override byte[] AsBinary() { return value ? trueBinary : falseBinary; } + public override OSD Copy() { return new OSDBoolean(value); } public override string ToString() { return AsString(); } } @@ -444,6 +460,7 @@ namespace OpenMetaverse.StructuredData public override double AsReal() { return (double)value; } public override string AsString() { return value.ToString(); } public override byte[] AsBinary() { return Utils.IntToBytesBig(value); } + public override OSD Copy() { return new OSDInteger(value); } public override string ToString() { return AsString(); } } @@ -463,7 +480,8 @@ namespace OpenMetaverse.StructuredData } public override bool AsBoolean() { return (!Double.IsNaN(value) && value != 0d); } - + public override OSD Copy() { return new OSDReal(value); } + public override int AsInteger() { if (Double.IsNaN(value)) @@ -524,6 +542,8 @@ namespace OpenMetaverse.StructuredData public override OSDType Type { get { return OSDType.String; } } + public override OSD Copy() { return new OSDString(value); } + public OSDString(string value) { // Refuse to hold null pointers @@ -633,6 +653,7 @@ namespace OpenMetaverse.StructuredData this.value = value; } + public override OSD Copy() { return new OSDUUID(value); } public override bool AsBoolean() { return (value == UUID.Zero) ? false : true; } public override string AsString() { return value.ToString(); } public override UUID AsUUID() { return value; } @@ -690,6 +711,7 @@ namespace OpenMetaverse.StructuredData return Utils.DoubleToBytes(ts.TotalSeconds); } + public override OSD Copy() { return new OSDDate(value); } public override DateTime AsDate() { return value; } public override string ToString() { return AsString(); } } @@ -720,6 +742,7 @@ namespace OpenMetaverse.StructuredData return string.Empty; } + public override OSD Copy() { return new OSDUri(value); } public override Uri AsUri() { return value; } public override byte[] AsBinary() { return Encoding.UTF8.GetBytes(AsString()); } public override string ToString() { return AsString(); } @@ -783,6 +806,7 @@ namespace OpenMetaverse.StructuredData }; } + public override OSD Copy() { return new OSDBinary(value); } public override string AsString() { return Convert.ToBase64String(value); } public override byte[] AsBinary() { return value; } @@ -861,6 +885,11 @@ namespace OpenMetaverse.StructuredData return OSDParser.SerializeJsonString(this, true); } + public override OSD Copy() + { + return new OSDMap(new Dictionary(value)); + } + #region IDictionary Implementation public int Count { get { return value.Count; } } @@ -1086,6 +1115,11 @@ namespace OpenMetaverse.StructuredData return color; } + public override OSD Copy() + { + return new OSDArray(new List(value)); + } + public override bool AsBoolean() { return value.Count > 0; } public override string ToString() diff --git a/OpenMetaverse/BitPack.cs b/OpenMetaverse/BitPack.cs index c1f5ac67..1a0008c3 100644 --- a/OpenMetaverse/BitPack.cs +++ b/OpenMetaverse/BitPack.cs @@ -73,6 +73,8 @@ namespace OpenMetaverse { Data = data; bytePos = pos; + Data[bytePos] = 0; + bitPos = 0; } /// @@ -322,6 +324,53 @@ namespace OpenMetaverse private void PackBitArray(byte[] data, int totalCount) { + if (totalCount <= 0) + return; + + int curBytePos = 0; + int count = totalCount; + + if (bitPos == 0) + { + while (count >= 8) + { + Data[bytePos++] = data[curBytePos++]; + count -= 8; + } + if (count > 0) + Data[bytePos] = (byte)(data[curBytePos++] << 8 - count); + } + else + { + int nshift = 8 - bitPos; + ushort stmp; + while (count >= 8) + { + stmp = (ushort)(data[curBytePos++] << nshift); + Data[bytePos++] |= (byte)(stmp >> 8); + Data[bytePos] = (byte)stmp; + count -= 8; + } + if (count > 0) + { + stmp = (ushort)(data[curBytePos++] << (nshift + 8 - count)); + Data[bytePos] |= (byte)(stmp >> 8); + if (count >= nshift) + { + bytePos++; + if (count > nshift) + Data[bytePos] = (byte)stmp; + } + } + } + + bitPos = (bitPos + totalCount) & 0x07; + if (bitPos == 0 && bytePos < Data.Length) + Data[bytePos] = 0; + + + // if (weAreBigEndian) +/* int count = 0; int curBytePos = 0; int curBitPos = 0; @@ -364,6 +413,7 @@ namespace OpenMetaverse } } } + */ } private byte[] UnpackBitsArray(int totalCount) diff --git a/OpenMetaverse/_Packets_.cs b/OpenMetaverse/_Packets_.cs index 35d2c792..4c0c13a5 100644 --- a/OpenMetaverse/_Packets_.cs +++ b/OpenMetaverse/_Packets_.cs @@ -67247,19 +67247,65 @@ namespace OpenMetaverse.Packets } + /// + public sealed class SizeBlock : PacketBlock + { + public ushort SizeX; + public ushort SizeY; + + public override int Length + { + get + { + return 4; + } + } + + public SizeBlock() { } + public SizeBlock(byte[] bytes, ref int i) + { + FromBytes(bytes, ref i); + } + + public override void FromBytes(byte[] bytes, ref int i) + { + try + { + SizeX = (ushort)(bytes[i++] + (bytes[i++] << 8)); + SizeY = (ushort)(bytes[i++] + (bytes[i++] << 8)); + } + catch (Exception) + { + throw new MalformedDataException(); + } + } + + public override void ToBytes(byte[] bytes, ref int i) + { + bytes[i++] = (byte)(SizeX % 256); + bytes[i++] = (byte)((SizeX >> 8) % 256); + bytes[i++] = (byte)(SizeY % 256); + bytes[i++] = (byte)((SizeY >> 8) % 256); + } + + } + public override int Length { get { - int length = 11; + int length = 12; length += AgentData.Length; for (int j = 0; j < Data.Length; j++) length += Data[j].Length; + for (int j = 0; j < Size.Length; j++) + length += Size[j].Length; return length; } } public AgentDataBlock AgentData; public DataBlock[] Data; + public SizeBlock[] Size; public MapBlockReplyPacket() { @@ -67271,6 +67317,7 @@ namespace OpenMetaverse.Packets Header.Reliable = true; AgentData = new AgentDataBlock(); Data = null; + Size = null; } public MapBlockReplyPacket(byte[] bytes, ref int i) : this() @@ -67296,6 +67343,15 @@ namespace OpenMetaverse.Packets } for (int j = 0; j < count; j++) { Data[j].FromBytes(bytes, ref i); } + count = (int)bytes[i++]; + if (Size == null || Size.Length != -1) + { + Size = new SizeBlock[count]; + for (int j = 0; j < count; j++) + { Size[j] = new SizeBlock(); } + } + for (int j = 0; j < count; j++) + { Size[j].FromBytes(bytes, ref i); } } public MapBlockReplyPacket(Header head, byte[] bytes, ref int i): this() @@ -67316,6 +67372,15 @@ namespace OpenMetaverse.Packets } for (int j = 0; j < count; j++) { Data[j].FromBytes(bytes, ref i); } + count = (int)bytes[i++]; + if (Size == null || Size.Length != count) + { + Size = new SizeBlock[count]; + for (int j = 0; j < count; j++) + { Size[j] = new SizeBlock(); } + } + for (int j = 0; j < count; j++) + { Size[j].FromBytes(bytes, ref i); } } public override byte[] ToBytes() @@ -67324,6 +67389,8 @@ namespace OpenMetaverse.Packets length += AgentData.Length; length++; for (int j = 0; j < Data.Length; j++) { length += Data[j].Length; } + length++; + for (int j = 0; j < Size.Length; j++) { length += Size[j].Length; } if (Header.AckList != null && Header.AckList.Length > 0) { length += Header.AckList.Length * 4 + 1; } byte[] bytes = new byte[length]; int i = 0; @@ -67331,6 +67398,8 @@ namespace OpenMetaverse.Packets AgentData.ToBytes(bytes, ref i); bytes[i++] = (byte)Data.Length; for (int j = 0; j < Data.Length; j++) { Data[j].ToBytes(bytes, ref i); } + bytes[i++] = (byte)Size.Length; + for (int j = 0; j < Size.Length; j++) { Size[j].ToBytes(bytes, ref i); } if (Header.AckList != null && Header.AckList.Length > 0) { Header.AcksToBytes(bytes, ref i); } return bytes; } @@ -67353,18 +67422,22 @@ namespace OpenMetaverse.Packets byte[] fixedBytes = new byte[fixedLength]; Header.ToBytes(fixedBytes, ref i); AgentData.ToBytes(fixedBytes, ref i); - fixedLength += 1; + fixedLength += 2; int DataStart = 0; + int SizeStart = 0; do { int variableLength = 0; int DataCount = 0; + int SizeCount = 0; i = DataStart; - while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) { + while (fixedLength + variableLength + acksLength < Packet.MTU && i < Data.Length) + { int blockLength = Data[i].Length; - if (fixedLength + variableLength + blockLength + acksLength <= MTU) { + if (fixedLength + variableLength + blockLength + acksLength <= MTU) + { variableLength += blockLength; ++DataCount; } @@ -67372,6 +67445,19 @@ namespace OpenMetaverse.Packets ++i; } + i = SizeStart; + while (fixedLength + variableLength + acksLength < Packet.MTU && i < Size.Length) + { + int blockLength = Size[i].Length; + if (fixedLength + variableLength + blockLength + acksLength <= MTU) + { + variableLength += blockLength; + ++SizeCount; + } + else { break; } + ++i; + } + byte[] packet = new byte[fixedLength + variableLength + acksLength]; int length = fixedBytes.Length; Buffer.BlockCopy(fixedBytes, 0, packet, 0, length); @@ -67381,14 +67467,20 @@ namespace OpenMetaverse.Packets for (i = DataStart; i < DataStart + DataCount; i++) { Data[i].ToBytes(packet, ref length); } DataStart += DataCount; - if (acksLength > 0) { + packet[length++] = (byte)SizeCount; + for (i = SizeStart; i < SizeStart + SizeCount; i++) { Size[i].ToBytes(packet, ref length); } + SizeStart += SizeCount; + + if (acksLength > 0) + { Buffer.BlockCopy(ackBytes, 0, packet, length, acksLength); acksLength = 0; } packets.Add(packet); } while ( - DataStart < Data.Length); + DataStart < Data.Length || + SizeStart < Size.Length); return packets.ToArray(); } diff --git a/OpenMetaverseTypes/Matrix4.cs b/OpenMetaverseTypes/Matrix4.cs index cefc1020..e6891798 100644 --- a/OpenMetaverseTypes/Matrix4.cs +++ b/OpenMetaverseTypes/Matrix4.cs @@ -30,13 +30,44 @@ using System.Runtime.InteropServices; namespace OpenMetaverse { [Serializable] - [StructLayout(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Explicit)] public struct Matrix4 : IEquatable { - public float M11, M12, M13, M14; - public float M21, M22, M23, M24; - public float M31, M32, M33, M34; - public float M41, M42, M43, M44; + [FieldOffset(sizeof(float))] + public float M11; + [FieldOffset(sizeof(float))] + public float M12; + [FieldOffset(2 * sizeof(float))] + public float M13; + [FieldOffset(3 * sizeof(float))] + public float M14; + + [FieldOffset(4 * sizeof(float))] + public float M21; + [FieldOffset(5 * sizeof(float))] + public float M22; + [FieldOffset(6 * sizeof(float))] + public float M23; + [FieldOffset(7 * sizeof(float))] + public float M24; + + [FieldOffset(8 * sizeof(float))] + public float M31; + [FieldOffset(9 * sizeof(float))] + public float M32; + [FieldOffset(10 * sizeof(float))] + public float M33; + [FieldOffset(11 * sizeof(float))] + public float M34; + + [FieldOffset(12 * sizeof(float))] + public float M41; + [FieldOffset(13 * sizeof(float))] + public float M42; + [FieldOffset(14 * sizeof(float))] + public float M43; + [FieldOffset(15 * sizeof(float))] + public float M44; #region Properties diff --git a/OpenMetaverseTypes/Quaternion.cs b/OpenMetaverseTypes/Quaternion.cs index 955c0dc6..eda37cc5 100644 --- a/OpenMetaverseTypes/Quaternion.cs +++ b/OpenMetaverseTypes/Quaternion.cs @@ -31,17 +31,17 @@ using System.Globalization; namespace OpenMetaverse { [Serializable] - [StructLayout(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Explicit)] public struct Quaternion : IEquatable { /// X value - public float X; + [FieldOffset(0)] public float X; /// Y value - public float Y; + [FieldOffset(sizeof(float))] public float Y; /// Z value - public float Z; + [FieldOffset(2 * sizeof(float))] public float Z; /// W value - public float W; + [FieldOffset(3 * sizeof(float))] public float W; #region Constructors diff --git a/OpenMetaverseTypes/Vector2.cs b/OpenMetaverseTypes/Vector2.cs index 9fbeae4c..b980c7bb 100644 --- a/OpenMetaverseTypes/Vector2.cs +++ b/OpenMetaverseTypes/Vector2.cs @@ -34,12 +34,14 @@ namespace OpenMetaverse /// A two-dimensional vector with floating-point values /// [Serializable] - [StructLayout(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Explicit)] public struct Vector2 : IComparable, IEquatable { /// X value + [FieldOffset(0)] public float X; /// Y value + [FieldOffset(sizeof(float))] public float Y; #region Constructors diff --git a/OpenMetaverseTypes/Vector3.cs b/OpenMetaverseTypes/Vector3.cs index e702e693..a73b301d 100644 --- a/OpenMetaverseTypes/Vector3.cs +++ b/OpenMetaverseTypes/Vector3.cs @@ -34,14 +34,17 @@ namespace OpenMetaverse /// A three-dimensional vector with floating-point values /// [Serializable] - [StructLayout(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Explicit)] public struct Vector3 : IComparable, IEquatable { /// X value + [FieldOffset(0)] public float X; /// Y value + [FieldOffset(sizeof(float))] public float Y; /// Z value + [FieldOffset(2 * sizeof(float))] public float Z; #region Constructors diff --git a/bin/log4net.dll b/bin/log4net.dll index 974b4939..e4a05f16 100644 Binary files a/bin/log4net.dll and b/bin/log4net.dll differ diff --git a/data/message_template.msg b/data/message_template.msg index 2cb0a833..6bf56790 100644 --- a/data/message_template.msg +++ b/data/message_template.msg @@ -8684,6 +8684,11 @@ version 2.0 { Agents U8 } { MapImageID LLUUID } } + { + Size Variable + { SizeX U16 } + { SizeY U16 } + } } // viewer -> sim