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 Basic Header #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 Message Header #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 Message Body // 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.gameinvite.contract.InvitationRequest")) MessageReceived(new InvitationRequest(body)); else if ( body.type.Equals("com.riotgames.platform.gameinvite.contract.InvitationRequest")) MessageReceived(new Inviter(body)); else if ( body.type.Equals("com.riotgames.platform.serviceproxy.dispatch.LcdsServiceProxyResponse")) MessageReceived(new LcdsServiceProxyResponse(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)); else if ( body.type.Equals( "com.riotgames.platform.broadcast.BroadcastNotification")) MessageReceived(new BroadcastNotification(body)); else if ( body.type.Equals( "com.riotgames.platform.messaging.StoreAccountBalanceNotification")) MessageReceived(new StoreAccountBalanceNotification(body)); else if ( body.type.Equals( "com.riotgames.platform.messaging.persistence.SimpleDialogMessage")) MessageReceived(new SimpleDialogMessage(body)); else if ( body.type.Equals( "com.riotgames.platform.trade.api.contract.TradeContractDTO")) MessageReceived(new TradeContractDTO(body)); else if ( body.type.Equals( "com.riotgames.platform.statistics.EndOfGameStats")) MessageReceived(new EndOfGameStats(body)); else if ( body.type.Equals( "com.riotgames.platform.gameinvite.contract.LobbyStatus")) MessageReceived(new LobbyStatus(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.IsBackground = true; decodeThread.Start(); }
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 Basic Header #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 Message Header #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 Message Body // 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")) { System.Diagnostics.Debug.WriteLine(result.GetTO("data")["faultString"]); 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.gameinvite.contract.InvitationRequest")) { MessageReceived(new InvitationRequest(body)); } else if ( body.type.Equals("com.riotgames.platform.gameinvite.contract.InvitationRequest")) { MessageReceived(new Inviter(body)); } else if ( body.type.Equals("com.riotgames.platform.serviceproxy.dispatch.LcdsServiceProxyResponse")) { MessageReceived(new LcdsServiceProxyResponse(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)); } else if ( body.type.Equals( "com.riotgames.platform.broadcast.BroadcastNotification")) { MessageReceived(new BroadcastNotification(body)); } else if ( body.type.Equals( "com.riotgames.platform.messaging.StoreAccountBalanceNotification")) { MessageReceived(new StoreAccountBalanceNotification(body)); } else if ( body.type.Equals( "com.riotgames.platform.messaging.persistence.SimpleDialogMessage")) { MessageReceived(new SimpleDialogMessage(body)); } else if ( body.type.Equals( "com.riotgames.platform.trade.api.contract.TradeContractDTO")) { MessageReceived(new TradeContractDTO(body)); } else if ( body.type.Equals( "com.riotgames.platform.statistics.EndOfGameStats")) { MessageReceived(new EndOfGameStats(body)); } else if ( body.type.Equals( "com.riotgames.platform.harassment.HarassmentReport")) { MessageReceived(new LobbyStatus(body)); } else if ( body.type.Equals( "com.riotgames.platform.gameinvite.contract.LobbyStatus")) { MessageReceived(new LobbyStatus(body)); } else if (body.type.Equals( "com.riotgames.platform.messaging.ClientLoginKickNotification")) { MessageReceived(new ClientLoginKickNotification(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.IsBackground = true; decodeThread.Start(); }