private void ProcessNetworkBuffer(NetworkConnection connection) { while (connection.NetworkBufferPosition >= 0x1C) { uint bufferSize = 0; byte[] destinationArray; lock (connection.NetworkBufferLock) { var indexes = new List<uint> { BitConverter.ToUInt32(connection.NetworkBuffer, 0), BitConverter.ToUInt32(connection.NetworkBuffer, 4), BitConverter.ToUInt32(connection.NetworkBuffer, 8), BitConverter.ToUInt32(connection.NetworkBuffer, 12) }; if ((indexes[0] != 0x41A05252) && ((indexes.Any(x => x != 0)))) { AdjustNetworkBuffer(connection); return; } bufferSize = BitConverter.ToUInt32(connection.NetworkBuffer, 0x18); if ((bufferSize == 0) || (bufferSize > 0x10000)) { AdjustNetworkBuffer(connection); return; } if (connection.NetworkBufferPosition < bufferSize) { if (DateTime.Now.Subtract(connection.LastNetworkBufferUpdate) .Seconds > 5) { AdjustNetworkBuffer(connection); } break; } destinationArray = new byte[bufferSize]; Array.Copy(connection.NetworkBuffer, destinationArray, bufferSize); Array.Copy(connection.NetworkBuffer, bufferSize, connection.NetworkBuffer, 0L, connection.NetworkBufferPosition - bufferSize); connection.NetworkBufferPosition -= (int) bufferSize; connection.LastNetworkBufferUpdate = DateTime.Now; } if (bufferSize <= 40) { return; } var timeDifference = BitConverter.ToUInt64(destinationArray, 0x10); var time = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(timeDifference) .ToLocalTime(); int limiter = BitConverter.ToInt16(destinationArray, 30); int encoding = BitConverter.ToInt16(destinationArray, 0x20); var bytes = new byte[0x10000]; int messageLength; switch (encoding) { case 0: case 1: messageLength = ((int) bufferSize) - 40; for (var i = 0; i < ((bufferSize / 4) - 10); i++) { Array.Copy(BitConverter.GetBytes(BitConverter.ToUInt32(destinationArray, (i * 4) + 40)), 0, bytes, i * 4, 4); } break; default: try { using (var decompressedStream = new DeflateStream(new MemoryStream(destinationArray, 0x2A, destinationArray.Length - 0x2A), CompressionMode.Decompress)) { messageLength = decompressedStream.Read(bytes, 0, bytes.Length); } } catch (Exception ex) { return; } break; } var position = 0; try { for (var i = 0; i < limiter; i++) { if ((position + 4) > messageLength) { return; } var messageSize = BitConverter.ToUInt32(bytes, position); if ((position + messageSize) > messageLength) { return; } if (messageSize > 0x18) { var networkPacket = new Common.Core.Network.NetworkPacket { Key = BitConverter.ToUInt32(bytes, position + 0x10), Buffer = bytes, CurrentPosition = position, MessageSize = (int) messageSize, PacketDate = time }; AppContextHelper.Instance.RaiseNewPacket(networkPacket); } position += (int) messageSize; } } catch (Exception ex) { return; } } }
private void AdjustNetworkBuffer(NetworkConnection connection) { var startIndex = 1; while ((BitConverter.ToUInt32(connection.NetworkBuffer, startIndex) != 0x41A05252) && (startIndex < connection.NetworkBufferPosition)) { startIndex++; } if (startIndex >= connection.NetworkBufferPosition) { connection.NetworkBufferPosition = 0; } else { Array.Copy(connection.NetworkBuffer, startIndex, connection.NetworkBuffer, 0, connection.NetworkBufferPosition - startIndex); connection.NetworkBufferPosition -= startIndex; } }
private void ParseData(SocketObject asyncState, byte[] byteData, int nReceived) { if ((byteData == null) || (byteData[9] != 6)) { return; } var startIndex = (byte) ((byteData[0] & 15) * 4); var lengthCheck = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(byteData, 2)); if ((nReceived < lengthCheck) || (startIndex > lengthCheck)) { return; } var IP = new IPHeader(byteData, nReceived); var TCP = new TCPHeader(byteData, nReceived); var serverConnection = new ServerConnection { SourceAddress = (uint) BitConverter.ToInt32(byteData, 12), DestinationAddress = (uint) BitConverter.ToInt32(byteData, 16), SourcePort = (ushort) BitConverter.ToInt16(byteData, startIndex), DestinationPort = (ushort) BitConverter.ToInt16(byteData, startIndex + 2), TimeStamp = DateTime.Now /* // these don't return the right ports for some reason DestinationAddress = BitConverter.ToUInt32(IP.DestinationAddress.GetAddressBytes(), 0), DestinationPort = Convert.ToUInt16(TCP.DestinationPort), SourcePort = Convert.ToUInt16(TCP.SourcePort), SourceAddress = BitConverter.ToUInt32(IP.SourceAddress.GetAddressBytes(), 0), TimeStamp = DateTime.Now */ }; lock (Lock) { var found = Enumerable.Contains(ServerConnections, serverConnection); if (!found) { if (Enumerable.Contains(DroppedConnections, serverConnection)) { return; } UpdateConnectionList(); if (!Enumerable.Contains(ServerConnections, serverConnection)) { DroppedConnections.Add(serverConnection); return; } } } if ((startIndex + 12) > nReceived) { return; } var nextTCPSequence = (uint) IPAddress.NetworkToHostOrder(BitConverter.ToInt32(byteData, startIndex + 4)); var cut = (byte) (((byteData[startIndex + 12] & 240) >> 4) * 4); var length = (nReceived - startIndex) - cut; if ((length < 0) || (length > 0x10000)) { return; } if (lengthCheck == startIndex + cut) { return; } lock (asyncState.SocketLock) { var connection = asyncState.Connections.FirstOrDefault(x => x.Equals(serverConnection)); if (connection == null) { connection = new NetworkConnection { SourceAddress = serverConnection.SourceAddress, SourcePort = serverConnection.SourcePort, DestinationAddress = serverConnection.DestinationAddress, DestinationPort = serverConnection.DestinationPort }; asyncState.Connections.Add(connection); } if (length == 0) { return; } var destinationBuffer = new byte[length]; Array.Copy(byteData, startIndex + cut, destinationBuffer, 0, length); if (connection.StalePackets.ContainsKey(nextTCPSequence)) { connection.StalePackets.Remove(nextTCPSequence); } var packet = new NetworkPacket { TCPSequence = nextTCPSequence, Buffer = destinationBuffer, Push = (byteData[startIndex + 13] & 8) != 0 }; connection.StalePackets.Add(nextTCPSequence, packet); if (!connection.NextTCPSequence.HasValue) { connection.NextTCPSequence = nextTCPSequence; } if (connection.StalePackets.Count == 1) { connection.LastGoodNetworkPacketTime = DateTime.Now; } if (!connection.StalePackets.Any(x => (x.Key <= connection.NextTCPSequence.Value))) { if (DateTime.Now.Subtract(connection.LastGoodNetworkPacketTime) .TotalSeconds <= 10.0) { return; } connection.NextTCPSequence = connection.StalePackets.Min(x => x.Key); } while (connection.StalePackets.Any(x => x.Key <= connection.NextTCPSequence.Value)) { NetworkPacket stalePacket; uint sequenceLength = 0; if (connection.StalePackets.ContainsKey(connection.NextTCPSequence.Value)) { stalePacket = connection.StalePackets[connection.NextTCPSequence.Value]; } else { stalePacket = (connection.StalePackets.Where(x => x.Key <= connection.NextTCPSequence.Value) .OrderBy(x => x.Key)).FirstOrDefault() .Value; sequenceLength = connection.NextTCPSequence.Value - stalePacket.TCPSequence; } connection.StalePackets.Remove(stalePacket.TCPSequence); if (connection.NetworkBufferPosition == 0) { connection.LastNetworkBufferUpdate = DateTime.Now; } if (sequenceLength >= stalePacket.Buffer.Length) { continue; } connection.NextTCPSequence = stalePacket.TCPSequence + ((uint) stalePacket.Buffer.Length); Array.Copy(stalePacket.Buffer, sequenceLength, connection.NetworkBuffer, connection.NetworkBufferPosition, stalePacket.Buffer.Length - sequenceLength); connection.NetworkBufferPosition += stalePacket.Buffer.Length - ((int) sequenceLength); if (stalePacket.Push) { ProcessNetworkBuffer(connection); } } } }