예제 #1
0
        private void BeginReceive()
        {
            decodeThread = new Thread(() =>
            {
                try
                {
                    Dictionary<int, Packet> previousReceivedPacket = new Dictionary<int, Packet>();
                    Dictionary<int, Packet> currentPackets = new Dictionary<int, Packet>();

                    while (true)
                    {

                        #region Basic Header
                        byte basicHeader = (byte)sslStream.ReadByte();
                        List<byte> basicHeaderStorage = new List<byte>();
                        if ((int)basicHeader == 255)
                            Disconnect();

                        int channel = 0;
                        //1 Byte Header
                        if ((basicHeader & 0x03) != 0)
                        {
                            channel = basicHeader & 0x3F;
                            basicHeaderStorage.Add(basicHeader);
                        }
                        //2 Byte Header
                        else if ((basicHeader & 0x01) != 0)
                        {
                            byte byte2 = (byte)sslStream.ReadByte();
                            channel = 64 + byte2;
                            basicHeaderStorage.Add(basicHeader);
                            basicHeaderStorage.Add(byte2);
                        }
                        //3 Byte Header
                        else if ((basicHeader & 0x02) != 0)
                        {
                            byte byte2 = (byte)sslStream.ReadByte();
                            byte byte3 = (byte)sslStream.ReadByte();
                            basicHeaderStorage.Add(basicHeader);
                            basicHeaderStorage.Add(byte2);
                            basicHeaderStorage.Add(byte3);
                            channel = 64 + byte2 + (256 * byte3);
                        }
                        #endregion

                        #region Message Header
                        int headerType = (basicHeader & 0xC0);
                        int headerSize = 0;
                        if (headerType == 0x00)
                            headerSize = 12;
                        else if (headerType == 0x40)
                            headerSize = 8;
                        else if (headerType == 0x80)
                            headerSize = 4;
                        else if (headerType == 0xC0)
                            headerSize = 0;

                        // Retrieve the packet or make a new one
                        if (!currentPackets.ContainsKey(channel))
                        {
                            currentPackets.Add(channel, new Packet());
                        }

                        Packet p = currentPackets[channel];
                        p.AddToRaw(basicHeaderStorage.ToArray());

                        if (headerSize == 12)
                        {
                            //Timestamp
                            byte[] timestamp = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                timestamp[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(timestamp[i]);
                            }

                            //Message Length
                            byte[] messageLength = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                messageLength[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(messageLength[i]);
                            }
                            int size = 0;
                            for (int i = 0; i < 3; i++)
                                size = size * 256 + (messageLength[i] & 0xFF);
                            p.SetSize(size);

                            //Message Type
                            int messageType = sslStream.ReadByte();
                            p.AddToRaw((byte)messageType);
                            p.SetType(messageType);

                            //Message Stream ID
                            byte[] messageStreamID = new byte[4];
                            for (int i = 0; i < 4; i++)
                            {
                                messageStreamID[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(messageStreamID[i]);
                            }
                        }
                        else if (headerSize == 8)
                        {
                            //Timestamp
                            byte[] timestamp = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                timestamp[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(timestamp[i]);
                            }

                            //Message Length
                            byte[] messageLength = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                messageLength[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(messageLength[i]);
                            }
                            int size = 0;
                            for (int i = 0; i < 3; i++)
                                size = size * 256 + (messageLength[i] & 0xFF);
                            p.SetSize(size);

                            //Message Type
                            int messageType = sslStream.ReadByte();
                            p.AddToRaw((byte)messageType);
                            p.SetType(messageType);
                        }
                        else if (headerSize == 4)
                        {
                            //Timestamp
                            byte[] timestamp = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                timestamp[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(timestamp[i]);
                            }

                            if (p.GetSize() == 0 && p.GetPacketType() == 0)
                            {
                                if (previousReceivedPacket.ContainsKey(channel))
                                {
                                    p.SetSize(previousReceivedPacket[channel].GetSize());
                                    p.SetType(previousReceivedPacket[channel].GetPacketType());
                                }
                            }
                        }
                        else if (headerSize == 0)
                        {
                            if (p.GetSize() == 0 && p.GetPacketType() == 0)
                            {
                                if (previousReceivedPacket.ContainsKey(channel))
                                {
                                    p.SetSize(previousReceivedPacket[channel].GetSize());
                                    p.SetType(previousReceivedPacket[channel].GetPacketType());
                                }
                            }
                        }
                        #endregion

                        #region Message Body
                        //DefaultChunkSize is 128
                        for (int i = 0; i < 128; i++)
                        {
                            byte b = (byte)sslStream.ReadByte();
                            p.Add(b);
                            p.AddToRaw(b);

                            if (p.IsComplete())
                                break;
                        }

                        if (!p.IsComplete())
                            continue;

                        if (previousReceivedPacket.ContainsKey(channel))
                            previousReceivedPacket.Remove(channel);

                        previousReceivedPacket.Add(channel, p);

                        if (currentPackets.ContainsKey(channel))
                            currentPackets.Remove(channel);
                        #endregion

                        // Decode result
                        TypedObject result;
                        RTMPSDecoder decoder = new RTMPSDecoder();
                        if (p.GetPacketType() == 0x14) // Connect
                            result = decoder.DecodeConnect(p.GetData());
                        else if (p.GetPacketType() == 0x11) // Invoke
                            result = decoder.DecodeInvoke(p.GetData());
                        else if (p.GetPacketType() == 0x06) // Set peer bandwidth
                        {
                            byte[] data = p.GetData();
                            int windowSize = 0;
                            for (int i = 0; i < 4; i++)
                                windowSize = windowSize * 256 + (data[i] & 0xFF);
                            int type = data[4];
                            continue;
                        }
                        else if (p.GetPacketType() == 0x05) // Window Acknowledgement Size
                        {
                            byte[] data = p.GetData();
                            int windowSize = 0;
                            for (int i = 0; i < 4; i++)
                                windowSize = windowSize * 256 + (data[i] & 0xFF);
                            continue;
                        }
                        else if (p.GetPacketType() == 0x03) // Ack
                        {
                            byte[] data = p.GetData();
                            int ackSize = 0;
                            for (int i = 0; i < 4; i++)
                                ackSize = ackSize * 256 + (data[i] & 0xFF);
                            continue;
                        }
                        else if (p.GetPacketType() == 0x02) //ABORT
                        {
                            byte[] data = p.GetData();
                            continue;
                        }
                        else if (p.GetPacketType() == 0x01) //MaxChunkSize
                        {
                            byte[] data = p.GetData();
                            continue;
                        }
                        else
                        // Skip most messages
                        {
                            continue;
                        }

                        // Store result
                        int? id = result.GetInt("invokeId");

                        //Check to see if the result is valid.
                        //If it isn't, give an error and remove the callback if there is one.
                        if (result["result"].Equals("_error"))
                        {
                            Error(GetErrorMessage(result), GetErrorCode(result), ErrorType.Receive);
                        }

                        if (result["result"].Equals("receive"))
                        {
                            if(result.GetTO("data") != null)
                            {
                                TypedObject to = result.GetTO("data");
                                if (to.ContainsKey("body"))
                                {
                                    if (to["body"] is TypedObject)
                                    {
                                        new Thread(new ThreadStart(() =>
                                            {
                                                TypedObject body = (TypedObject)to["body"];
                                                if (body.type.Equals("com.riotgames.platform.game.GameDTO"))
                                                    MessageReceived(new GameDTO(body));
                                                else if (body.type.Equals("com.riotgames.platform.game.PlayerCredentialsDto"))
                                                    MessageReceived(new PlayerCredentialsDto(body));
                                                else if (body.type.Equals("com.riotgames.platform.game.message.GameNotification"))
                                                    MessageReceived(new GameNotification(body));
                                                else if (body.type.Equals("com.riotgames.platform.matchmaking.SearchingForMatchNotification"))
                                                    MessageReceived(new SearchingForMatchNotification(body));
                                                //MessageReceived(to["body"]);
                                            })).Start();
                                    }
                                }
                            }
                            //MessageReceived(
                        }

                        if (id == null)
                            continue;

                        if (id == 0)
                        {
                        }
                        else if (callbacks.ContainsKey((int)id))
                        {
                            RiotGamesObject cb = callbacks[(int)id];
                            callbacks.Remove((int)id);
                            if (cb != null)
                            {
                                TypedObject messageBody = result.GetTO("data").GetTO("body");
                                new Thread(() =>
                                {
                                    cb.DoCallback(messageBody);
                                }).Start();
                            }
                        }

                        else
                        {
                            results.Add((int)id, result);
                        }

                        pendingInvokes.Remove((int)id);

                    }

                }
                catch (Exception e)
                {
                    if (IsConnected())
                        Error(e.Message, ErrorType.Receive);

                    //Disconnect();
                }
            });
            decodeThread.Start();
        }
예제 #2
0
        private void BeginReceive()
        {
            decodeThread = new Thread(() =>
            {
                try
                {
                    Dictionary <int, Packet> previousReceivedPacket = new Dictionary <int, Packet>();
                    Dictionary <int, Packet> currentPackets         = new Dictionary <int, Packet>();

                    while (true)
                    {
                        #region Basic Header
                        byte basicHeader = (byte)sslStream.ReadByte();
                        List <byte> basicHeaderStorage = new List <byte>();
                        if ((int)basicHeader == 255)
                        {
                            Disconnect();
                        }

                        int channel = 0;
                        //1 Byte Header
                        if ((basicHeader & 0x03) != 0)
                        {
                            channel = basicHeader & 0x3F;
                            basicHeaderStorage.Add(basicHeader);
                        }
                        //2 Byte Header
                        else if ((basicHeader & 0x01) != 0)
                        {
                            byte byte2 = (byte)sslStream.ReadByte();
                            channel    = 64 + byte2;
                            basicHeaderStorage.Add(basicHeader);
                            basicHeaderStorage.Add(byte2);
                        }
                        //3 Byte Header
                        else if ((basicHeader & 0x02) != 0)
                        {
                            byte byte2 = (byte)sslStream.ReadByte();
                            byte byte3 = (byte)sslStream.ReadByte();
                            basicHeaderStorage.Add(basicHeader);
                            basicHeaderStorage.Add(byte2);
                            basicHeaderStorage.Add(byte3);
                            channel = 64 + byte2 + (256 * byte3);
                        }
                        #endregion

                        #region Message Header
                        int headerType = (basicHeader & 0xC0);
                        int headerSize = 0;
                        if (headerType == 0x00)
                        {
                            headerSize = 12;
                        }
                        else if (headerType == 0x40)
                        {
                            headerSize = 8;
                        }
                        else if (headerType == 0x80)
                        {
                            headerSize = 4;
                        }
                        else if (headerType == 0xC0)
                        {
                            headerSize = 0;
                        }

                        // Retrieve the packet or make a new one
                        if (!currentPackets.ContainsKey(channel))
                        {
                            currentPackets.Add(channel, new Packet());
                        }

                        Packet p = currentPackets[channel];
                        p.AddToRaw(basicHeaderStorage.ToArray());

                        if (headerSize == 12)
                        {
                            //Timestamp
                            byte[] timestamp = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                timestamp[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(timestamp[i]);
                            }

                            //Message Length
                            byte[] messageLength = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                messageLength[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(messageLength[i]);
                            }
                            int size = 0;
                            for (int i = 0; i < 3; i++)
                            {
                                size = size * 256 + (messageLength[i] & 0xFF);
                            }
                            p.SetSize(size);

                            //Message Type
                            int messageType = sslStream.ReadByte();
                            p.AddToRaw((byte)messageType);
                            p.SetType(messageType);

                            //Message Stream ID
                            byte[] messageStreamID = new byte[4];
                            for (int i = 0; i < 4; i++)
                            {
                                messageStreamID[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(messageStreamID[i]);
                            }
                        }
                        else if (headerSize == 8)
                        {
                            //Timestamp
                            byte[] timestamp = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                timestamp[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(timestamp[i]);
                            }

                            //Message Length
                            byte[] messageLength = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                messageLength[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(messageLength[i]);
                            }
                            int size = 0;
                            for (int i = 0; i < 3; i++)
                            {
                                size = size * 256 + (messageLength[i] & 0xFF);
                            }
                            p.SetSize(size);

                            //Message Type
                            int messageType = sslStream.ReadByte();
                            p.AddToRaw((byte)messageType);
                            p.SetType(messageType);
                        }
                        else if (headerSize == 4)
                        {
                            //Timestamp
                            byte[] timestamp = new byte[3];
                            for (int i = 0; i < 3; i++)
                            {
                                timestamp[i] = (byte)sslStream.ReadByte();
                                p.AddToRaw(timestamp[i]);
                            }

                            if (p.GetSize() == 0 && p.GetPacketType() == 0)
                            {
                                if (previousReceivedPacket.ContainsKey(channel))
                                {
                                    p.SetSize(previousReceivedPacket[channel].GetSize());
                                    p.SetType(previousReceivedPacket[channel].GetPacketType());
                                }
                            }
                        }
                        else if (headerSize == 0)
                        {
                            if (p.GetSize() == 0 && p.GetPacketType() == 0)
                            {
                                if (previousReceivedPacket.ContainsKey(channel))
                                {
                                    p.SetSize(previousReceivedPacket[channel].GetSize());
                                    p.SetType(previousReceivedPacket[channel].GetPacketType());
                                }
                            }
                        }
                        #endregion

                        #region Message Body
                        //DefaultChunkSize is 128
                        for (int i = 0; i < 128; i++)
                        {
                            byte b = (byte)sslStream.ReadByte();
                            p.Add(b);
                            p.AddToRaw(b);

                            if (p.IsComplete())
                            {
                                break;
                            }
                        }

                        if (!p.IsComplete())
                        {
                            continue;
                        }

                        if (previousReceivedPacket.ContainsKey(channel))
                        {
                            previousReceivedPacket.Remove(channel);
                        }

                        previousReceivedPacket.Add(channel, p);

                        if (currentPackets.ContainsKey(channel))
                        {
                            currentPackets.Remove(channel);
                        }
                        #endregion


                        // Decode result
                        TypedObject result;
                        RTMPSDecoder decoder = new RTMPSDecoder();
                        if (p.GetPacketType() == 0x14)                         // Connect
                        {
                            result = decoder.DecodeConnect(p.GetData());
                        }
                        else if (p.GetPacketType() == 0x11)                         // Invoke
                        {
                            result = decoder.DecodeInvoke(p.GetData());
                        }
                        else if (p.GetPacketType() == 0x06)                         // Set peer bandwidth
                        {
                            byte[] data    = p.GetData();
                            int windowSize = 0;
                            for (int i = 0; i < 4; i++)
                            {
                                windowSize = windowSize * 256 + (data[i] & 0xFF);
                            }
                            int type = data[4];
                            continue;
                        }
                        else if (p.GetPacketType() == 0x05)                         // Window Acknowledgement Size
                        {
                            byte[] data    = p.GetData();
                            int windowSize = 0;
                            for (int i = 0; i < 4; i++)
                            {
                                windowSize = windowSize * 256 + (data[i] & 0xFF);
                            }
                            continue;
                        }
                        else if (p.GetPacketType() == 0x03)                         // Ack
                        {
                            byte[] data = p.GetData();
                            int ackSize = 0;
                            for (int i = 0; i < 4; i++)
                            {
                                ackSize = ackSize * 256 + (data[i] & 0xFF);
                            }
                            continue;
                        }
                        else if (p.GetPacketType() == 0x02)                         //ABORT
                        {
                            byte[] data = p.GetData();
                            continue;
                        }
                        else if (p.GetPacketType() == 0x01)                         //MaxChunkSize
                        {
                            byte[] data = p.GetData();
                            continue;
                        }
                        else
                        // Skip most messages
                        {
                            continue;
                        }

                        // Store result
                        int?id = result.GetInt("invokeId");

                        //Check to see if the result is valid.
                        //If it isn't, give an error and remove the callback if there is one.
                        if (result["result"].Equals("_error"))
                        {
                            Error(GetErrorMessage(result), GetErrorCode(result), ErrorType.Receive);
                        }

                        if (result["result"].Equals("receive"))
                        {
                            if (result.GetTO("data") != null)
                            {
                                TypedObject to = result.GetTO("data");
                                if (to.ContainsKey("body"))
                                {
                                    if (to["body"] is TypedObject)
                                    {
                                        new Thread(new ThreadStart(() =>
                                        {
                                            TypedObject body = (TypedObject)to["body"];
                                            if (body.type.Equals("com.riotgames.platform.game.GameDTO"))
                                            {
                                                MessageReceived(new GameDTO(body));
                                            }
                                            else if (body.type.Equals("com.riotgames.platform.game.PlayerCredentialsDto"))
                                            {
                                                MessageReceived(new PlayerCredentialsDto(body));
                                            }
                                            else if (body.type.Equals("com.riotgames.platform.game.message.GameNotification"))
                                            {
                                                MessageReceived(new GameNotification(body));
                                            }
                                            else if (body.type.Equals("com.riotgames.platform.matchmaking.SearchingForMatchNotification"))
                                            {
                                                MessageReceived(new SearchingForMatchNotification(body));
                                            }
                                            //MessageReceived(to["body"]);
                                        })).Start();
                                    }
                                }
                            }
                            //MessageReceived(
                        }

                        if (id == null)
                        {
                            continue;
                        }

                        if (id == 0)
                        {
                        }
                        else if (callbacks.ContainsKey((int)id))
                        {
                            RiotGamesObject cb = callbacks[(int)id];
                            callbacks.Remove((int)id);
                            if (cb != null)
                            {
                                TypedObject messageBody = result.GetTO("data").GetTO("body");
                                new Thread(() =>
                                {
                                    cb.DoCallback(messageBody);
                                }).Start();
                            }
                        }

                        else
                        {
                            results.Add((int)id, result);
                        }

                        pendingInvokes.Remove((int)id);
                    }
                }
                catch (Exception e)
                {
                    if (IsConnected())
                    {
                        Error(e.Message, ErrorType.Receive);
                    }

                    //Disconnect();
                }
            });
            decodeThread.Start();
        }