diff --git a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerTypes.cs b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerTypes.cs index a3669479..73426f53 100644 --- a/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerTypes.cs +++ b/OpenMetaverse.Rendering.Meshmerizer/MeshmerizerTypes.cs @@ -1925,7 +1925,7 @@ namespace OpenMetaverse.Rendering for (int k = 0; k < extraParamCount; k++) { - ushort epType = Helpers.BytesToUInt16(data, i); + ushort epType = Utils.BytesToUInt16(data, i); i += 2; // uint paramLength = Helpers.BytesToUIntBig(data, i); @@ -2065,9 +2065,9 @@ namespace OpenMetaverse.Rendering _lightColorG = lColor.G; _lightColorB = lColor.B; - _lightRadius = Helpers.BytesToFloat(data, pos + 4); - _lightCutoff = Helpers.BytesToFloat(data, pos + 8); - _lightFalloff = Helpers.BytesToFloat(data, pos + 12); + _lightRadius = Utils.BytesToFloat(data, pos + 4); + _lightCutoff = Utils.BytesToFloat(data, pos + 8); + _lightFalloff = Utils.BytesToFloat(data, pos + 12); } else { @@ -2091,9 +2091,9 @@ namespace OpenMetaverse.Rendering Color4 tmpColor = new Color4(_lightColorR, _lightColorG, _lightColorB, _lightIntensity); tmpColor.GetBytes().CopyTo(data, 0); - Helpers.FloatToBytes(_lightRadius).CopyTo(data, 4); - Helpers.FloatToBytes(_lightCutoff).CopyTo(data, 8); - Helpers.FloatToBytes(_lightFalloff).CopyTo(data, 12); + Utils.FloatToBytes(_lightRadius).CopyTo(data, 4); + Utils.FloatToBytes(_lightCutoff).CopyTo(data, 8); + Utils.FloatToBytes(_lightFalloff).CopyTo(data, 12); return data; } diff --git a/OpenMetaverse/AgentManager.cs b/OpenMetaverse/AgentManager.cs index 642badb2..a47f7d45 100644 --- a/OpenMetaverse/AgentManager.cs +++ b/OpenMetaverse/AgentManager.cs @@ -1101,7 +1101,7 @@ namespace OpenMetaverse if (Client.Network.CurrentSim != null) { uint globalX, globalY; - Helpers.LongToUInts(Client.Network.CurrentSim.Handle, out globalX, out globalY); + Utils.LongToUInts(Client.Network.CurrentSim.Handle, out globalX, out globalY); Vector3 pos = SimPosition; return new Vector3d( @@ -1774,7 +1774,7 @@ namespace OpenMetaverse public void AutoPilotLocal(int localX, int localY, float z) { uint x, y; - Helpers.LongToUInts(Client.Network.CurrentSim.Handle, out x, out y); + Utils.LongToUInts(Client.Network.CurrentSim.Handle, out x, out y); AutoPilot((ulong)(x + localX), (ulong)(y + localY), z); } diff --git a/OpenMetaverse/AgentThrottle.cs b/OpenMetaverse/AgentThrottle.cs index e4c65e78..be890fbc 100644 --- a/OpenMetaverse/AgentThrottle.cs +++ b/OpenMetaverse/AgentThrottle.cs @@ -222,13 +222,13 @@ namespace OpenMetaverse byte[] data = new byte[7 * 4]; int i = 0; - Buffer.BlockCopy(Helpers.FloatToBytes(Resend), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Helpers.FloatToBytes(Land), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Helpers.FloatToBytes(Wind), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Helpers.FloatToBytes(Cloud), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Helpers.FloatToBytes(Task), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Helpers.FloatToBytes(Texture), 0, data, i, 4); i += 4; - Buffer.BlockCopy(Helpers.FloatToBytes(Asset), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes(Resend), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes(Land), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes(Wind), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes(Cloud), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes(Task), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes(Texture), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes(Asset), 0, data, i, 4); i += 4; return data; } diff --git a/OpenMetaverse/AppearanceManager.cs b/OpenMetaverse/AppearanceManager.cs index 322f68f7..75a6b093 100644 --- a/OpenMetaverse/AppearanceManager.cs +++ b/OpenMetaverse/AppearanceManager.cs @@ -852,7 +852,7 @@ namespace OpenMetaverse { if (data.Asset != null && data.Asset.Params.ContainsKey(vp.ParamID)) { - set.VisualParam[vpIndex].ParamValue = Helpers.FloatToByte(data.Asset.Params[vp.ParamID], vp.MinValue, vp.MaxValue); + set.VisualParam[vpIndex].ParamValue = Utils.FloatToByte(data.Asset.Params[vp.ParamID], vp.MinValue, vp.MaxValue); count++; switch (vp.ParamID) @@ -924,7 +924,7 @@ namespace OpenMetaverse // FIXME: Our hackish algorithm is making squished avatars. See // http://www.OpenMetaverse.org/wiki/Agent_Size for discussion of the correct algorithm - //float height = Helpers.ByteToFloat(set.VisualParam[33].ParamValue, VisualParams.Params[33].MinValue, + //float height = Utils.ByteToFloat(set.VisualParam[33].ParamValue, VisualParams.Params[33].MinValue, // VisualParams.Params[33].MaxValue); // Takes into account the Shoe Heel/Platform offsets but not the Head Size Offset. But seems to work. diff --git a/OpenMetaverse/AssetManager.cs b/OpenMetaverse/AssetManager.cs index da61d42d..602637f5 100644 --- a/OpenMetaverse/AssetManager.cs +++ b/OpenMetaverse/AssetManager.cs @@ -530,7 +530,7 @@ namespace OpenMetaverse byte[] paramField = new byte[20]; Array.Copy(assetID.GetBytes(), 0, paramField, 0, 16); - Array.Copy(Helpers.IntToBytes((int)type), 0, paramField, 16, 4); + Array.Copy(Utils.IntToBytes((int)type), 0, paramField, 16, 4); request.TransferInfo.Params = paramField; Client.Network.SendPacket(request, transfer.Simulator); @@ -618,7 +618,7 @@ namespace OpenMetaverse Buffer.BlockCopy(taskID.GetBytes(), 0, paramField, 48, 16); Buffer.BlockCopy(itemID.GetBytes(), 0, paramField, 64, 16); Buffer.BlockCopy(assetID.GetBytes(), 0, paramField, 80, 16); - Buffer.BlockCopy(Helpers.IntToBytes((int)type), 0, paramField, 96, 4); + Buffer.BlockCopy(Utils.IntToBytes((int)type), 0, paramField, 96, 4); request.TransferInfo.Params = paramField; Client.Network.SendPacket(request, transfer.Simulator); @@ -964,7 +964,7 @@ namespace OpenMetaverse // The first packet reserves the first four bytes of the data for the // total length of the asset and appends 1000 bytes of data after that send.DataPacket.Data = new byte[1004]; - Buffer.BlockCopy(Helpers.IntToBytes(upload.Size), 0, send.DataPacket.Data, 0, 4); + Buffer.BlockCopy(Utils.IntToBytes(upload.Size), 0, send.DataPacket.Data, 0, 4); Buffer.BlockCopy(upload.AssetData, 0, send.DataPacket.Data, 4, 1000); upload.Transferred += 1000; diff --git a/OpenMetaverse/AssetTypes.cs b/OpenMetaverse/AssetTypes.cs index b9b21242..d41c8a0d 100644 --- a/OpenMetaverse/AssetTypes.cs +++ b/OpenMetaverse/AssetTypes.cs @@ -465,11 +465,11 @@ namespace OpenMetaverse StringBuilder data = new StringBuilder("LLWearable version 22\n"); data.Append(Name); data.Append(NL); data.Append(NL); data.Append("\tpermissions 0\n\t{\n"); - data.Append("\t\tbase_mask\t"); data.Append(Helpers.UIntToHexString((uint)Permissions.BaseMask)); data.Append(NL); - data.Append("\t\towner_mask\t"); data.Append(Helpers.UIntToHexString((uint)Permissions.OwnerMask)); data.Append(NL); - data.Append("\t\tgroup_mask\t"); data.Append(Helpers.UIntToHexString((uint)Permissions.GroupMask)); data.Append(NL); - data.Append("\t\teveryone_mask\t"); data.Append(Helpers.UIntToHexString((uint)Permissions.EveryoneMask)); data.Append(NL); - data.Append("\t\tnext_owner_mask\t"); data.Append(Helpers.UIntToHexString((uint)Permissions.NextOwnerMask)); data.Append(NL); + data.Append("\t\tbase_mask\t"); data.Append(Utils.UIntToHexString((uint)Permissions.BaseMask)); data.Append(NL); + data.Append("\t\towner_mask\t"); data.Append(Utils.UIntToHexString((uint)Permissions.OwnerMask)); data.Append(NL); + data.Append("\t\tgroup_mask\t"); data.Append(Utils.UIntToHexString((uint)Permissions.GroupMask)); data.Append(NL); + data.Append("\t\teveryone_mask\t"); data.Append(Utils.UIntToHexString((uint)Permissions.EveryoneMask)); data.Append(NL); + data.Append("\t\tnext_owner_mask\t"); data.Append(Utils.UIntToHexString((uint)Permissions.NextOwnerMask)); data.Append(NL); data.Append("\t\tcreator_id\t"); data.Append(Creator.ToString()); data.Append(NL); data.Append("\t\towner_id\t"); data.Append(Owner.ToString()); data.Append(NL); data.Append("\t\tlast_owner_id\t"); data.Append(LastOwner.ToString()); data.Append(NL); diff --git a/OpenMetaverse/AvatarManager.cs b/OpenMetaverse/AvatarManager.cs index 7c03deef..1f2e2369 100644 --- a/OpenMetaverse/AvatarManager.cs +++ b/OpenMetaverse/AvatarManager.cs @@ -428,7 +428,7 @@ namespace OpenMetaverse properties.FirstLifeText = Utils.BytesToString(reply.PropertiesData.FLAboutText); properties.BornOn = Utils.BytesToString(reply.PropertiesData.BornOn); //properties.CharterMember = Utils.BytesToString(reply.PropertiesData.CharterMember); - uint charter = Helpers.BytesToUInt(reply.PropertiesData.CharterMember); + uint charter = Utils.BytesToUInt(reply.PropertiesData.CharterMember); if ( charter == 0 ) { properties.CharterMember = "Resident"; } else if ( charter == 2 ) { diff --git a/OpenMetaverse/CapsToPacket.cs b/OpenMetaverse/CapsToPacket.cs index 632fbf63..e018ff9c 100644 --- a/OpenMetaverse/CapsToPacket.cs +++ b/OpenMetaverse/CapsToPacket.cs @@ -174,14 +174,14 @@ namespace OpenMetaverse.Packets { // ulongs come in as a byte array, convert it manually here byte[] bytes = blockData[field.Name].AsBinary(); - ulong value = Helpers.BytesToUInt64(bytes); + ulong value = Utils.BytesToUInt64(bytes); field.SetValue(block, value); } else if (fieldType == typeof(uint)) { // uints come in as a byte array, convert it manually here byte[] bytes = blockData[field.Name].AsBinary(); - uint value = Helpers.BytesToUInt(bytes); + uint value = Utils.BytesToUInt(bytes); field.SetValue(block, value); } else if (fieldType == typeof(ushort)) diff --git a/OpenMetaverse/DirectoryManager.cs b/OpenMetaverse/DirectoryManager.cs index 6598cc7f..b864386f 100644 --- a/OpenMetaverse/DirectoryManager.cs +++ b/OpenMetaverse/DirectoryManager.cs @@ -824,7 +824,7 @@ namespace OpenMetaverse evinfo.Name = Utils.BytesToString(eventReply.EventData.Name); evinfo.Desc = Utils.BytesToString(eventReply.EventData.Desc); evinfo.Amount = eventReply.EventData.Amount; - evinfo.Category = (EventCategories)Helpers.BytesToUInt(eventReply.EventData.Category); + evinfo.Category = (EventCategories)Utils.BytesToUInt(eventReply.EventData.Category); evinfo.Cover = eventReply.EventData.Cover; evinfo.Creator = (UUID)Utils.BytesToString(eventReply.EventData.Creator); evinfo.Date = Utils.BytesToString(eventReply.EventData.Date); diff --git a/OpenMetaverse/EstateTools.cs b/OpenMetaverse/EstateTools.cs index 01c4a908..727e5733 100644 --- a/OpenMetaverse/EstateTools.cs +++ b/OpenMetaverse/EstateTools.cs @@ -232,7 +232,7 @@ namespace OpenMetaverse { string estateName = Utils.BytesToString(message.ParamList[0].Parameter); UUID estateOwner = new UUID(Utils.BytesToString(message.ParamList[1].Parameter)); - estateID = Helpers.BytesToUInt(message.ParamList[2].Parameter); + estateID = Utils.BytesToUInt(message.ParamList[2].Parameter); /* foreach (EstateOwnerMessagePacket.ParamListBlock param in message.ParamList) { @@ -240,7 +240,7 @@ namespace OpenMetaverse } */ bool denyNoPaymentInfo; - if (Helpers.BytesToUInt(message.ParamList[8].Parameter) == 0) denyNoPaymentInfo = true; + if (Utils.BytesToUInt(message.ParamList[8].Parameter) == 0) denyNoPaymentInfo = true; else denyNoPaymentInfo = false; if (OnGetEstateUpdateInfo != null) @@ -256,16 +256,16 @@ namespace OpenMetaverse else if (method == "setaccess") { int count; - estateID = Helpers.BytesToUInt(message.ParamList[0].Parameter); + estateID = Utils.BytesToUInt(message.ParamList[0].Parameter); if (message.ParamList.Length > 1) { - EstateAccessReplyDelta accessType = (EstateAccessReplyDelta)Helpers.BytesToUInt(message.ParamList[1].Parameter); + EstateAccessReplyDelta accessType = (EstateAccessReplyDelta)Utils.BytesToUInt(message.ParamList[1].Parameter); switch (accessType) { case EstateAccessReplyDelta.EstateManagers: if (OnGetEstateManagers != null) { - count = (int)Helpers.BytesToUInt(message.ParamList[3].Parameter); + count = (int)Utils.BytesToUInt(message.ParamList[3].Parameter); List managers = new List(); if (message.ParamList.Length > 5) { @@ -286,7 +286,7 @@ namespace OpenMetaverse case EstateAccessReplyDelta.EstateBans: if (OnGetEstateBans != null) { - count = (int)Helpers.BytesToUInt(message.ParamList[4].Parameter); + count = (int)Utils.BytesToUInt(message.ParamList[4].Parameter); List bannedUsers = new List(); if (message.ParamList.Length > 5) { @@ -307,7 +307,7 @@ namespace OpenMetaverse case EstateAccessReplyDelta.AllowedUsers: if (OnGetAllowedUsers != null) { - count = (int)Helpers.BytesToUInt(message.ParamList[2].Parameter); + count = (int)Utils.BytesToUInt(message.ParamList[2].Parameter); List allowedUsers = new List(); if (message.ParamList.Length > 5) { @@ -328,7 +328,7 @@ namespace OpenMetaverse case EstateAccessReplyDelta.AllowedGroups: if (OnGetAllowedGroups != null) { - count = (int)Helpers.BytesToUInt(message.ParamList[3].Parameter); + count = (int)Utils.BytesToUInt(message.ParamList[3].Parameter); List allowedGroups = new List(); if (message.ParamList.Length > 5) { @@ -351,7 +351,7 @@ namespace OpenMetaverse { if (OnGetEstateManagers != null) { - count = (int)Helpers.BytesToUInt(message.ParamList[5].Parameter); + count = (int)Utils.BytesToUInt(message.ParamList[5].Parameter); List managers = new List(); for (int i = 5; i < message.ParamList.Length; i++) diff --git a/OpenMetaverse/GridManager.cs b/OpenMetaverse/GridManager.cs index b5f38c17..f8c2d3aa 100644 --- a/OpenMetaverse/GridManager.cs +++ b/OpenMetaverse/GridManager.cs @@ -185,7 +185,7 @@ namespace OpenMetaverse public ulong RegionHandle { - get { return Helpers.UIntsToLong((uint)(GlobalX - (GlobalX % 256)), (uint)(GlobalY - (GlobalY % 256))); } + get { return Utils.UIntsToLong((uint)(GlobalX - (GlobalX % 256)), (uint)(GlobalY - (GlobalY % 256))); } } } @@ -529,7 +529,7 @@ namespace OpenMetaverse region.Agents = block.Agents; region.Access = (SimAccess)block.Access; region.MapImageID = block.MapImageID; - region.RegionHandle = Helpers.UIntsToLong((uint)(region.X * 256), (uint)(region.Y * 256)); + region.RegionHandle = Utils.UIntsToLong((uint)(region.X * 256), (uint)(region.Y * 256)); lock (Regions) { diff --git a/OpenMetaverse/Helpers.cs b/OpenMetaverse/Helpers.cs index be361046..7de1973b 100644 --- a/OpenMetaverse/Helpers.cs +++ b/OpenMetaverse/Helpers.cs @@ -136,28 +136,6 @@ namespace OpenMetaverse return (float)bytes[pos] / 255.0f; } - /// - /// Converts an unsigned integer to a hexadecimal string - /// - /// An unsigned integer to convert to a string - /// A hexadecimal string 10 characters long - /// 0x7fffffff - public static string UIntToHexString(uint i) - { - return string.Format("{0:x8}", i); - } - - /// - /// Packs to 32-bit unsigned integers in to a 64-bit unsigned integer - /// - /// The left-hand (or X) value - /// The right-hand (or Y) value - /// A 64-bit integer containing the two 32-bit input values - public static ulong UIntsToLong(uint a, uint b) - { - return ((ulong)a << 32) | (ulong)b; - } - /// /// Given an X/Y location in absolute (grid-relative) terms, a region /// handle is returned along with the local X/Y location in that region @@ -177,216 +155,9 @@ namespace OpenMetaverse uint y = ((uint)globalY / 256) * 256; localX = globalX - (float)x; localY = globalY - (float)y; - return UIntsToLong(x, y); + return Utils.UIntsToLong(x, y); } - /// - /// Unpacks two 32-bit unsigned integers from a 64-bit unsigned integer - /// - /// The 64-bit input integer - /// The left-hand (or X) output value - /// The right-hand (or Y) output value - public static void LongToUInts(ulong a, out uint b, out uint c) - { - b = (uint)(a >> 32); - c = (uint)(a & 0x00000000FFFFFFFF); - } - - /// - /// Convert an integer to a byte array in little endian format - /// - /// The integer to convert - /// A four byte little endian array - public static byte[] IntToBytes(int x) - { - byte[] bytes = new byte[4]; - - bytes[0]= (byte)(x % 256); - bytes[1] = (byte)((x >> 8) % 256); - bytes[2] = (byte)((x >> 16) % 256); - bytes[3] = (byte)((x >> 24) % 256); - - return bytes; - } - - /// - /// Convert the first four bytes starting at the given position in - /// little endian ordering to a signed integer - /// - /// Byte array containing the int - /// Position to start reading the int from - /// A signed integer, will be zero if an int can't be read - /// at the given position - public static int BytesToInt(byte[] bytes, int pos) - { - if (bytes.Length < pos + 4) return 0; - return (int)(bytes[pos + 0] + (bytes[pos + 1] << 8) + (bytes[pos + 2] << 16) + (bytes[pos + 3] << 24)); - } - - /// - /// Convert the first four bytes of the given array in little endian - /// ordering to a signed integer - /// - /// An array four bytes or longer - /// A signed integer, will be zero if the array contains - /// less than four bytes - public static int BytesToInt(byte[] bytes) - { - return BytesToInt(bytes, 0); - } - - /// - /// Convert the first two bytes starting at the given position in - /// little endian ordering to an unsigned short - /// - /// Byte array containing the ushort - /// Position to start reading the ushort from - /// An unsigned short, will be zero if a ushort can't be read - /// at the given position - public static ushort BytesToUInt16(byte[] bytes, int pos) - { - if (bytes.Length <= pos + 1) return 0; - return (ushort)(bytes[pos] + (bytes[pos + 1] << 8)); - } - - /// - /// Convert the first four bytes starting at the given position in - /// little endian ordering to an unsigned integer - /// - /// Byte array containing the uint - /// Position to start reading the uint from - /// An unsigned integer, will be zero if a uint can't be read - /// at the given position - public static uint BytesToUInt(byte[] bytes, int pos) - { - if (bytes.Length < pos + 4) return 0; - return (uint)(bytes[pos + 0] + (bytes[pos + 1] << 8) + (bytes[pos + 2] << 16) + (bytes[pos + 3] << 24)); - } - - /// - /// Convert the first four bytes of the given array in little endian - /// ordering to an unsigned integer - /// - /// An array four bytes or longer - /// An unsigned integer, will be zero if the array contains - /// less than four bytes - public static uint BytesToUInt(byte[] bytes) - { - return BytesToUInt(bytes, 0); - } - - /// - /// Convert the first eight bytes of the given array in little endian - /// ordering to an unsigned 64-bit integer - /// - /// An array eight bytes or longer - /// An unsigned 64-bit integer, will be zero if the array - /// contains less than eight bytes - public static ulong BytesToUInt64(byte[] bytes) - { - if (bytes.Length < 8) return 0; - return (ulong) - ((ulong)bytes[0] + - ((ulong)bytes[1] << 8) + - ((ulong)bytes[2] << 16) + - ((ulong)bytes[3] << 24) + - ((ulong)bytes[4] << 32) + - ((ulong)bytes[5] << 40) + - ((ulong)bytes[6] << 48) + - ((ulong)bytes[7] << 56)); - } - - /// - /// Convert four bytes in little endian ordering to a floating point - /// value - /// - /// Byte array containing a little ending floating - /// point value - /// Starting position of the floating point value in - /// the byte array - /// Single precision value - public static float BytesToFloat(byte[] bytes, int pos) - { - if (!BitConverter.IsLittleEndian) - { - byte[] newBytes = new byte[4]; - Buffer.BlockCopy(bytes, pos, newBytes, 0, 4); - Array.Reverse(newBytes, pos, 4); - return BitConverter.ToSingle(newBytes, 0); - } - else - { - return BitConverter.ToSingle(bytes, pos); - } - } - - /// - /// Convert a floating point value to four bytes in little endian - /// ordering - /// - /// A floating point value - /// A four byte array containing the value in little endian - /// ordering - public static byte[] FloatToBytes(float value) - { - byte[] bytes = BitConverter.GetBytes(value); - if (!BitConverter.IsLittleEndian) - Array.Reverse(bytes); - return bytes; - } - - public static double BytesToDouble(byte[] bytes, int pos) - { - if (!BitConverter.IsLittleEndian) - { - byte[] newBytes = new byte[8]; - Buffer.BlockCopy(bytes, pos, newBytes, 0, 8); - Array.Reverse(newBytes, pos, 8); - return BitConverter.ToDouble(newBytes, 0); - } - else - { - return BitConverter.ToDouble(bytes, pos); - } - } - - public static byte[] DoubleToBytes(double value) - { - byte[] bytes = BitConverter.GetBytes(value); - if (!BitConverter.IsLittleEndian) - Array.Reverse(bytes); - return bytes; - } - - public static byte[] IntToBytes(int value) - { - byte[] bytes = new byte[4]; - bytes[0] = (byte)(value % 256); - bytes[1] = (byte)((value >> 8) % 256); - bytes[2] = (byte)((value >> 16) % 256); - bytes[3] = (byte)((value >> 24) % 256); - return bytes; - } - - public static byte[] UInt16ToBytes(int value) - { - byte[] bytes = new byte[2]; - bytes[0] = (byte)(value % 256); - bytes[1] = (byte)((value >> 8) % 256); - return bytes; - } - - public static byte[] UIntToBytes(uint value) - { - byte[] bytes = new byte[4]; - bytes[0] = (byte)(value % 256); - bytes[1] = (byte)((value >> 8) % 256); - bytes[2] = (byte)((value >> 16) % 256); - bytes[3] = (byte)((value >> 24) % 256); - return bytes; - } - - /// /// Converts a floating point number to a terse string format used for /// transmitting numbers in wearable asset files @@ -414,99 +185,6 @@ namespace OpenMetaverse return s; } - /// - /// Convert a float value to a byte given a minimum and maximum range - /// - /// Value to convert to a byte - /// Minimum value range - /// Maximum value range - /// A single byte representing the original float value - public static byte FloatToByte(float val, float lower, float upper) - { - val = Utils.Clamp(val, lower, upper); - // Normalize the value - val -= lower; - val /= (upper - lower); - - return (byte)Math.Floor(val * (float)byte.MaxValue); - } - - /// - /// Convert a byte to a float value given a minimum and maximum range - /// - /// Byte array to get the byte from - /// Position in the byte array the desired byte is at - /// Minimum value range - /// Maximum value range - /// A float value inclusively between lower and upper - public static float ByteToFloat(byte[] bytes, int pos, float lower, float upper) - { - if (bytes.Length <= pos) return 0; - return ByteToFloat(bytes[pos], lower, upper); - } - - /// - /// Convert a byte to a float value given a minimum and maximum range - /// - /// Byte to convert to a float value - /// Minimum value range - /// Maximum value range - /// A float value inclusively between lower and upper - public static float ByteToFloat(byte val, float lower, float upper) - { - const float ONE_OVER_BYTEMAX = 1.0f / (float)byte.MaxValue; - - float fval = (float)val * ONE_OVER_BYTEMAX; - float delta = (upper - lower); - fval *= delta; - fval += lower; - - // Test for values very close to zero - float error = delta * ONE_OVER_BYTEMAX; - if (Math.Abs(fval) < error) - fval = 0.0f; - - return fval; - } - - /// - /// - /// - /// - /// - /// - /// - /// - public static float UInt16ToFloat(byte[] bytes, int pos, float lower, float upper) - { - ushort val = BytesToUInt16(bytes, pos); - return UInt16ToFloat(val, lower, upper); - } - - /// - /// - /// - /// - /// - /// - /// - public static float UInt16ToFloat(ushort val, float lower, float upper) - { - const float ONE_OVER_U16_MAX = 1.0f / 65535.0f; - - float fval = (float)val * ONE_OVER_U16_MAX; - float delta = upper - lower; - fval *= delta; - fval += lower; - - // Make sure zeroes come through as zero - float maxError = delta * ONE_OVER_U16_MAX; - if (Math.Abs(fval) < maxError) - fval = 0.0f; - - return fval; - } - /// /// Convert a variable length field (byte array) to a string /// diff --git a/OpenMetaverse/LLSD/LLSD.cs b/OpenMetaverse/LLSD/LLSD.cs index 949b2d18..7dfd44c5 100644 --- a/OpenMetaverse/LLSD/LLSD.cs +++ b/OpenMetaverse/LLSD/LLSD.cs @@ -94,6 +94,7 @@ namespace OpenMetaverse.StructuredData public static LLSD FromInteger(ushort value) { return new LLSDInteger((int)value); } public static LLSD FromInteger(sbyte value) { return new LLSDInteger((int)value); } public static LLSD FromInteger(byte value) { return new LLSDInteger((int)value); } + public static LLSD FromUInteger(uint value) { return new LLSDBinary(value); } public static LLSD FromReal(double value) { return new LLSDReal(value); } public static LLSD FromReal(float value) { return new LLSDReal((double)value); } public static LLSD FromString(string value) { return new LLSDString(value); } @@ -195,7 +196,7 @@ namespace OpenMetaverse.StructuredData if (value.Type == LLSDType.Binary) { byte[] bytes = value.AsBinary(); - return Helpers.BytesToUInt64(bytes); + return Utils.BytesToUInt64(bytes); } else { @@ -207,7 +208,7 @@ namespace OpenMetaverse.StructuredData if (value.Type == LLSDType.Binary) { byte[] bytes = value.AsBinary(); - return Helpers.BytesToUInt(bytes); + return Utils.BytesToUInt(bytes); } else { @@ -376,7 +377,7 @@ namespace OpenMetaverse.StructuredData public override int AsInteger() { return value; } public override double AsReal() { return (double)value; } public override string AsString() { return value.ToString(); } - public override byte[] AsBinary() { return Helpers.IntToBytes(value); } + public override byte[] AsBinary() { return Utils.IntToBytes(value); } public override string ToString() { return AsString(); } } @@ -408,14 +409,7 @@ namespace OpenMetaverse.StructuredData public override double AsReal() { return value; } public override string AsString() { return value.ToString(Helpers.EnUsCulture); } - - public override byte[] AsBinary() { - byte[] bytesHostEnd = BitConverter.GetBytes( value ); - long longHostEnd = BitConverter.ToInt64( bytesHostEnd, 0 ); - long longNetEnd = System.Net.IPAddress.HostToNetworkOrder( longHostEnd ); - byte[] bytesNetEnd = BitConverter.GetBytes( longNetEnd ); - return bytesNetEnd; - } + public override byte[] AsBinary() { return Utils.DoubleToBytes(value); } public override string ToString() { return AsString(); } } @@ -532,14 +526,10 @@ namespace OpenMetaverse.StructuredData return value.ToUniversalTime().ToString( format ); } - public override byte[] AsBinary() { + public override byte[] AsBinary() + { TimeSpan ts = value.ToUniversalTime() - new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc ); - double timestamp = (double)ts.TotalSeconds; - byte[] bytesHostEnd = BitConverter.GetBytes( timestamp ); - long longHostEnd = BitConverter.ToInt64( bytesHostEnd, 0 ); - long longNetEnd = System.Net.IPAddress.HostToNetworkOrder( longHostEnd ); - byte[] bytesNetEnd = BitConverter.GetBytes( longNetEnd ); - return bytesNetEnd; + return Utils.DoubleToBytes(ts.TotalSeconds); } public override DateTime AsDate() { return value; } @@ -585,17 +575,17 @@ namespace OpenMetaverse.StructuredData public LLSDBinary(uint value) { - this.value = BitConverter.GetBytes(value); + this.value = Utils.UIntToBytes(value); } public LLSDBinary(long value) { - this.value = BitConverter.GetBytes(value); + this.value = Utils.Int64ToBytes(value); } public LLSDBinary(ulong value) { - this.value = BitConverter.GetBytes(value); + this.value = Utils.UInt64ToBytes(value); } public override string AsString() { return Convert.ToBase64String(value); } diff --git a/OpenMetaverse/Login.cs b/OpenMetaverse/Login.cs index e082f3cc..e629207e 100644 --- a/OpenMetaverse/Login.cs +++ b/OpenMetaverse/Login.cs @@ -160,7 +160,7 @@ namespace OpenMetaverse { LLSDArray homeArray = (LLSDArray)homeRegion; if (homeArray.Count == 2) - HomeRegion = Helpers.UIntsToLong((uint)homeArray[0].AsInteger(), (uint)homeArray[1].AsInteger()); + HomeRegion = Utils.UIntsToLong((uint)homeArray[0].AsInteger(), (uint)homeArray[1].AsInteger()); else HomeRegion = 0; } @@ -342,7 +342,7 @@ namespace OpenMetaverse LLSDArray homeRegionHandle = new LLSDArray(2); uint homeRegionX, homeRegionY; - Helpers.LongToUInts(HomeRegion, out homeRegionX, out homeRegionY); + Utils.LongToUInts(HomeRegion, out homeRegionX, out homeRegionY); homeRegionHandle.Add(LLSD.FromReal((double)homeRegionX)); homeRegionHandle.Add(LLSD.FromReal((double)homeRegionY)); @@ -1046,7 +1046,7 @@ namespace OpenMetaverse UpdateLoginStatus(LoginStatus.ConnectingToSim, "Connecting to simulator..."); - ulong handle = Helpers.UIntsToLong(data.RegionX, data.RegionY); + ulong handle = Utils.UIntsToLong(data.RegionX, data.RegionY); if (data.SimIP != null && data.SimPort != 0) { diff --git a/OpenMetaverse/ObjectManager.cs b/OpenMetaverse/ObjectManager.cs index 3e5f60f3..989419eb 100644 --- a/OpenMetaverse/ObjectManager.cs +++ b/OpenMetaverse/ObjectManager.cs @@ -1350,34 +1350,34 @@ namespace OpenMetaverse // Position position = new Vector3( - Helpers.UInt16ToFloat(block.ObjectData, pos, -0.5f * 256.0f, 1.5f * 256.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -0.5f * 256.0f, 1.5f * 256.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 3.0f * 256.0f)); + Utils.UInt16ToFloat(block.ObjectData, pos, -0.5f * 256.0f, 1.5f * 256.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 2, -0.5f * 256.0f, 1.5f * 256.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 3.0f * 256.0f)); pos += 6; // Velocity velocity = new Vector3( - Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); + Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; // Acceleration acceleration = new Vector3( - Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); + Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; // Rotation (theta) rotation = new Quaternion( - Helpers.UInt16ToFloat(block.ObjectData, pos, -1.0f, 1.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -1.0f, 1.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 6, -1.0f, 1.0f)); + Utils.UInt16ToFloat(block.ObjectData, pos, -1.0f, 1.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 4, -1.0f, 1.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 6, -1.0f, 1.0f)); pos += 8; // Angular velocity (omega) angularVelocity = new Vector3( - Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), - Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); + Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), + Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; break; @@ -1386,34 +1386,34 @@ namespace OpenMetaverse // Position position = new Vector3( - Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); + Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), + Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), + Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Velocity velocity = new Vector3( - Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); + Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), + Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), + Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Accleration acceleration = new Vector3( - Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); + Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), + Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), + Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Rotation rotation = new Quaternion( - Helpers.ByteToFloat(block.ObjectData, pos, -1.0f, 1.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 1, -1.0f, 1.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 3, -1.0f, 1.0f)); + Utils.ByteToFloat(block.ObjectData, pos, -1.0f, 1.0f), + Utils.ByteToFloat(block.ObjectData, pos + 1, -1.0f, 1.0f), + Utils.ByteToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), + Utils.ByteToFloat(block.ObjectData, pos + 3, -1.0f, 1.0f)); pos += 4; // Angular Velocity angularVelocity = new Vector3( - Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), - Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); + Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), + Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), + Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; break; @@ -1633,7 +1633,7 @@ namespace OpenMetaverse try { int pos = 4; - uint localid = Helpers.BytesToUInt(block.Data, 0); + uint localid = Utils.BytesToUInt(block.Data, 0); // Check if we are interested in this update if (!Client.Settings.ALWAYS_DECODE_OBJECTS && localid != Client.Self.localID && OnObjectUpdated == null) @@ -1660,28 +1660,28 @@ namespace OpenMetaverse pos += 12; // Velocity update.Velocity = new Vector3( - Helpers.UInt16ToFloat(block.Data, pos, -128.0f, 128.0f), - Helpers.UInt16ToFloat(block.Data, pos + 2, -128.0f, 128.0f), - Helpers.UInt16ToFloat(block.Data, pos + 4, -128.0f, 128.0f)); + Utils.UInt16ToFloat(block.Data, pos, -128.0f, 128.0f), + Utils.UInt16ToFloat(block.Data, pos + 2, -128.0f, 128.0f), + Utils.UInt16ToFloat(block.Data, pos + 4, -128.0f, 128.0f)); pos += 6; // Acceleration update.Acceleration = new Vector3( - Helpers.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f), - Helpers.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f), - Helpers.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f)); + Utils.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f), + Utils.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f), + Utils.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f)); pos += 6; // Rotation (theta) update.Rotation = new Quaternion( - Helpers.UInt16ToFloat(block.Data, pos, -1.0f, 1.0f), - Helpers.UInt16ToFloat(block.Data, pos + 2, -1.0f, 1.0f), - Helpers.UInt16ToFloat(block.Data, pos + 4, -1.0f, 1.0f), - Helpers.UInt16ToFloat(block.Data, pos + 6, -1.0f, 1.0f)); + Utils.UInt16ToFloat(block.Data, pos, -1.0f, 1.0f), + Utils.UInt16ToFloat(block.Data, pos + 2, -1.0f, 1.0f), + Utils.UInt16ToFloat(block.Data, pos + 4, -1.0f, 1.0f), + Utils.UInt16ToFloat(block.Data, pos + 6, -1.0f, 1.0f)); pos += 8; // Angular velocity update.AngularVelocity = new Vector3( - Helpers.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f), - Helpers.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f), - Helpers.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f)); + Utils.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f), + Utils.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f), + Utils.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f)); pos += 6; // Textures @@ -1829,7 +1829,7 @@ namespace OpenMetaverse prim.Rotation = new Quaternion(block.Data, i, true); i += 12; // Compressed flags - CompressedFlags flags = (CompressedFlags)Helpers.BytesToUInt(block.Data, i); + CompressedFlags flags = (CompressedFlags)Utils.BytesToUInt(block.Data, i); i += 4; prim.OwnerID = new UUID(block.Data, i); @@ -1923,10 +1923,10 @@ namespace OpenMetaverse prim.Sound = new UUID(block.Data, i); i += 16; - prim.SoundGain = Helpers.BytesToFloat(block.Data, i); + prim.SoundGain = Utils.BytesToFloat(block.Data, i); i += 4; prim.SoundFlags = block.Data[i++]; - prim.SoundRadius = Helpers.BytesToFloat(block.Data, i); + prim.SoundRadius = Utils.BytesToFloat(block.Data, i); i += 4; } @@ -1959,9 +1959,9 @@ namespace OpenMetaverse } prim.PrimData.PathCurve = (PathCurve)block.Data[i++]; - ushort pathBegin = Helpers.BytesToUInt16(block.Data, i); i += 2; + ushort pathBegin = Utils.BytesToUInt16(block.Data, i); i += 2; prim.PrimData.PathBegin = Primitive.UnpackBeginCut(pathBegin); - ushort pathEnd = Helpers.BytesToUInt16(block.Data, i); i += 2; + ushort pathEnd = Utils.BytesToUInt16(block.Data, i); i += 2; prim.PrimData.PathEnd = Primitive.UnpackEndCut(pathEnd); prim.PrimData.PathScaleX = Primitive.UnpackPathScale(block.Data[i++]); prim.PrimData.PathScaleY = Primitive.UnpackPathScale(block.Data[i++]); @@ -1976,15 +1976,15 @@ namespace OpenMetaverse prim.PrimData.PathSkew = Primitive.UnpackPathTwist((sbyte)block.Data[i++]); prim.PrimData.profileCurve = block.Data[i++]; - ushort profileBegin = Helpers.BytesToUInt16(block.Data, i); i += 2; + ushort profileBegin = Utils.BytesToUInt16(block.Data, i); i += 2; prim.PrimData.ProfileBegin = Primitive.UnpackBeginCut(profileBegin); - ushort profileEnd = Helpers.BytesToUInt16(block.Data, i); i += 2; + ushort profileEnd = Utils.BytesToUInt16(block.Data, i); i += 2; prim.PrimData.ProfileEnd = Primitive.UnpackEndCut(profileEnd); - ushort profileHollow = Helpers.BytesToUInt16(block.Data, i); i += 2; + ushort profileHollow = Utils.BytesToUInt16(block.Data, i); i += 2; prim.PrimData.ProfileHollow = Primitive.UnpackProfileHollow(profileHollow); // TextureEntry - int textureEntryLength = (int)Helpers.BytesToUInt(block.Data, i); + int textureEntryLength = (int)Utils.BytesToUInt(block.Data, i); i += 4; prim.Textures = new Primitive.TextureEntry(block.Data, i, textureEntryLength); i += textureEntryLength; @@ -1992,7 +1992,7 @@ namespace OpenMetaverse // Texture animation if ((flags & CompressedFlags.TextureAnimation) != 0) { - //int textureAnimLength = (int)Helpers.BytesToUIntBig(block.Data, i); + //int textureAnimLength = (int)Utils.BytesToUIntBig(block.Data, i); i += 4; prim.TextureAnim = new Primitive.TextureAnimation(block.Data, i); } diff --git a/OpenMetaverse/ParcelManager.cs b/OpenMetaverse/ParcelManager.cs index 71e72129..1bfa12a0 100644 --- a/OpenMetaverse/ParcelManager.cs +++ b/OpenMetaverse/ParcelManager.cs @@ -1625,7 +1625,7 @@ namespace OpenMetaverse if (BitConverter.IsLittleEndian) Array.Reverse(bytes); - uint value = Helpers.BytesToUInt(bytes); + uint value = Utils.BytesToUInt(bytes); poe.NewestPrim = Utils.UnixTimeToDateTime(value); } diff --git a/OpenMetaverse/Permissions.cs b/OpenMetaverse/Permissions.cs index f1f2c73c..c7053471 100644 --- a/OpenMetaverse/Permissions.cs +++ b/OpenMetaverse/Permissions.cs @@ -25,6 +25,7 @@ */ using System; +using OpenMetaverse.StructuredData; namespace OpenMetaverse { @@ -89,6 +90,36 @@ namespace OpenMetaverse OwnerMask = (PermissionMask)ownerMask; } + public LLSD GetLLSD() + { + LLSDMap permissions = new LLSDMap(5); + permissions["BaseMask"] = LLSD.FromUInteger((uint)BaseMask); + permissions["EveryoneMask"] = LLSD.FromUInteger((uint)EveryoneMask); + permissions["GroupMask"] = LLSD.FromUInteger((uint)GroupMask); + permissions["NextOwnerMask"] = LLSD.FromUInteger((uint)NextOwnerMask); + permissions["OwnerMask"] = LLSD.FromUInteger((uint)OwnerMask); + return permissions; + } + + public static Permissions FromLLSD(LLSD llsd) + { + Permissions permissions = new Permissions(); + LLSDMap map = (LLSDMap)llsd; + + byte[] bytes = map["BaseMask"].AsBinary(); + permissions.BaseMask = (PermissionMask)Utils.BytesToUInt(bytes); + bytes = map["EveryoneMask"].AsBinary(); + permissions.EveryoneMask = (PermissionMask)Utils.BytesToUInt(bytes); + bytes = map["GroupMask"].AsBinary(); + permissions.GroupMask = (PermissionMask)Utils.BytesToUInt(bytes); + bytes = map["NextOwnerMask"].AsBinary(); + permissions.NextOwnerMask = (PermissionMask)Utils.BytesToUInt(bytes); + bytes = map["OwnerMask"].AsBinary(); + permissions.OwnerMask = (PermissionMask)Utils.BytesToUInt(bytes); + + return permissions; + } + public override string ToString() { return String.Format("Base: {0}, Everyone: {1}, Group: {2}, NextOwner: {3}, Owner: {4}", diff --git a/OpenMetaverse/Primitives/Primitive.cs b/OpenMetaverse/Primitives/Primitive.cs index c1683d9d..37381e24 100644 --- a/OpenMetaverse/Primitives/Primitive.cs +++ b/OpenMetaverse/Primitives/Primitive.cs @@ -783,9 +783,9 @@ namespace OpenMetaverse if (data.Length - pos >= 16) { Color = new Color4(data, pos, false); - Radius = Helpers.BytesToFloat(data, pos + 4); - Cutoff = Helpers.BytesToFloat(data, pos + 8); - Falloff = Helpers.BytesToFloat(data, pos + 12); + Radius = Utils.BytesToFloat(data, pos + 4); + Cutoff = Utils.BytesToFloat(data, pos + 8); + Falloff = Utils.BytesToFloat(data, pos + 12); // Alpha in color is actually intensity Intensity = Color.A; @@ -813,9 +813,9 @@ namespace OpenMetaverse Color4 tmpColor = Color; tmpColor.A = Intensity; tmpColor.GetBytes().CopyTo(data, 0); - Helpers.FloatToBytes(Radius).CopyTo(data, 4); - Helpers.FloatToBytes(Cutoff).CopyTo(data, 8); - Helpers.FloatToBytes(Falloff).CopyTo(data, 12); + Utils.FloatToBytes(Radius).CopyTo(data, 4); + Utils.FloatToBytes(Cutoff).CopyTo(data, 8); + Utils.FloatToBytes(Falloff).CopyTo(data, 12); return data; } @@ -1274,10 +1274,10 @@ namespace OpenMetaverse for (int k = 0; k < extraParamCount; k++) { - ExtraParamType type = (ExtraParamType)Helpers.BytesToUInt16(data, i); + ExtraParamType type = (ExtraParamType)Utils.BytesToUInt16(data, i); i += 2; - uint paramLength = Helpers.BytesToUInt(data, i); + uint paramLength = Utils.BytesToUInt(data, i); i += 4; if (type == ExtraParamType.Flexible) diff --git a/OpenMetaverse/Primitives/TextureEntry.cs b/OpenMetaverse/Primitives/TextureEntry.cs index ac97146a..da462646 100644 --- a/OpenMetaverse/Primitives/TextureEntry.cs +++ b/OpenMetaverse/Primitives/TextureEntry.cs @@ -718,12 +718,12 @@ namespace OpenMetaverse #endregion Color #region RepeatU - DefaultTexture.RepeatU = Helpers.BytesToFloat(data, i); + DefaultTexture.RepeatU = Utils.BytesToFloat(data, i); i += 4; while (ReadFaceBitfield(data, ref i, ref faceBits, ref bitfieldSize)) { - float tmpFloat = Helpers.BytesToFloat(data, i); + float tmpFloat = Utils.BytesToFloat(data, i); i += 4; for (uint face = 0, bit = 1; face < bitfieldSize; face++, bit <<= 1) @@ -733,12 +733,12 @@ namespace OpenMetaverse #endregion RepeatU #region RepeatV - DefaultTexture.RepeatV = Helpers.BytesToFloat(data, i); + DefaultTexture.RepeatV = Utils.BytesToFloat(data, i); i += 4; while (ReadFaceBitfield(data, ref i, ref faceBits, ref bitfieldSize)) { - float tmpFloat = Helpers.BytesToFloat(data, i); + float tmpFloat = Utils.BytesToFloat(data, i); i += 4; for (uint face = 0, bit = 1; face < bitfieldSize; face++, bit <<= 1) @@ -1173,9 +1173,9 @@ namespace OpenMetaverse SizeX = (uint)data[pos++]; SizeY = (uint)data[pos++]; - Start = Helpers.BytesToFloat(data, pos); - Length = Helpers.BytesToFloat(data, pos + 4); - Rate = Helpers.BytesToFloat(data, pos + 8); + Start = Utils.BytesToFloat(data, pos); + Length = Utils.BytesToFloat(data, pos + 4); + Rate = Utils.BytesToFloat(data, pos + 8); } else { @@ -1204,9 +1204,9 @@ namespace OpenMetaverse data[pos++] = (byte)SizeX; data[pos++] = (byte)SizeY; - Helpers.FloatToBytes(Start).CopyTo(data, pos); - Helpers.FloatToBytes(Length).CopyTo(data, pos + 4); - Helpers.FloatToBytes(Rate).CopyTo(data, pos + 4); + Utils.FloatToBytes(Start).CopyTo(data, pos); + Utils.FloatToBytes(Length).CopyTo(data, pos + 4); + Utils.FloatToBytes(Rate).CopyTo(data, pos + 4); return data; } diff --git a/OpenMetaverse/Types/Utils.cs b/OpenMetaverse/Types/Utils.cs index 9482d79c..4c3198e1 100644 --- a/OpenMetaverse/Types/Utils.cs +++ b/OpenMetaverse/Types/Utils.cs @@ -29,7 +29,7 @@ using System.Text; namespace OpenMetaverse { - public static class Utils + public static partial class Utils { /// /// Operating system @@ -341,338 +341,5 @@ namespace OpenMetaverse } #endregion Platform - - #region Conversion - - /// - /// Copy a byte array - /// - /// Byte array to copy - /// A copy of the given byte array - public static byte[] CopyBytes(byte[] bytes) - { - if (bytes == null) - return null; - - byte[] newBytes = new byte[bytes.Length]; - Buffer.BlockCopy(bytes, 0, newBytes, 0, bytes.Length); - return newBytes; - } - - /// - /// Convert four bytes in little endian ordering to a floating point - /// value - /// - /// Byte array containing a little ending floating - /// point value - /// Starting position of the floating point value in - /// the byte array - /// Single precision value - public static float BytesToFloat(byte[] bytes, int pos) - { - if (!BitConverter.IsLittleEndian) - Array.Reverse(bytes, pos, 4); - return BitConverter.ToSingle(bytes, pos); - } - - /// - /// Convert a float value to a byte given a minimum and maximum range - /// - /// Value to convert to a byte - /// Minimum value range - /// Maximum value range - /// A single byte representing the original float value - public static byte FloatToByte(float val, float lower, float upper) - { - val = Clamp(val, lower, upper); - // Normalize the value - val -= lower; - val /= (upper - lower); - - return (byte)Math.Floor(val * (float)byte.MaxValue); - } - - /// - /// Convert a floating point value to four bytes in little endian - /// ordering - /// - /// A floating point value - /// A four byte array containing the value in little endian - /// ordering - public static byte[] FloatToBytes(float value) - { - byte[] bytes = BitConverter.GetBytes(value); - if (!BitConverter.IsLittleEndian) - Array.Reverse(bytes); - return bytes; - } - - /// - /// Convert an IP address object to an unsigned 32-bit integer - /// - /// IP address to convert - /// 32-bit unsigned integer holding the IP address bits - public static uint IPToUInt(System.Net.IPAddress address) - { - byte[] bytes = address.GetAddressBytes(); - return (uint)((bytes[3] << 24) + (bytes[2] << 16) + (bytes[1] << 8) + bytes[0]); - } - - /// - /// Convert a variable length UTF8 byte array to a string - /// - /// The UTF8 encoded byte array to convert - /// The decoded string - public static string BytesToString(byte[] bytes) - { - if (bytes.Length > 0 && bytes[bytes.Length - 1] == 0x00) - return UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length - 1); - else - return UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length); - } - - /// - /// Converts a byte array to a string containing hexadecimal characters - /// - /// The byte array to convert to a string - /// The name of the field to prepend to each - /// line of the string - /// A string containing hexadecimal characters on multiple - /// lines. Each line is prepended with the field name - public static string BytesToHexString(byte[] bytes, string fieldName) - { - return BytesToHexString(bytes, bytes.Length, fieldName); - } - - /// - /// Converts a byte array to a string containing hexadecimal characters - /// - /// The byte array to convert to a string - /// Number of bytes in the array to parse - /// A string to prepend to each line of the hex - /// dump - /// A string containing hexadecimal characters on multiple - /// lines. Each line is prepended with the field name - public static string BytesToHexString(byte[] bytes, int length, string fieldName) - { - StringBuilder output = new StringBuilder(); - - for (int i = 0; i < length; i += 16) - { - if (i != 0) - output.Append('\n'); - - if (!String.IsNullOrEmpty(fieldName)) - { - output.Append(fieldName); - output.Append(": "); - } - - for (int j = 0; j < 16; j++) - { - if ((i + j) < length) - { - if (j != 0) - output.Append(' '); - - output.Append(String.Format("{0:X2}", bytes[i + j])); - } - } - } - - return output.ToString(); - } - - /// - /// Convert a string to a UTF8 encoded byte array - /// - /// The string to convert - /// A null-terminated UTF8 byte array - public static byte[] StringToBytes(string str) - { - if (String.IsNullOrEmpty(str)) { return new byte[0]; } - if (!str.EndsWith("\0")) { str += "\0"; } - return System.Text.UTF8Encoding.UTF8.GetBytes(str); - } - - ///// - ///// Converts a string containing hexadecimal characters to a byte array - ///// - ///// String containing hexadecimal characters - ///// The converted byte array - public static byte[] HexStringToBytes(string hexString) - { - if (String.IsNullOrEmpty(hexString)) - return new byte[0]; - - StringBuilder stripped = new StringBuilder(hexString.Length); - char c; - - // remove all non A-F, 0-9, characters - for (int i = 0; i < hexString.Length; i++) - { - c = hexString[i]; - if (IsHexDigit(c)) - stripped.Append(c); - } - - string newString = stripped.ToString(); - - // if odd number of characters, discard last character - if (newString.Length % 2 != 0) - { - newString = newString.Substring(0, newString.Length - 1); - } - - int byteLength = newString.Length / 2; - byte[] bytes = new byte[byteLength]; - string hex; - int j = 0; - - for (int i = 0; i < bytes.Length; i++) - { - hex = new String(new Char[] { newString[j], newString[j + 1] }); - bytes[i] = HexToByte(hex); - j = j + 2; - } - - return bytes; - } - - /// - /// Returns true is c is a hexadecimal digit (A-F, a-f, 0-9) - /// - /// Character to test - /// true if hex digit, false if not - private static bool IsHexDigit(Char c) - { - const int numA = 65; - const int num0 = 48; - - int numChar; - - c = Char.ToUpper(c); - numChar = Convert.ToInt32(c); - - if (numChar >= numA && numChar < (numA + 6)) - return true; - else if (numChar >= num0 && numChar < (num0 + 10)) - return true; - else - return false; - } - - /// - /// Converts 1 or 2 character string into equivalant byte value - /// - /// 1 or 2 character string - /// byte - private static byte HexToByte(string hex) - { - if (hex.Length > 2 || hex.Length <= 0) - throw new ArgumentException("hex must be 1 or 2 characters in length"); - byte newByte = Byte.Parse(hex, System.Globalization.NumberStyles.HexNumber); - return newByte; - } - - /// - /// Gets a unix timestamp for the current time - /// - /// An unsigned integer representing a unix timestamp for now - public static uint GetUnixTime() - { - return (uint)(DateTime.UtcNow - Epoch).TotalSeconds; - } - - /// - /// Convert a UNIX timestamp to a native DateTime object - /// - /// An unsigned integer representing a UNIX - /// timestamp - /// A DateTime object containing the same time specified in - /// the given timestamp - public static DateTime UnixTimeToDateTime(uint timestamp) - { - System.DateTime dateTime = Epoch; - - // Add the number of seconds in our UNIX timestamp - dateTime = dateTime.AddSeconds(timestamp); - - return dateTime; - } - - /// - /// Convert a UNIX timestamp to a native DateTime object - /// - /// A signed integer representing a UNIX - /// timestamp - /// A DateTime object containing the same time specified in - /// the given timestamp - public static DateTime UnixTimeToDateTime(int timestamp) - { - return DateTime.FromBinary(timestamp); - } - - /// - /// Convert a native DateTime object to a UNIX timestamp - /// - /// A DateTime object you want to convert to a - /// timestamp - /// An unsigned integer representing a UNIX timestamp - public static uint DateTimeToUnixTime(DateTime time) - { - TimeSpan ts = (time - new DateTime(1970, 1, 1, 0, 0, 0)); - return (uint)ts.TotalSeconds; - } - - /// - /// Swap two values - /// - /// Type of the values to swap - /// First value - /// Second value - public static void Swap(ref T lhs, ref T rhs) - { - T temp = lhs; - lhs = rhs; - rhs = temp; - } - - /// - /// Attempts to parse a floating point value from a string, using an - /// EN-US number format - /// - /// String to parse - /// Resulting floating point number - /// True if the parse was successful, otherwise false - public static bool TryParseSingle(string s, out float result) - { - return Single.TryParse(s, System.Globalization.NumberStyles.Float, EnUsCulture.NumberFormat, out result); - } - - /// - /// Attempts to parse a floating point value from a string, using an - /// EN-US number format - /// - /// String to parse - /// Resulting floating point number - /// True if the parse was successful, otherwise false - public static bool TryParseDouble(string s, out double result) - { - return Double.TryParse(s, System.Globalization.NumberStyles.Float, EnUsCulture.NumberFormat, out result); - } - - /// - /// Tries to parse an unsigned 32-bit integer from a hexadecimal string - /// - /// String to parse - /// Resulting integer - /// True if the parse was successful, otherwise false - public static bool TryParseHex(string s, out uint result) - { - return UInt32.TryParse(s, System.Globalization.NumberStyles.HexNumber, EnUsCulture.NumberFormat, out result); - } - - #endregion Conversion } } diff --git a/OpenMetaverse/Types/UtilsConversions.cs b/OpenMetaverse/Types/UtilsConversions.cs new file mode 100644 index 00000000..10642aee --- /dev/null +++ b/OpenMetaverse/Types/UtilsConversions.cs @@ -0,0 +1,655 @@ +/* + * Copyright (c) 2008, openmetaverse.org + * All rights reserved. + * + * - 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 openmetaverse.org 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.Text; + +namespace OpenMetaverse +{ + public static partial class Utils + { + #region Conversion + + /// + /// Copy a byte array + /// + /// Byte array to copy + /// A copy of the given byte array + public static byte[] CopyBytes(byte[] bytes) + { + if (bytes == null) + return null; + + byte[] newBytes = new byte[bytes.Length]; + Buffer.BlockCopy(bytes, 0, newBytes, 0, bytes.Length); + return newBytes; + } + + /// + /// Convert a floating point value to four bytes in little endian + /// ordering + /// + /// A floating point value + /// A four byte array containing the value in little endian + /// ordering + public static byte[] FloatToBytes(float value) + { + byte[] bytes = BitConverter.GetBytes(value); + if (!BitConverter.IsLittleEndian) + Array.Reverse(bytes); + return bytes; + } + + /// + /// Converts an unsigned integer to a hexadecimal string + /// + /// An unsigned integer to convert to a string + /// A hexadecimal string 10 characters long + /// 0x7fffffff + public static string UIntToHexString(uint i) + { + return string.Format("{0:x8}", i); + } + + /// + /// Packs to 32-bit unsigned integers in to a 64-bit unsigned integer + /// + /// The left-hand (or X) value + /// The right-hand (or Y) value + /// A 64-bit integer containing the two 32-bit input values + public static ulong UIntsToLong(uint a, uint b) + { + return ((ulong)a << 32) | (ulong)b; + } + + /// + /// Unpacks two 32-bit unsigned integers from a 64-bit unsigned integer + /// + /// The 64-bit input integer + /// The left-hand (or X) output value + /// The right-hand (or Y) output value + public static void LongToUInts(ulong a, out uint b, out uint c) + { + b = (uint)(a >> 32); + c = (uint)(a & 0x00000000FFFFFFFF); + } + + /// + /// Convert an integer to a byte array in little endian format + /// + /// The integer to convert + /// A four byte little endian array + public static byte[] IntToBytes(int x) + { + byte[] bytes = new byte[4]; + + bytes[0] = (byte)(x % 256); + bytes[1] = (byte)((x >> 8) % 256); + bytes[2] = (byte)((x >> 16) % 256); + bytes[3] = (byte)((x >> 24) % 256); + + return bytes; + } + + /// + /// Convert a 64-bit integer to a byte array in little endian format + /// + /// The value to convert + /// An 8 byte little endian array + public static byte[] Int64ToBytes(long value) + { + byte[] bytes = BitConverter.GetBytes(value); + if (!BitConverter.IsLittleEndian) + Array.Reverse(bytes); + + return bytes; + } + + /// + /// Convert a 64-bit unsigned integer to a byte array in little endian + /// format + /// + /// The value to convert + /// An 8 byte little endian array + public static byte[] UInt64ToBytes(ulong value) + { + byte[] bytes = BitConverter.GetBytes(value); + if (!BitConverter.IsLittleEndian) + Array.Reverse(bytes); + + return bytes; + } + + /// + /// Convert the first four bytes starting at the given position in + /// little endian ordering to a signed integer + /// + /// Byte array containing the int + /// Position to start reading the int from + /// A signed integer, will be zero if an int can't be read + /// at the given position + public static int BytesToInt(byte[] bytes, int pos) + { + if (bytes.Length < pos + 4) return 0; + return (int)(bytes[pos + 0] + (bytes[pos + 1] << 8) + (bytes[pos + 2] << 16) + (bytes[pos + 3] << 24)); + } + + /// + /// Convert the first four bytes of the given array in little endian + /// ordering to a signed integer + /// + /// An array four bytes or longer + /// A signed integer, will be zero if the array contains + /// less than four bytes + public static int BytesToInt(byte[] bytes) + { + return BytesToInt(bytes, 0); + } + + /// + /// Convert the first two bytes starting at the given position in + /// little endian ordering to an unsigned short + /// + /// Byte array containing the ushort + /// Position to start reading the ushort from + /// An unsigned short, will be zero if a ushort can't be read + /// at the given position + public static ushort BytesToUInt16(byte[] bytes, int pos) + { + if (bytes.Length <= pos + 1) return 0; + return (ushort)(bytes[pos] + (bytes[pos + 1] << 8)); + } + + /// + /// Convert two bytes in little endian ordering to an unsigned short + /// + /// Byte array containing the ushort + /// An unsigned short, will be zero if a ushort can't be + /// read + public static ushort BytesToUInt16(byte[] bytes) + { + return BytesToUInt16(bytes, 0); + } + + /// + /// Convert the first four bytes starting at the given position in + /// little endian ordering to an unsigned integer + /// + /// Byte array containing the uint + /// Position to start reading the uint from + /// An unsigned integer, will be zero if a uint can't be read + /// at the given position + public static uint BytesToUInt(byte[] bytes, int pos) + { + if (bytes.Length < pos + 4) return 0; + return (uint)(bytes[pos + 0] + (bytes[pos + 1] << 8) + (bytes[pos + 2] << 16) + (bytes[pos + 3] << 24)); + } + + /// + /// Convert the first four bytes of the given array in little endian + /// ordering to an unsigned integer + /// + /// An array four bytes or longer + /// An unsigned integer, will be zero if the array contains + /// less than four bytes + public static uint BytesToUInt(byte[] bytes) + { + return BytesToUInt(bytes, 0); + } + + /// + /// Convert the first eight bytes of the given array in little endian + /// ordering to an unsigned 64-bit integer + /// + /// An array eight bytes or longer + /// An unsigned 64-bit integer, will be zero if the array + /// contains less than eight bytes + public static ulong BytesToUInt64(byte[] bytes) + { + if (bytes.Length < 8) return 0; + return (ulong) + ((ulong)bytes[0] + + ((ulong)bytes[1] << 8) + + ((ulong)bytes[2] << 16) + + ((ulong)bytes[3] << 24) + + ((ulong)bytes[4] << 32) + + ((ulong)bytes[5] << 40) + + ((ulong)bytes[6] << 48) + + ((ulong)bytes[7] << 56)); + } + + /// + /// Convert four bytes in little endian ordering to a floating point + /// value + /// + /// Byte array containing a little ending floating + /// point value + /// Starting position of the floating point value in + /// the byte array + /// Single precision value + public static float BytesToFloat(byte[] bytes, int pos) + { + if (!BitConverter.IsLittleEndian) + { + byte[] newBytes = new byte[4]; + Buffer.BlockCopy(bytes, pos, newBytes, 0, 4); + Array.Reverse(newBytes, pos, 4); + return BitConverter.ToSingle(newBytes, 0); + } + else + { + return BitConverter.ToSingle(bytes, pos); + } + } + + public static double BytesToDouble(byte[] bytes, int pos) + { + if (!BitConverter.IsLittleEndian) + { + byte[] newBytes = new byte[8]; + Buffer.BlockCopy(bytes, pos, newBytes, 0, 8); + Array.Reverse(newBytes, pos, 8); + return BitConverter.ToDouble(newBytes, 0); + } + else + { + return BitConverter.ToDouble(bytes, pos); + } + } + + public static byte[] DoubleToBytes(double value) + { + byte[] bytes = BitConverter.GetBytes(value); + if (!BitConverter.IsLittleEndian) + Array.Reverse(bytes); + return bytes; + } + + public static byte[] UInt16ToBytes(int value) + { + byte[] bytes = new byte[2]; + bytes[0] = (byte)(value % 256); + bytes[1] = (byte)((value >> 8) % 256); + return bytes; + } + + public static byte[] UIntToBytes(uint value) + { + byte[] bytes = new byte[4]; + bytes[0] = (byte)(value % 256); + bytes[1] = (byte)((value >> 8) % 256); + bytes[2] = (byte)((value >> 16) % 256); + bytes[3] = (byte)((value >> 24) % 256); + return bytes; + } + + /// + /// Convert a float value to a byte given a minimum and maximum range + /// + /// Value to convert to a byte + /// Minimum value range + /// Maximum value range + /// A single byte representing the original float value + public static byte FloatToByte(float val, float lower, float upper) + { + val = Utils.Clamp(val, lower, upper); + // Normalize the value + val -= lower; + val /= (upper - lower); + + return (byte)Math.Floor(val * (float)byte.MaxValue); + } + + /// + /// Convert a byte to a float value given a minimum and maximum range + /// + /// Byte array to get the byte from + /// Position in the byte array the desired byte is at + /// Minimum value range + /// Maximum value range + /// A float value inclusively between lower and upper + public static float ByteToFloat(byte[] bytes, int pos, float lower, float upper) + { + if (bytes.Length <= pos) return 0; + return ByteToFloat(bytes[pos], lower, upper); + } + + /// + /// Convert a byte to a float value given a minimum and maximum range + /// + /// Byte to convert to a float value + /// Minimum value range + /// Maximum value range + /// A float value inclusively between lower and upper + public static float ByteToFloat(byte val, float lower, float upper) + { + const float ONE_OVER_BYTEMAX = 1.0f / (float)byte.MaxValue; + + float fval = (float)val * ONE_OVER_BYTEMAX; + float delta = (upper - lower); + fval *= delta; + fval += lower; + + // Test for values very close to zero + float error = delta * ONE_OVER_BYTEMAX; + if (Math.Abs(fval) < error) + fval = 0.0f; + + return fval; + } + + public static float UInt16ToFloat(byte[] bytes, int pos, float lower, float upper) + { + ushort val = BytesToUInt16(bytes, pos); + return UInt16ToFloat(val, lower, upper); + } + + public static float UInt16ToFloat(ushort val, float lower, float upper) + { + const float ONE_OVER_U16_MAX = 1.0f / (float)UInt16.MaxValue; + + float fval = (float)val * ONE_OVER_U16_MAX; + float delta = upper - lower; + fval *= delta; + fval += lower; + + // Make sure zeroes come through as zero + float maxError = delta * ONE_OVER_U16_MAX; + if (Math.Abs(fval) < maxError) + fval = 0.0f; + + return fval; + } + + /// + /// Convert an IP address object to an unsigned 32-bit integer + /// + /// IP address to convert + /// 32-bit unsigned integer holding the IP address bits + public static uint IPToUInt(System.Net.IPAddress address) + { + byte[] bytes = address.GetAddressBytes(); + return (uint)((bytes[3] << 24) + (bytes[2] << 16) + (bytes[1] << 8) + bytes[0]); + } + + /// + /// Convert a variable length UTF8 byte array to a string + /// + /// The UTF8 encoded byte array to convert + /// The decoded string + public static string BytesToString(byte[] bytes) + { + if (bytes.Length > 0 && bytes[bytes.Length - 1] == 0x00) + return UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length - 1); + else + return UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length); + } + + /// + /// Converts a byte array to a string containing hexadecimal characters + /// + /// The byte array to convert to a string + /// The name of the field to prepend to each + /// line of the string + /// A string containing hexadecimal characters on multiple + /// lines. Each line is prepended with the field name + public static string BytesToHexString(byte[] bytes, string fieldName) + { + return BytesToHexString(bytes, bytes.Length, fieldName); + } + + /// + /// Converts a byte array to a string containing hexadecimal characters + /// + /// The byte array to convert to a string + /// Number of bytes in the array to parse + /// A string to prepend to each line of the hex + /// dump + /// A string containing hexadecimal characters on multiple + /// lines. Each line is prepended with the field name + public static string BytesToHexString(byte[] bytes, int length, string fieldName) + { + StringBuilder output = new StringBuilder(); + + for (int i = 0; i < length; i += 16) + { + if (i != 0) + output.Append('\n'); + + if (!String.IsNullOrEmpty(fieldName)) + { + output.Append(fieldName); + output.Append(": "); + } + + for (int j = 0; j < 16; j++) + { + if ((i + j) < length) + { + if (j != 0) + output.Append(' '); + + output.Append(String.Format("{0:X2}", bytes[i + j])); + } + } + } + + return output.ToString(); + } + + /// + /// Convert a string to a UTF8 encoded byte array + /// + /// The string to convert + /// A null-terminated UTF8 byte array + public static byte[] StringToBytes(string str) + { + if (String.IsNullOrEmpty(str)) { return new byte[0]; } + if (!str.EndsWith("\0")) { str += "\0"; } + return System.Text.UTF8Encoding.UTF8.GetBytes(str); + } + + ///// + ///// Converts a string containing hexadecimal characters to a byte array + ///// + ///// String containing hexadecimal characters + ///// The converted byte array + public static byte[] HexStringToBytes(string hexString) + { + if (String.IsNullOrEmpty(hexString)) + return new byte[0]; + + StringBuilder stripped = new StringBuilder(hexString.Length); + char c; + + // remove all non A-F, 0-9, characters + for (int i = 0; i < hexString.Length; i++) + { + c = hexString[i]; + if (IsHexDigit(c)) + stripped.Append(c); + } + + string newString = stripped.ToString(); + + // if odd number of characters, discard last character + if (newString.Length % 2 != 0) + { + newString = newString.Substring(0, newString.Length - 1); + } + + int byteLength = newString.Length / 2; + byte[] bytes = new byte[byteLength]; + string hex; + int j = 0; + + for (int i = 0; i < bytes.Length; i++) + { + hex = new String(new Char[] { newString[j], newString[j + 1] }); + bytes[i] = HexToByte(hex); + j = j + 2; + } + + return bytes; + } + + /// + /// Returns true is c is a hexadecimal digit (A-F, a-f, 0-9) + /// + /// Character to test + /// true if hex digit, false if not + private static bool IsHexDigit(Char c) + { + const int numA = 65; + const int num0 = 48; + + int numChar; + + c = Char.ToUpper(c); + numChar = Convert.ToInt32(c); + + if (numChar >= numA && numChar < (numA + 6)) + return true; + else if (numChar >= num0 && numChar < (num0 + 10)) + return true; + else + return false; + } + + /// + /// Converts 1 or 2 character string into equivalant byte value + /// + /// 1 or 2 character string + /// byte + private static byte HexToByte(string hex) + { + if (hex.Length > 2 || hex.Length <= 0) + throw new ArgumentException("hex must be 1 or 2 characters in length"); + byte newByte = Byte.Parse(hex, System.Globalization.NumberStyles.HexNumber); + return newByte; + } + + /// + /// Gets a unix timestamp for the current time + /// + /// An unsigned integer representing a unix timestamp for now + public static uint GetUnixTime() + { + return (uint)(DateTime.UtcNow - Epoch).TotalSeconds; + } + + /// + /// Convert a UNIX timestamp to a native DateTime object + /// + /// An unsigned integer representing a UNIX + /// timestamp + /// A DateTime object containing the same time specified in + /// the given timestamp + public static DateTime UnixTimeToDateTime(uint timestamp) + { + System.DateTime dateTime = Epoch; + + // Add the number of seconds in our UNIX timestamp + dateTime = dateTime.AddSeconds(timestamp); + + return dateTime; + } + + /// + /// Convert a UNIX timestamp to a native DateTime object + /// + /// A signed integer representing a UNIX + /// timestamp + /// A DateTime object containing the same time specified in + /// the given timestamp + public static DateTime UnixTimeToDateTime(int timestamp) + { + return DateTime.FromBinary(timestamp); + } + + /// + /// Convert a native DateTime object to a UNIX timestamp + /// + /// A DateTime object you want to convert to a + /// timestamp + /// An unsigned integer representing a UNIX timestamp + public static uint DateTimeToUnixTime(DateTime time) + { + TimeSpan ts = (time - new DateTime(1970, 1, 1, 0, 0, 0)); + return (uint)ts.TotalSeconds; + } + + /// + /// Swap two values + /// + /// Type of the values to swap + /// First value + /// Second value + public static void Swap(ref T lhs, ref T rhs) + { + T temp = lhs; + lhs = rhs; + rhs = temp; + } + + /// + /// Attempts to parse a floating point value from a string, using an + /// EN-US number format + /// + /// String to parse + /// Resulting floating point number + /// True if the parse was successful, otherwise false + public static bool TryParseSingle(string s, out float result) + { + return Single.TryParse(s, System.Globalization.NumberStyles.Float, EnUsCulture.NumberFormat, out result); + } + + /// + /// Attempts to parse a floating point value from a string, using an + /// EN-US number format + /// + /// String to parse + /// Resulting floating point number + /// True if the parse was successful, otherwise false + public static bool TryParseDouble(string s, out double result) + { + return Double.TryParse(s, System.Globalization.NumberStyles.Float, EnUsCulture.NumberFormat, out result); + } + + /// + /// Tries to parse an unsigned 32-bit integer from a hexadecimal string + /// + /// String to parse + /// Resulting integer + /// True if the parse was successful, otherwise false + public static bool TryParseHex(string s, out uint result) + { + return UInt32.TryParse(s, System.Globalization.NumberStyles.HexNumber, EnUsCulture.NumberFormat, out result); + } + + #endregion Conversion + } +} diff --git a/Programs/GridProxy/GridProxy.cs b/Programs/GridProxy/GridProxy.cs index ea65eb62..14f3c638 100644 --- a/Programs/GridProxy/GridProxy.cs +++ b/Programs/GridProxy/GridProxy.cs @@ -918,7 +918,7 @@ namespace GridProxy else info = (LLSDMap)(((LLSDArray)body["RegionData"])[0]); byte[] bytes = info["SimIP"].AsBinary(); - uint simIP = Helpers.BytesToUInt(bytes); + uint simIP = Utils.BytesToUInt(bytes); ushort simPort = (ushort)info["SimPort"].AsInteger(); string capsURL = info["SeedCapability"].AsString(); @@ -937,7 +937,7 @@ namespace GridProxy string ipAndPort = body["sim-ip-and-port"].AsString(); string[] pieces = ipAndPort.Split(':'); byte[] bytes = IPAddress.Parse(pieces[0]).GetAddressBytes(); - uint simIP = Helpers.BytesToUInt(bytes); + uint simIP = Utils.BytesToUInt(bytes); ushort simPort = (ushort)Convert.ToInt32(pieces[1]); string capsURL = body["seed-capability"].AsString(); @@ -1932,7 +1932,7 @@ namespace GridProxy simPort = (ushort)fakeSim.Port; byte[] bytes = fakeSim.Address.GetAddressBytes(); - simIP = Helpers.BytesToUInt(bytes); + simIP = Utils.BytesToUInt(bytes); if (simCaps != null && simCaps.Length > 0) { CapInfo info = new CapInfo(simCaps, realSim, "SeedCapability"); diff --git a/Programs/GridProxy/Plugins/ClientAO.cs b/Programs/GridProxy/Plugins/ClientAO.cs index 406fad18..b89ffd56 100644 --- a/Programs/GridProxy/Plugins/ClientAO.cs +++ b/Programs/GridProxy/Plugins/ClientAO.cs @@ -504,7 +504,7 @@ public class ClientAO : ProxyPlugin Buffer.BlockCopy(UUID.Zero.GetBytes(), 0, paramField, 48, 16); Buffer.BlockCopy(item.UUID.GetBytes(), 0, paramField, 64, 16); Buffer.BlockCopy(item.AssetUUID.GetBytes(), 0, paramField, 80, 16); - Buffer.BlockCopy(Helpers.IntToBytes((int)item.AssetType), 0, paramField, 96, 4); + Buffer.BlockCopy(Utils.IntToBytes((int)item.AssetType), 0, paramField, 96, 4); request.TransferInfo.Params = paramField; // add a delegate to monitor configuration notecards download diff --git a/Programs/Simian/Agent.cs b/Programs/Simian/Agent.cs index c0a84668..6734b37d 100644 --- a/Programs/Simian/Agent.cs +++ b/Programs/Simian/Agent.cs @@ -97,10 +97,6 @@ namespace Simian public AgentManager.ControlFlags ControlFlags = AgentManager.ControlFlags.NONE; [NonSerialized] public AnimationSet Animations = new AnimationSet(); - [NonSerialized] - public Dictionary Inventory = new Dictionary(); - [NonSerialized] - public Dictionary Library = new Dictionary(); // TODO: Replace byte with enum [NonSerialized] public byte State; diff --git a/Programs/Simian/Extensions/AccountManager.cs b/Programs/Simian/Extensions/AccountManager.cs index f77a9696..f79e9577 100644 --- a/Programs/Simian/Extensions/AccountManager.cs +++ b/Programs/Simian/Extensions/AccountManager.cs @@ -8,8 +8,6 @@ namespace Simian.Extensions { public class AccountManager : IExtension, IAccountProvider, IPersistable { - public string StoreName { get { return "Accounts"; } } - Simian server; DoubleDictionary accounts = new DoubleDictionary(); diff --git a/Programs/Simian/Extensions/AssetManager.cs b/Programs/Simian/Extensions/AssetManager.cs index 4318cba6..3b4192b9 100644 --- a/Programs/Simian/Extensions/AssetManager.cs +++ b/Programs/Simian/Extensions/AssetManager.cs @@ -143,7 +143,7 @@ namespace Simian.Extensions return; } - uint size = Helpers.BytesToUInt(xfer.DataPacket.Data); + uint size = Utils.BytesToUInt(xfer.DataPacket.Data); asset.AssetData = new byte[size]; Buffer.BlockCopy(xfer.DataPacket.Data, 4, asset.AssetData, 0, xfer.DataPacket.Data.Length - 4); @@ -232,7 +232,7 @@ namespace Simian.Extensions { // Parse the request UUID assetID = new UUID(request.TransferInfo.Params, 0); - AssetType type = (AssetType)(sbyte)Helpers.BytesToInt(request.TransferInfo.Params, 16); + AssetType type = (AssetType)(sbyte)Utils.BytesToInt(request.TransferInfo.Params, 16); // Set the response channel type response.TransferInfo.ChannelType = (int)ChannelType.Asset; @@ -240,7 +240,7 @@ namespace Simian.Extensions // Params response.TransferInfo.Params = new byte[20]; Buffer.BlockCopy(assetID.GetBytes(), 0, response.TransferInfo.Params, 0, 16); - Buffer.BlockCopy(Helpers.IntToBytes((int)type), 0, response.TransferInfo.Params, 16, 4); + Buffer.BlockCopy(Utils.IntToBytes((int)type), 0, response.TransferInfo.Params, 16, 4); // Check if we have this asset Asset asset; @@ -306,7 +306,7 @@ namespace Simian.Extensions { UUID agentID = new UUID(request.TransferInfo.Params, 0); UUID sessionID = new UUID(request.TransferInfo.Params, 16); - EstateAssetType type = (EstateAssetType)Helpers.BytesToInt(request.TransferInfo.Params, 32); + EstateAssetType type = (EstateAssetType)Utils.BytesToInt(request.TransferInfo.Params, 32); Logger.Log("Please implement estate asset transfers", Helpers.LogLevel.Warning); } @@ -318,7 +318,7 @@ namespace Simian.Extensions UUID taskID = new UUID(request.TransferInfo.Params, 48); UUID itemID = new UUID(request.TransferInfo.Params, 64); UUID assetID = new UUID(request.TransferInfo.Params, 80); - AssetType type = (AssetType)(sbyte)Helpers.BytesToInt(request.TransferInfo.Params, 96); + AssetType type = (AssetType)(sbyte)Utils.BytesToInt(request.TransferInfo.Params, 96); if (taskID != UUID.Zero) { diff --git a/Programs/Simian/Extensions/AuthFreeForAll.cs b/Programs/Simian/Extensions/AuthFreeForAll.cs index 31266765..e7dca96e 100644 --- a/Programs/Simian/Extensions/AuthFreeForAll.cs +++ b/Programs/Simian/Extensions/AuthFreeForAll.cs @@ -36,7 +36,7 @@ namespace Simian.Extensions agent.CreationTime = Utils.DateTimeToUnixTime(DateTime.Now); agent.CurrentLookAt = Vector3.Zero; agent.CurrentPosition = new Vector3(128f, 128f, 25f); - agent.CurrentRegionHandle = Helpers.UIntsToLong(Simian.REGION_X, Simian.REGION_Y); + agent.CurrentRegionHandle = Utils.UIntsToLong(Simian.REGION_X, Simian.REGION_Y); agent.FirstName = firstName; agent.GodLevel = 0; agent.HomeLookAt = agent.CurrentLookAt; diff --git a/Programs/Simian/Extensions/AvatarManager.cs b/Programs/Simian/Extensions/AvatarManager.cs index ad72ee69..d3f9471b 100644 --- a/Programs/Simian/Extensions/AvatarManager.cs +++ b/Programs/Simian/Extensions/AvatarManager.cs @@ -349,7 +349,7 @@ namespace Simian.Extensions UUID itemID = wearing.WearableData[i].ItemID; InventoryObject invObj; - if (agent.Inventory.TryGetValue(itemID, out invObj) && invObj is InventoryItem) + if (Server.Inventory.TryGetInventory(agent.AgentID, itemID, out invObj) && invObj is InventoryItem) assetID = ((InventoryItem)invObj).AssetID; #region Update Wearables diff --git a/Programs/Simian/Extensions/InventoryManager.cs b/Programs/Simian/Extensions/InventoryManager.cs index 68348a44..a11f8527 100644 --- a/Programs/Simian/Extensions/InventoryManager.cs +++ b/Programs/Simian/Extensions/InventoryManager.cs @@ -2,13 +2,20 @@ using System; using System.Collections.Generic; using ExtensionLoader; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenMetaverse.Packets; namespace Simian.Extensions { - public class InventoryManager : IExtension, IInventoryProvider + public class InventoryManager : IExtension, IInventoryProvider, IPersistable { Simian Server; + /// Dictionary of inventories for each agent. Each inventory + /// is also a dictionary itself + Dictionary> Inventory = + new Dictionary>(); + /// Global shared inventory for all agent + Dictionary Library = new Dictionary(); public InventoryManager(Simian server) { @@ -28,6 +35,22 @@ namespace Simian.Extensions { } + Dictionary GetAgentInventory(UUID agentID) + { + Dictionary agentInventory; + if (!Inventory.TryGetValue(agentID, out agentInventory)) + { + Logger.Log("Creating an empty inventory store for agent " + agentID.ToString(), + Helpers.LogLevel.Info); + + agentInventory = new Dictionary(); + lock (Inventory) + Inventory[agentID] = agentInventory; + } + + return agentInventory; + } + void CreateInventoryItemHandler(Packet packet, Agent agent) { CreateInventoryItemPacket create = (CreateInventoryItemPacket)packet; @@ -71,9 +94,10 @@ namespace Simian.Extensions for (int i = 0; i < update.InventoryData.Length; i++) { UpdateInventoryItemPacket.InventoryDataBlock block = update.InventoryData[i]; + Dictionary agentInventory = GetAgentInventory(agent.AgentID); InventoryObject obj; - if (agent.Inventory.TryGetValue(block.ItemID, out obj) && obj is InventoryItem) + if (agentInventory.TryGetValue(block.ItemID, out obj) && obj is InventoryItem) { InventoryItem item = (InventoryItem)obj; @@ -116,12 +140,14 @@ namespace Simian.Extensions bool sendItems = fetch.InventoryData.FetchItems; InventorySortOrder order = (InventorySortOrder)fetch.InventoryData.SortOrder; + Dictionary agentInventory = GetAgentInventory(agent.AgentID); + // TODO: Use OwnerID // TODO: Do we need to obey InventorySortOrder? // FIXME: This packet can become huge very quickly. Add logic to break it up into multiple packets InventoryObject invObject; - if (agent.Inventory.TryGetValue(fetch.InventoryData.FolderID, out invObject) && invObject is InventoryFolder) + if (agentInventory.TryGetValue(fetch.InventoryData.FolderID, out invObject) && invObject is InventoryFolder) { InventoryFolder folder = (InventoryFolder)invObject; @@ -228,12 +254,13 @@ namespace Simian.Extensions for (int i = 0; i < fetch.InventoryData.Length; i++) { UUID itemID = fetch.InventoryData[i].ItemID; + Dictionary agentInventory = GetAgentInventory(agent.AgentID); reply.InventoryData[i] = new FetchInventoryReplyPacket.InventoryDataBlock(); reply.InventoryData[i].ItemID = itemID; InventoryObject obj; - if (agent.Inventory.TryGetValue(itemID, out obj) && obj is InventoryItem) + if (agentInventory.TryGetValue(itemID, out obj) && obj is InventoryItem) { InventoryItem item = (InventoryItem)obj; @@ -277,9 +304,11 @@ namespace Simian.Extensions public bool CreateRootFolder(Agent agent, UUID folderID, string name, UUID ownerID) { - lock (agent.Inventory) + Dictionary agentInventory = GetAgentInventory(agent.AgentID); + + lock (agentInventory) { - if (!agent.Inventory.ContainsKey(folderID)) + if (!agentInventory.ContainsKey(folderID)) { InventoryFolder folder = new InventoryFolder(); folder.Name = name; @@ -292,7 +321,7 @@ namespace Simian.Extensions Logger.DebugLog("Creating root inventory folder " + folder.Name); - agent.Inventory[folder.ID] = folder; + agentInventory[folder.ID] = folder; return true; } else @@ -312,14 +341,16 @@ namespace Simian.Extensions if (parentID == UUID.Zero) parentID = agent.InventoryRoot; - lock (agent.Inventory) + Dictionary agentInventory = GetAgentInventory(agent.AgentID); + + lock (agentInventory) { InventoryObject parent; - if (agent.Inventory.TryGetValue(parentID, out parent) && parent is InventoryFolder) + if (agentInventory.TryGetValue(parentID, out parent) && parent is InventoryFolder) { InventoryFolder parentFolder = (InventoryFolder)parent; - if (!agent.Inventory.ContainsKey(folderID)) + if (!agentInventory.ContainsKey(folderID)) { InventoryFolder folder = new InventoryFolder(); folder.Name = name; @@ -332,7 +363,7 @@ namespace Simian.Extensions Logger.DebugLog("Creating inventory folder " + folder.Name); - agent.Inventory[folder.ID] = folder; + agentInventory[folder.ID] = folder; lock (parentFolder.Children.Dictionary) parentFolder.Children.Dictionary[folder.ID] = folder; @@ -363,10 +394,12 @@ namespace Simian.Extensions if (parentID == UUID.Zero) parentID = agent.InventoryRoot; - lock (agent.Inventory) + Dictionary agentInventory = GetAgentInventory(agent.AgentID); + + lock (agentInventory) { InventoryObject parent; - if (agent.Inventory.TryGetValue(parentID, out parent) && parent is InventoryFolder) + if (agentInventory.TryGetValue(parentID, out parent) && parent is InventoryFolder) { InventoryFolder parentFolder = (InventoryFolder)parent; @@ -390,7 +423,7 @@ namespace Simian.Extensions item.InventoryType, item.AssetType)); // Store the inventory item - agent.Inventory[item.ID] = item; + agentInventory[item.ID] = item; lock (parentFolder.Children.Dictionary) parentFolder.Children.Dictionary[item.ID] = item; @@ -445,5 +478,103 @@ namespace Simian.Extensions } } } + + public bool TryGetInventory(UUID agentID, UUID objectID, out InventoryObject obj) + { + Dictionary inventory; + + if (Inventory.TryGetValue(agentID, out inventory)) + { + if (inventory.TryGetValue(objectID, out obj)) + return true; + } + + obj = null; + return false; + } + + #region Persistance + + LLSDMap SerializeInventoryItem(InventoryItem item) + { + LLSDMap itemMap = new LLSDMap(16); + itemMap.Add("ID", LLSD.FromUUID(item.ID)); + itemMap.Add("ParentID", LLSD.FromUUID(item.ParentID)); + itemMap.Add("Name", LLSD.FromString(item.Name)); + itemMap.Add("OwnerID", LLSD.FromUUID(item.OwnerID)); + itemMap.Add("AssetID", LLSD.FromUUID(item.AssetID)); + itemMap.Add("AssetType", LLSD.FromInteger((sbyte)item.AssetType)); + itemMap.Add("InventoryType", LLSD.FromInteger((sbyte)item.InventoryType)); + itemMap.Add("CreatorID", LLSD.FromUUID(item.CreatorID)); + itemMap.Add("GroupID", LLSD.FromUUID(item.GroupID)); + itemMap.Add("Description", LLSD.FromString(item.Description)); + itemMap.Add("GroupOwned", LLSD.FromBoolean(item.GroupOwned)); + itemMap.Add("Permissions", item.Permissions.GetLLSD()); + itemMap.Add("SalePrice", LLSD.FromInteger(item.SalePrice)); + itemMap.Add("SaleType", LLSD.FromInteger((byte)item.SaleType)); + itemMap.Add("Flags", LLSD.FromUInteger((uint)item.Flags)); + itemMap.Add("CreationDate", LLSD.FromDate(item.CreationDate)); + return itemMap; + } + + LLSDMap SerializeInventoryFolder(InventoryFolder folder) + { + LLSDMap folderMap = new LLSDMap(6); + folderMap.Add("ID", LLSD.FromUUID(folder.ID)); + folderMap.Add("ParentID", LLSD.FromUUID(folder.ParentID)); + folderMap.Add("Name", LLSD.FromString(folder.Name)); + folderMap.Add("OwnerID", LLSD.FromUUID(folder.OwnerID)); + folderMap.Add("PreferredType", LLSD.FromInteger((sbyte)folder.PreferredType)); + folderMap.Add("Version", LLSD.FromInteger(folder.Version)); + return folderMap; + } + + LLSDMap SerializeInventory(Dictionary agentInventory) + { + LLSDMap map = new LLSDMap(agentInventory.Count); + + // FIXME: + + return map; + } + + public LLSD Serialize() + { + LLSDMap map = new LLSDMap(Inventory.Count); + int itemCount = 0; + + foreach (KeyValuePair> kvp in Inventory) + { + map.Add(kvp.Key.ToString(), SerializeInventory(kvp.Value)); + itemCount += kvp.Value.Count; + } + + Logger.Log(String.Format("Serializing the inventory store with {0} items", itemCount), + Helpers.LogLevel.Info); + + return map; + } + + public void Deserialize(LLSD serialized) + { + //accounts.Clear(); + + //LLSDArray array = (LLSDArray)serialized; + + //for (int i = 0; i < array.Count; i++) + //{ + // Agent agent = new Agent(); + // object agentRef = (object)agent; + // LLSD.DeserializeMembers(ref agentRef, (LLSDMap)array[i]); + // agent = (Agent)agentRef; + + // accounts.Add(agent.FullName, agent.AgentID, agent); + //} + + //Logger.Log(String.Format("Deserialized the agent store with {0} entries", accounts.Count), + // Helpers.LogLevel.Info); + } + + #endregion Persistance } } diff --git a/Programs/Simian/Extensions/ObjectManager.cs b/Programs/Simian/Extensions/ObjectManager.cs index 25940f3d..7b616aa7 100644 --- a/Programs/Simian/Extensions/ObjectManager.cs +++ b/Programs/Simian/Extensions/ObjectManager.cs @@ -558,7 +558,8 @@ namespace Simian.Extensions break; case DeRezDestination.TrashFolder: InventoryObject invObj; - if (agent.Inventory.TryGetValue(derez.AgentBlock.DestinationID, out invObj) && invObj is InventoryFolder) + if (Server.Inventory.TryGetInventory(agent.AgentID, derez.AgentBlock.DestinationID, out invObj) && + invObj is InventoryFolder) { // FIXME: Handle children InventoryFolder trash = (InventoryFolder)invObj; diff --git a/Programs/Simian/Interfaces/IInventoryProvider.cs b/Programs/Simian/Interfaces/IInventoryProvider.cs index 997e42c0..b21a39fa 100644 --- a/Programs/Simian/Interfaces/IInventoryProvider.cs +++ b/Programs/Simian/Interfaces/IInventoryProvider.cs @@ -11,5 +11,6 @@ namespace Simian bool CreateFolder(Agent agent, UUID folderID, string name, AssetType preferredType, UUID parentID, UUID ownerID); bool CreateRootFolder(Agent agent, UUID folderID, string name, UUID ownerID); + bool TryGetInventory(UUID agentID, UUID objectID, out InventoryObject obj); } } diff --git a/Programs/Simian/Interfaces/IPersistable.cs b/Programs/Simian/Interfaces/IPersistable.cs index 16c0a73a..a5e9e787 100644 --- a/Programs/Simian/Interfaces/IPersistable.cs +++ b/Programs/Simian/Interfaces/IPersistable.cs @@ -5,8 +5,6 @@ namespace Simian { public interface IPersistable { - string StoreName { get; } - LLSD Serialize(); void Deserialize(LLSD serialized); } diff --git a/Programs/Simian/Simian.cs b/Programs/Simian/Simian.cs index 362400c5..38e6da8c 100644 --- a/Programs/Simian/Simian.cs +++ b/Programs/Simian/Simian.cs @@ -54,7 +54,7 @@ namespace Simian InitHttpServer(HttpPort, ssl); - RegionHandle = Helpers.UIntsToLong(REGION_X, REGION_Y); + RegionHandle = Utils.UIntsToLong(REGION_X, REGION_Y); try { @@ -359,7 +359,7 @@ namespace Simian response.Reason = String.Empty; uint regionX, regionY; - Helpers.LongToUInts(agent.CurrentRegionHandle, out regionX, out regionY); + Utils.LongToUInts(agent.CurrentRegionHandle, out regionX, out regionY); response.RegionX = regionX; response.RegionY = regionY; diff --git a/Programs/examples/GUITestClient/Interfaces/HeightmapInterface.cs b/Programs/examples/GUITestClient/Interfaces/HeightmapInterface.cs index adf8c5cf..996ee629 100644 --- a/Programs/examples/GUITestClient/Interfaces/HeightmapInterface.cs +++ b/Programs/examples/GUITestClient/Interfaces/HeightmapInterface.cs @@ -67,7 +67,7 @@ namespace OpenMetaverse.GUITestClient for (int xp = 0; xp < 16; xp++) { float height = data[yp * 16 + xp]; - int colorVal = Helpers.FloatToByte(height, 0.0f, 60.0f); + int colorVal = Utils.FloatToByte(height, 0.0f, 60.0f); int lesserVal = (int)((float)colorVal * 0.75f); Color color; diff --git a/Programs/examples/Heightmap/frmHeightmap.cs b/Programs/examples/Heightmap/frmHeightmap.cs index 30f4649e..2817ed65 100644 --- a/Programs/examples/Heightmap/frmHeightmap.cs +++ b/Programs/examples/Heightmap/frmHeightmap.cs @@ -151,16 +151,16 @@ namespace Heightmap { float maxVal = (float)Math.Log(Math.Abs(512+1-simulator.WaterHeight),2); float lgHeight = (float)Math.Log(Math.Abs(height + 1 - simulator.WaterHeight), 2); - int colorVal1 = Helpers.FloatToByte(lgHeight, simulator.WaterHeight, maxVal); - int colorVal2 = Helpers.FloatToByte(height, simulator.WaterHeight, 25.0f); + int colorVal1 = Utils.FloatToByte(lgHeight, simulator.WaterHeight, maxVal); + int colorVal2 = Utils.FloatToByte(height, simulator.WaterHeight, 25.0f); color = Color.FromArgb(255, colorVal2, colorVal1); } else { const float minVal = -5.0f; float maxVal = simulator.WaterHeight; - int colorVal1 = Helpers.FloatToByte(height, -5.0f, minVal+(maxVal-minVal)*1.5f); - int colorVal2 = Helpers.FloatToByte(height, -5.0f, maxVal); + int colorVal1 = Utils.FloatToByte(height, -5.0f, minVal + (maxVal - minVal) * 1.5f); + int colorVal2 = Utils.FloatToByte(height, -5.0f, maxVal); color = Color.FromArgb(colorVal1, colorVal2, 255); } patch.SetPixel(xp, yp, color); // 0, 0 is top left diff --git a/Programs/examples/TestClient/Commands/Movement/FollowCommand.cs b/Programs/examples/TestClient/Commands/Movement/FollowCommand.cs index 96678e2b..ee28a4ad 100644 --- a/Programs/examples/TestClient/Commands/Movement/FollowCommand.cs +++ b/Programs/examples/TestClient/Commands/Movement/FollowCommand.cs @@ -134,7 +134,7 @@ namespace OpenMetaverse.TestClient if (distance > DISTANCE_BUFFER) { uint regionX, regionY; - Helpers.LongToUInts(Client.Network.Simulators[i].Handle, out regionX, out regionY); + Utils.LongToUInts(Client.Network.Simulators[i].Handle, out regionX, out regionY); double xTarget = (double)targetAv.Position.X + (double)regionX; double yTarget = (double)targetAv.Position.Y + (double)regionY; diff --git a/Programs/examples/TestClient/Commands/Movement/MoveToCommand.cs b/Programs/examples/TestClient/Commands/Movement/MoveToCommand.cs index 600d7082..cfde739a 100644 --- a/Programs/examples/TestClient/Commands/Movement/MoveToCommand.cs +++ b/Programs/examples/TestClient/Commands/Movement/MoveToCommand.cs @@ -19,7 +19,7 @@ namespace OpenMetaverse.TestClient.Commands.Movement return "Usage: moveto x y z"; uint regionX, regionY; - Helpers.LongToUInts(Client.Network.CurrentSim.Handle, out regionX, out regionY); + Utils.LongToUInts(Client.Network.CurrentSim.Handle, out regionX, out regionY); double x, y, z; if (!Double.TryParse(args[0], out x) || diff --git a/Programs/examples/TestClient/Commands/Stats/RegionInfoCommand.cs b/Programs/examples/TestClient/Commands/Stats/RegionInfoCommand.cs index 589323f2..16df2e7d 100644 --- a/Programs/examples/TestClient/Commands/Stats/RegionInfoCommand.cs +++ b/Programs/examples/TestClient/Commands/Stats/RegionInfoCommand.cs @@ -20,7 +20,7 @@ namespace OpenMetaverse.TestClient output.Append("UUID: "); output.AppendLine(Client.Network.CurrentSim.ID.ToString()); uint x, y; - Helpers.LongToUInts(Client.Network.CurrentSim.Handle, out x, out y); + Utils.LongToUInts(Client.Network.CurrentSim.Handle, out x, out y); output.AppendLine(String.Format("Handle: {0} (X: {1} Y: {2})", Client.Network.CurrentSim.Handle, x, y)); output.Append("Access: "); output.AppendLine(Client.Network.CurrentSim.Access.ToString());