Esempio n. 1
0
        /// <summary>
        /// Constructor used for building a packet where the length of the data
        /// is known in advance. This is being phased out in favor of
        /// pre-assembling the data or using PacketBuilder.BuildPacket().
        /// </summary>
        /// <param name="command">The name of the command in the message template</param>
        /// <param name="protocol">A reference to the ProtocolManager instance</param>
        /// <param name="length">The length of the packet data</param>
        public Packet(string command, ProtocolManager protocol, int length)
        {
            Protocol = protocol;
            Data     = new byte[length];
            Layout   = protocol.Command(command);

            if (Layout == null)
            {
                Console.WriteLine("Attempting to build a packet with invalid command \"" + command + "\"");

                // Create an empty Layout
                Layout        = new MapPacket();
                Layout.Blocks = new ArrayList();
                return;
            }

            switch (Layout.Frequency)
            {
            case PacketFrequency.Low:
                // Set the low frequency identifier bits
                byte[] lowHeader = { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
                Array.Copy(lowHeader, 0, Data, 0, 6);

                // Store the packet ID in network order
                Data[6] = (byte)(Layout.ID / 256);
                Data[7] = (byte)(Layout.ID % 256);

                break;

            case PacketFrequency.Medium:
                // Set the medium frequency identifier bits
                byte[] mediumHeader = { 0x00, 0x00, 0x00, 0x00, 0xFF };
                Array.Copy(mediumHeader, 0, Data, 0, 5);
                Data[5] = (byte)Layout.ID;

                break;

            case PacketFrequency.High:
                // Set the high frequency identifier bits
                byte[] highHeader = { 0x00, 0x00, 0x00, 0x00 };
                Array.Copy(highHeader, 0, Data, 0, 4);
                Data[4] = (byte)Layout.ID;

                break;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// This is a special constructor created specifically for optimizing
        /// SLProxy, do not use it under any circumstances.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <param name="protocol"></param>
        /// <param name="layout"></param>
        /// <param name="copy"></param>
        public Packet(byte[] data, int length, ProtocolManager protocol, MapPacket layout, bool copy)
        {
            Protocol = protocol;
            Layout   = layout;

            if (Layout == null)
            {
                // Create an empty MapPacket
                Layout        = new MapPacket();
                Layout.Blocks = new ArrayList();
            }

            if (copy)
            {
                // Copy the network byte array to this packet's byte array
                Data = new byte[length];
                Array.Copy(data, 0, Data, 0, length);
            }
            else
            {
                // Use the buffer we got for Data
                Data = data;
            }
        }
    // UnregisterDelegates: unregister delegates for each packet in an array of packet maps
    private static void UnregisterDelegates(Proxy proxy, MapPacket[] maps)
    {
        foreach (MapPacket map in maps)
            if (map != null) {
                loggedPackets.Remove(map.Name);

                if (map.Name != "ChatFromViewer") {
                    proxy.RemoveDelegate(map.Name, Direction.Incoming);
                    proxy.RemoveDelegate(map.Name, Direction.Outgoing);
                }
            }
    }
    // RegisterDelegates: register delegates for each packet in an array of packet maps
    private static void RegisterDelegates(Proxy proxy, MapPacket[] maps)
    {
        foreach (MapPacket map in maps)
            if (map != null) {
                loggedPackets[map.Name] = null;

                if (map.Name != "ChatFromViewer") {
                    proxy.AddDelegate(map.Name, Direction.Incoming, new PacketDelegate(AnalyzeIn));
                    proxy.AddDelegate(map.Name, Direction.Outgoing, new PacketDelegate(AnalyzeOut));
                }
            }
    }
Esempio n. 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mapFile"></param>
        private void LoadMapFile(string mapFile)
        {
            FileStream map;
            ushort     low    = 1;
            ushort     medium = 1;
            ushort     high   = 1;

            // Load the protocol map file
            try
            {
                map = new FileStream(mapFile, FileMode.Open, FileAccess.Read);
            }
            catch (Exception e)
            {
                throw new Exception("Map file error", e);
            }

            try
            {
                StreamReader r = new StreamReader(map);
                r.BaseStream.Seek(0, SeekOrigin.Begin);
                string    newline;
                string    trimmedline;
                bool      inPacket      = false;
                bool      inBlock       = false;
                MapPacket currentPacket = null;
                MapBlock  currentBlock  = null;
                char[]    trimArray     = new char[] { ' ', '\t' };

                // While not at the end of the file
                while (r.Peek() > -1)
                {
                    #region ParseMap

                    newline     = r.ReadLine();
                    trimmedline = System.Text.RegularExpressions.Regex.Replace(newline, @"\s+", " ");
                    trimmedline = trimmedline.Trim(trimArray);

                    if (!inPacket)
                    {
                        // Outside of all packet blocks

                        if (trimmedline == "{")
                        {
                            inPacket = true;
                        }
                    }
                    else
                    {
                        // Inside of a packet block

                        if (!inBlock)
                        {
                            // Inside a packet block, outside of the blocks

                            if (trimmedline == "{")
                            {
                                inBlock = true;
                            }
                            else if (trimmedline == "}")
                            {
                                // Reached the end of the packet
                                currentPacket.Blocks.Sort();
                                inPacket = false;
                            }
                            else
                            {
                                // The packet header
                                #region ParsePacketHeader

                                // Splice the string in to tokens
                                string[] tokens = trimmedline.Split(new char[] { ' ', '\t' });

                                if (tokens.Length > 3)
                                {
                                    //Hash packet name to insure correct keyword ordering
                                    KeywordPosition(tokens[0]);

                                    if (tokens[1] == "Fixed")
                                    {
                                        // Remove the leading "0x"
                                        if (tokens[2].Substring(0, 2) == "0x")
                                        {
                                            tokens[2] = tokens[2].Substring(2, tokens[2].Length - 2);
                                        }

                                        uint fixedID = UInt32.Parse(tokens[2], System.Globalization.NumberStyles.HexNumber);
                                        // Truncate the id to a short
                                        fixedID                   ^= 0xFFFF0000;
                                        LowMaps[fixedID]           = new MapPacket();
                                        LowMaps[fixedID].ID        = (ushort)fixedID;
                                        LowMaps[fixedID].Frequency = PacketFrequency.Low;
                                        LowMaps[fixedID].Name      = tokens[0];
                                        LowMaps[fixedID].Trusted   = (tokens[3] == "Trusted");
                                        LowMaps[fixedID].Encoded   = (tokens[4] == "Zerocoded");
                                        LowMaps[fixedID].Blocks    = new List <MapBlock>();

                                        currentPacket = LowMaps[fixedID];
                                    }
                                    else if (tokens[1] == "Low")
                                    {
                                        LowMaps[low]           = new MapPacket();
                                        LowMaps[low].ID        = low;
                                        LowMaps[low].Frequency = PacketFrequency.Low;
                                        LowMaps[low].Name      = tokens[0];
                                        LowMaps[low].Trusted   = (tokens[2] == "Trusted");
                                        LowMaps[low].Encoded   = (tokens[3] == "Zerocoded");
                                        LowMaps[low].Blocks    = new List <MapBlock>();

                                        currentPacket = LowMaps[low];

                                        low++;
                                    }
                                    else if (tokens[1] == "Medium")
                                    {
                                        MediumMaps[medium]           = new MapPacket();
                                        MediumMaps[medium].ID        = medium;
                                        MediumMaps[medium].Frequency = PacketFrequency.Medium;
                                        MediumMaps[medium].Name      = tokens[0];
                                        MediumMaps[medium].Trusted   = (tokens[2] == "Trusted");
                                        MediumMaps[medium].Encoded   = (tokens[3] == "Zerocoded");
                                        MediumMaps[medium].Blocks    = new List <MapBlock>();

                                        currentPacket = MediumMaps[medium];

                                        medium++;
                                    }
                                    else if (tokens[1] == "High")
                                    {
                                        HighMaps[high]           = new MapPacket();
                                        HighMaps[high].ID        = high;
                                        HighMaps[high].Frequency = PacketFrequency.High;
                                        HighMaps[high].Name      = tokens[0];
                                        HighMaps[high].Trusted   = (tokens[2] == "Trusted");
                                        HighMaps[high].Encoded   = (tokens[3] == "Zerocoded");
                                        HighMaps[high].Blocks    = new List <MapBlock>();

                                        currentPacket = HighMaps[high];

                                        high++;
                                    }
                                    else
                                    {
                                        Client.Log("Unknown packet frequency", Helpers.LogLevel.Error);
                                    }
                                }

                                #endregion
                            }
                        }
                        else
                        {
                            if (trimmedline.Length > 0 && trimmedline.Substring(0, 1) == "{")
                            {
                                // A field
                                #region ParseField

                                MapField field = new MapField();

                                // Splice the string in to tokens
                                string[] tokens = trimmedline.Split(new char[] { ' ', '\t' });

                                field.Name            = tokens[1];
                                field.KeywordPosition = KeywordPosition(field.Name);
                                field.Type            = (FieldType)Enum.Parse(typeof(FieldType), tokens[2], true);

                                if (tokens[3] != "}")
                                {
                                    field.Count = Int32.Parse(tokens[3]);
                                }
                                else
                                {
                                    field.Count = 1;
                                }

                                // Save this field to the current block
                                currentBlock.Fields.Add(field);

                                #endregion
                            }
                            else if (trimmedline == "}")
                            {
                                currentBlock.Fields.Sort();
                                inBlock = false;
                            }
                            else if (trimmedline.Length != 0 && trimmedline.Substring(0, 2) != "//")
                            {
                                // The block header
                                #region ParseBlockHeader

                                currentBlock = new MapBlock();

                                // Splice the string in to tokens
                                string[] tokens = trimmedline.Split(new char[] { ' ', '\t' });

                                currentBlock.Name            = tokens[0];
                                currentBlock.KeywordPosition = KeywordPosition(currentBlock.Name);
                                currentBlock.Fields          = new List <MapField>();
                                currentPacket.Blocks.Add(currentBlock);

                                if (tokens[1] == "Single")
                                {
                                    currentBlock.Count = 1;
                                }
                                else if (tokens[1] == "Multiple")
                                {
                                    currentBlock.Count = Int32.Parse(tokens[2]);
                                }
                                else if (tokens[1] == "Variable")
                                {
                                    currentBlock.Count = -1;
                                }
                                else
                                {
                                    Client.Log("Unknown block frequency", Helpers.LogLevel.Error);
                                }

                                #endregion
                            }
                        }
                    }

                    #endregion
                }

                r.Close();
                map.Close();
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="map"></param>
        /// <param name="frequency"></param>
        private void PrintOneMap(MapPacket[] map, string frequency)
        {
            int i;

            for (i = 0; i < map.Length; ++i)
            {
                if (map[i] != null)
                {
                    Console.WriteLine("{0} {1,5} - {2} - {3} - {4}", frequency, i, map[i].Name,
                        map[i].Trusted ? "Trusted" : "Untrusted",
                        map[i].Encoded ? "Unencoded" : "Zerocoded");

                    foreach (MapBlock block in map[i].Blocks)
                    {
                        if (block.Count == -1)
                        {
                            Console.WriteLine("\t{0,4} {1} (Variable)", block.KeywordPosition, block.Name);
                        }
                        else
                        {
                            Console.WriteLine("\t{0,4} {1} ({2})", block.KeywordPosition, block.Name, block.Count);
                        }

                        foreach (MapField field in block.Fields)
                        {
                            Console.WriteLine("\t\t{0,4} {1} ({2} / {3})", field.KeywordPosition, field.Name,
                                field.Type, field.Count);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mapFile"></param>
        private void LoadMapFile(string mapFile)
        {
            FileStream map;
            ushort low = 1;
            ushort medium = 1;
            ushort high = 1;

            // Load the protocol map file
            try
            {
                map = new FileStream(mapFile, FileMode.Open, FileAccess.Read);
            }
            catch(Exception e)
            {
                throw new Exception("Map file error", e);
            }

            try
            {
                StreamReader r = new StreamReader(map);
                r.BaseStream.Seek(0, SeekOrigin.Begin);
                string newline;
                string trimmedline;
                bool inPacket = false;
                bool inBlock = false;
                MapPacket currentPacket = null;
                MapBlock currentBlock = null;
                char[] trimArray = new char[] {' ', '\t'};

                // While not at the end of the file
                while (r.Peek() > -1)
                {
                    #region ParseMap

                    newline = r.ReadLine();
                    trimmedline = System.Text.RegularExpressions.Regex.Replace(newline, @"\s+", " ");
                    trimmedline = trimmedline.Trim(trimArray);

                    if (!inPacket)
                    {
                        // Outside of all packet blocks

                        if (trimmedline == "{")
                        {
                            inPacket = true;
                        }
                    }
                    else
                    {
                        // Inside of a packet block

                        if (!inBlock)
                        {
                            // Inside a packet block, outside of the blocks

                            if (trimmedline == "{")
                            {
                                inBlock = true;
                            }
                            else if (trimmedline == "}")
                            {
                                // Reached the end of the packet
                                currentPacket.Blocks.Sort();
                                inPacket = false;
                            }
                            else
                            {
                                // The packet header
                                #region ParsePacketHeader

                                // Splice the string in to tokens
                                string[] tokens = trimmedline.Split(new char[] {' ', '\t'});

                                if (tokens.Length > 3)
                                {
                                    //Hash packet name to insure correct keyword ordering
                                    KeywordPosition(tokens[0]);

                                    if (tokens[1] == "Fixed")
                                    {
                                        // Remove the leading "0x"
                                        if (tokens[2].Substring(0, 2) == "0x")
                                        {
                                            tokens[2] = tokens[2].Substring(2, tokens[2].Length - 2);
                                        }

                                        uint fixedID = UInt32.Parse(tokens[2], System.Globalization.NumberStyles.HexNumber);
                                        // Truncate the id to a short
                                        fixedID ^= 0xFFFF0000;
                                        LowMaps[fixedID] = new MapPacket();
                                        LowMaps[fixedID].ID = (ushort)fixedID;
                                        LowMaps[fixedID].Frequency = PacketFrequency.Low;
                                        LowMaps[fixedID].Name = tokens[0];
                                        LowMaps[fixedID].Trusted = (tokens[3] == "Trusted");
                                        LowMaps[fixedID].Encoded = (tokens[4] == "Zerocoded");
                                        LowMaps[fixedID].Blocks = new List<MapBlock>();

                                        currentPacket = LowMaps[fixedID];
                                    }
                                    else if (tokens[1] == "Low")
                                    {
                                        LowMaps[low] = new MapPacket();
                                        LowMaps[low].ID = low;
                                        LowMaps[low].Frequency = PacketFrequency.Low;
                                        LowMaps[low].Name = tokens[0];
                                        LowMaps[low].Trusted = (tokens[2] == "Trusted");
                                        LowMaps[low].Encoded = (tokens[3] == "Zerocoded");
                                        LowMaps[low].Blocks = new List<MapBlock>();

                                        currentPacket = LowMaps[low];

                                        low++;
                                    }
                                    else if (tokens[1] == "Medium")
                                    {
                                        MediumMaps[medium] = new MapPacket();
                                        MediumMaps[medium].ID = medium;
                                        MediumMaps[medium].Frequency = PacketFrequency.Medium;
                                        MediumMaps[medium].Name = tokens[0];
                                        MediumMaps[medium].Trusted = (tokens[2] == "Trusted");
                                        MediumMaps[medium].Encoded = (tokens[3] == "Zerocoded");
                                        MediumMaps[medium].Blocks = new List<MapBlock>();

                                        currentPacket = MediumMaps[medium];

                                        medium++;
                                    }
                                    else if (tokens[1] == "High")
                                    {
                                        HighMaps[high] = new MapPacket();
                                        HighMaps[high].ID = high;
                                        HighMaps[high].Frequency = PacketFrequency.High;
                                        HighMaps[high].Name = tokens[0];
                                        HighMaps[high].Trusted = (tokens[2] == "Trusted");
                                        HighMaps[high].Encoded = (tokens[3] == "Zerocoded");
                                        HighMaps[high].Blocks = new List<MapBlock>();

                                        currentPacket = HighMaps[high];

                                        high++;
                                    }
                                    else
                                    {
                                        Client.Log("Unknown packet frequency", Helpers.LogLevel.Error);
                                    }
                                }

                                #endregion
                            }
                        }
                        else
                        {
                            if (trimmedline.Length > 0 && trimmedline.Substring(0, 1) == "{")
                            {
                                // A field
                                #region ParseField

                                MapField field = new MapField();

                                // Splice the string in to tokens
                                string[] tokens = trimmedline.Split(new char[] {' ', '\t'});

                                field.Name = tokens[1];
                                field.KeywordPosition = KeywordPosition(field.Name);
                                field.Type = (FieldType)Enum.Parse(typeof(FieldType), tokens[2], true);

                                if (tokens[3] != "}")
                                {
                                    field.Count = Int32.Parse(tokens[3]);
                                }
                                else
                                {
                                    field.Count = 1;
                                }

                                // Save this field to the current block
                                currentBlock.Fields.Add(field);

                                #endregion
                            }
                            else if (trimmedline == "}")
                            {
                                currentBlock.Fields.Sort();
                                inBlock = false;
                            }
                            else if (trimmedline.Length != 0 && trimmedline.Substring(0, 2) != "//")
                            {
                                // The block header
                                #region ParseBlockHeader

                                currentBlock = new MapBlock();

                                // Splice the string in to tokens
                                string[] tokens = trimmedline.Split(new char[] {' ', '\t'});

                                currentBlock.Name = tokens[0];
                                currentBlock.KeywordPosition = KeywordPosition(currentBlock.Name);
                                currentBlock.Fields = new List<MapField>();
                                currentPacket.Blocks.Add(currentBlock);

                                if (tokens[1] == "Single")
                                {
                                    currentBlock.Count = 1;
                                }
                                else if (tokens[1] == "Multiple")
                                {
                                    currentBlock.Count = Int32.Parse(tokens[2]);
                                }
                                else if (tokens[1] == "Variable")
                                {
                                    currentBlock.Count = -1;
                                }
                                else
                                {
                                    Client.Log("Unknown block frequency", Helpers.LogLevel.Error);
                                }

                                #endregion
                            }
                        }
                    }

                    #endregion
                }

                r.Close();
                map.Close();
            }
            catch (Exception e)
            {
                throw e;
            }
        }
Esempio n. 8
0
        public static Packet BuildPacket(string name, ProtocolManager protocol, Hashtable blocks, byte flags)
        {
            Hashtable fields;

            byte[] byteArray   = new byte[4096];
            int    length      = 0;
            int    blockCount  = 0;
            int    fieldLength = 0;
            IDictionaryEnumerator blocksEnum;

            MapPacket packetMap = protocol.Command(name);

            // Build the header
            #region Header
            switch (packetMap.Frequency)
            {
            case PacketFrequency.High:
                byteArray[4] = (byte)packetMap.ID;
                length       = 5;
                break;

            case PacketFrequency.Medium:
                byteArray[4] = 0xFF;
                byteArray[5] = (byte)packetMap.ID;
                length       = 6;
                break;

            case PacketFrequency.Low:
                byteArray[4] = 0xFF;
                byteArray[5] = 0xFF;
                byteArray[6] = (byte)(packetMap.ID / 256);
                byteArray[7] = (byte)(packetMap.ID % 256);
                length       = 8;
                break;
            }
            #endregion Header

            foreach (MapBlock blockMap in packetMap.Blocks)
            {
                // If this is a variable count block, count the number of appearances of this block in the
                // passed in Hashtable and prepend a counter byte
                #region VariableSize
                if (blockMap.Count == -1)
                {
                    blockCount = 0;

                    // Count the number of this type of block in the blocks Hashtable
                    blocksEnum = blocks.GetEnumerator();

                    while (blocksEnum.MoveNext())
                    {
                        if ((string)blocksEnum.Value == blockMap.Name)
                        {
                            blockCount++;
                        }
                    }

                    if (blockCount > 255)
                    {
                        throw new Exception("Trying to put more than 255 blocks in a variable block");
                    }

                    // Prepend the blocks with a count
                    byteArray[length] = (byte)blockCount;
                    length++;
                }
                #endregion VariableSize

                // Reset blockCount
                blockCount = 0;

                // Check for blocks of this type in the Hashtable
                #region BuildBlock
                blocksEnum = blocks.GetEnumerator();

                while (blocksEnum.MoveNext())
                {
                    if ((string)blocksEnum.Value == blockMap.Name)
                    {
                        // Found a match of this block
                        if ((blockMap.Count == -1 && blockCount < 255) || blockCount < blockMap.Count)
                        {
                            blockCount++;

                            #region TryBlockTypecast
                            try
                            {
                                fields = (Hashtable)blocksEnum.Key;
                            }
                            catch (Exception e)
                            {
                                throw new Exception("A block Hashtable did not contain a fields Hashtable", e);
                            }
                            #endregion TryBlockTypecast

                            foreach (MapField fieldMap in blockMap.Fields)
                            {
                                if (fields.ContainsKey(fieldMap.Name))
                                {
                                    object field = fields[fieldMap.Name];

                                    #region AddField
                                    switch (fieldMap.Type)
                                    {
                                    case FieldType.U8:
                                        byteArray[length++] = (byte)field;
                                        break;

                                    case FieldType.U16:
                                        ushort fieldUShort = (ushort)field;
                                        byteArray[length++] = (byte)(fieldUShort % 256);
                                        fieldUShort       >>= 8;
                                        byteArray[length++] = (byte)(fieldUShort % 256);
                                        break;

                                    case FieldType.U32:
                                        uint fieldUInt = (uint)field;
                                        byteArray[length++] = (byte)(fieldUInt % 256);
                                        fieldUInt         >>= 8;
                                        byteArray[length++] = (byte)(fieldUInt % 256);
                                        fieldUInt         >>= 8;
                                        byteArray[length++] = (byte)(fieldUInt % 256);
                                        fieldUInt         >>= 8;
                                        byteArray[length++] = (byte)(fieldUInt % 256);
                                        break;

                                    case FieldType.U64:
                                        // FIXME: Apply endianness patch
                                        Array.Copy(((U64)field).GetBytes(), 0, byteArray, length, 8);
                                        length += 8;
                                        break;

                                    case FieldType.S8:
                                        byteArray[length++] = (byte)((sbyte)field);
                                        break;

                                    case FieldType.S16:
                                        // FIXME: Apply endianness patch
                                        Array.Copy(BitConverter.GetBytes((short)field), 0, byteArray, length, 2);
                                        length += 2;
                                        break;

                                    case FieldType.S32:
                                        // FIXME: Apply endianness patch
                                        Array.Copy(BitConverter.GetBytes((int)field), 0, byteArray, length, 4);
                                        length += 4;
                                        break;

                                    case FieldType.S64:
                                        // FIXME: Apply endianness patch
                                        Array.Copy(BitConverter.GetBytes((long)field), 0, byteArray, length, 8);
                                        length += 8;
                                        break;

                                    case FieldType.F32:
                                        Array.Copy(BitConverter.GetBytes((float)field), 0, byteArray, length, 4);
                                        length += 4;
                                        break;

                                    case FieldType.F64:
                                        Array.Copy(BitConverter.GetBytes((double)field), 0, byteArray, length, 8);
                                        length += 8;
                                        break;

                                    case FieldType.LLUUID:
                                        Array.Copy(((LLUUID)field).Data, 0, byteArray, length, 16);
                                        length += 16;
                                        break;

                                    case FieldType.BOOL:
                                        byteArray[length] = (byte)((bool)field == true ? 1 : 0);
                                        length++;
                                        break;

                                    case FieldType.LLVector3:
                                        Array.Copy(((LLVector3)field).GetBytes(), 0, byteArray, length, 12);
                                        length += 12;
                                        break;

                                    case FieldType.LLVector3d:
                                        Array.Copy(((LLVector3d)field).GetBytes(), 0, byteArray, length, 24);
                                        length += 24;
                                        break;

                                    case FieldType.LLVector4:
                                        Array.Copy(((LLVector4)field).GetBytes(), 0, byteArray, length, 16);
                                        length += 16;
                                        break;

                                    case FieldType.LLQuaternion:
                                        Array.Copy(((LLQuaternion)field).GetBytes(), 0, byteArray, length, 16);
                                        length += 16;
                                        break;

                                    case FieldType.IPADDR:
                                        Array.Copy(((IPAddress)field).GetAddressBytes(), 0, byteArray, length, 4);
                                        length += 4;
                                        break;

                                    case FieldType.IPPORT:
                                        ushort fieldIPPort = (ushort)field;
                                        byteArray[length + 1] = (byte)(fieldIPPort % 256);
                                        fieldIPPort         >>= 8;
                                        byteArray[length]     = (byte)(fieldIPPort % 256);
                                        length += 2;
                                        break;

                                    case FieldType.Variable:
                                        if (field.GetType().IsArray)
                                        {
                                            // Assume this is a byte array
                                            fieldLength = ((byte[])field).Length;
                                        }
                                        else
                                        {
                                            // Assume this is a string, add 1 for the null terminator
                                            fieldLength = ((string)field).Length + 1;
                                        }

                                        if (fieldMap.Count == 1)
                                        {
                                            if (fieldLength > 255)
                                            {
                                                throw new Exception("Variable byte field longer than 255 characters");
                                            }

                                            byteArray[length] = (byte)(fieldLength);
                                            length++;
                                        }
                                        else if (fieldMap.Count == 2)
                                        {
                                            if (fieldLength > 1024)
                                            {
                                                throw new Exception("Variable byte field longer than 1024 characters");
                                            }

                                            byteArray[length++] = (byte)(fieldLength % 256);
                                            byteArray[length++] = (byte)(fieldLength / 256);
                                        }
                                        else
                                        {
                                            throw new Exception("Variable field with an unknown count, protocol map error");
                                        }

                                        if (field.GetType().IsArray)
                                        {
                                            // Assume this is a byte array
                                            Array.Copy((byte[])field, 0, byteArray, length, fieldLength);
                                        }
                                        else
                                        {
                                            // Assume this is a string, add 1 for the null terminator
                                            byte[] stringBytes = System.Text.Encoding.UTF8.GetBytes((string)field);
                                            Array.Copy(stringBytes, 0, byteArray, length, stringBytes.Length);
                                            fieldLength = stringBytes.Length + 1;
                                        }

                                        length += fieldLength;

                                        break;

                                    case FieldType.Fixed:
                                        Array.Copy((byte[])field, 0, byteArray, length, fieldMap.Count);
                                        length += fieldMap.Count;
                                        break;

                                    default:
                                        throw new Exception("Unhandled FieldType");
                                    }
                                    #endregion AddField
                                }
                                else
                                {
                                    // This field wasn't passed in, create an empty version
                                    #region EmptyField
                                    if (fieldMap.Type == FieldType.Variable)
                                    {
                                        // Just set the counter to zero and move on
                                        if (fieldMap.Count == 2)
                                        {
                                            length += 2;
                                        }
                                        else
                                        {
                                            if (fieldMap.Count != 1)
                                            {
                                                throw new Exception("Variable length field has an invalid Count");
                                            }

                                            length++;
                                        }
                                    }
                                    else if (fieldMap.Type == FieldType.Fixed)
                                    {
                                        length += fieldMap.Count;
                                    }
                                    else
                                    {
                                        length += (int)protocol.TypeSizes[fieldMap.Type];
                                    }
                                    #endregion EmptyField
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("Too many blocks");
                        }
                    }
                }
                #endregion BuildBlock

                // If this is a fixed count block and it doesn't appear in the Hashtable passed in, create
                // empty filler blocks
                #region EmptyBlock
                if (blockCount == 0 && blockMap.Count != -1)
                {
                    for (int i = 0; i < blockMap.Count; ++i)
                    {
                        foreach (MapField field in blockMap.Fields)
                        {
                            if (field.Type == FieldType.Variable)
                            {
                                length++;
                            }
                            else
                            {
                                length += (int)protocol.TypeSizes[field.Type];
                            }
                        }
                    }
                }
                #endregion EmptyBlock
            }

            Packet packet = new Packet(byteArray, length, protocol);
            packet.Data[0] = flags;
            return(packet);
        }
        /// <summary>
        /// This is a special constructor created specifically for optimizing 
        /// SLProxy, do not use it under any circumstances.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <param name="protocol"></param>
        /// <param name="layout"></param>
        /// <param name="copy"></param>
        public Packet(byte[] data, int length, ProtocolManager protocol, MapPacket layout, bool copy)
        {
            Protocol = protocol;
            Layout = layout;

            if (Layout == null)
            {
                // Create an empty MapPacket
                Layout = new MapPacket();
                Layout.Blocks = new ArrayList();
            }

            if (copy) {
                // Copy the network byte array to this packet's byte array
                Data = new byte[length];
                Array.Copy(data, 0, Data, 0, length);
            }
            else
            {
                // Use the buffer we got for Data
                Data = data;
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Constructor used for building a packet where the length of the data
        /// is known in advance. This is being phased out in favor of 
        /// pre-assembling the data or using PacketBuilder.BuildPacket().
        /// </summary>
        /// <param name="command">The name of the command in the message template</param>
        /// <param name="protocol">A reference to the ProtocolManager instance</param>
        /// <param name="length">The length of the packet data</param>
        public Packet(string command, ProtocolManager protocol, int length)
        {
            Protocol = protocol;
            Data = new byte[length];
            Layout = protocol.Command(command);

            if (Layout == null)
            {
                Console.WriteLine("Attempting to build a packet with invalid command \"" + command + "\"");

                // Create an empty Layout
                Layout = new MapPacket();
                Layout.Blocks = new ArrayList();
                return;
            }

            switch (Layout.Frequency)
            {
                case PacketFrequency.Low:
                    // Set the low frequency identifier bits
                    byte[] lowHeader = {0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF};
                    Array.Copy(lowHeader, 0, Data, 0, 6);

                    // Store the packet ID in network order
                    Data[6] = (byte)(Layout.ID / 256);
                    Data[7] = (byte)(Layout.ID % 256);

                    break;
                case PacketFrequency.Medium:
                    // Set the medium frequency identifier bits
                    byte[] mediumHeader = {0x00, 0x00, 0x00, 0x00, 0xFF};
                    Array.Copy(mediumHeader, 0, Data, 0, 5);
                    Data[5] = (byte)Layout.ID;

                    break;
                case PacketFrequency.High:
                    // Set the high frequency identifier bits
                    byte[] highHeader = {0x00, 0x00, 0x00, 0x00};
                    Array.Copy(highHeader, 0, Data, 0, 4);
                    Data[4] = (byte)Layout.ID;

                    break;
            }
        }