public UltimaClientConnection(UltimaClientConnectionStatus status, IDiagnosticPullStream diagnosticPullStream,
     IDiagnosticPushStream diagnosticPushStream, PacketDefinitionRegistry packetRegistry,
     EncryptionSetup encryption, LoginEncryptionKey? configuedLoginEncryptionKey)
 {
     this.diagnosticPullStream = diagnosticPullStream;
     this.diagnosticPushStream = diagnosticPushStream;
     this.encryption = encryption;
     this.configuedLoginEncryptionKey = configuedLoginEncryptionKey;
     Status = status;
     packetLogParser = new PacketLogParser(packetRegistry);
     loginStream = new LoginPullStream();
     loginStream.BaseStream = diagnosticPullStream;
     receiveNewGameStream = new ClientNewGamePullStream();
     receiveNewGameStream.BaseStream = diagnosticPullStream;
     sendNewGameStream = new ClientNewGamePushStream();
 }
        private int ReceiveSeed(IPullStream inputStream, int batchLength, UltimaClientConnectionStatus nextStatus)
        {
            int byteReceived = 0;

            if (receivedPosition == 0)
            {
                var firstByte = inputStream.ReadByte();
                byteReceived++;
                receivedPosition++;
                receivedSeed[0] = (byte)firstByte;
                if (firstByte != 0xEF)
                {
                    var seed = new byte[4];
                    inputStream.Read(seed, 1, 3);
                    seed[0] = (byte)firstByte;
                    var packet = new Packet(PacketDefinitions.LoginSeed.Id, seed);
                    OnPacketReceived(packet);
                    Status = nextStatus;
                    receivedPosition = 0;
                    this.loginSeed = BitConverter.ToUInt32(seed.Reverse().ToArray(), 0);
                    if (requiresEncryption)
                    {
                        receiveNewGameStream = new ClientNewGamePullStream(seed);
                        receiveNewGameStream.BaseStream = diagnosticPullStream;
                        sendNewGameStream = new ClientNewGamePushStream(seed);
                        NewGameEncryptionStarted?.Invoke(seed);
                    }
                    else if (encryption == EncryptionSetup.EncryptedServer)
                    {
                        NewGameEncryptionStarted?.Invoke(seed);
                    }

                    return 4;
                }
            }

            if (batchLength > byteReceived)
            {
                var remaining = 21 - receivedPosition;
                var len = batchLength - byteReceived;
                len = (len > remaining) ? remaining : len;
                inputStream.Read(receivedSeed, receivedPosition, len);
                receivedPosition += len;
                byteReceived += len;
            }

            if (receivedPosition >= 21)
            {
                var packet = new Packet(PacketDefinitions.ExtendedLoginSeed.Id, receivedSeed);
                OnPacketReceived(packet);
                Status = nextStatus;
                receivedPosition = 0;

                this.loginSeed = BitConverter.ToUInt32(receivedSeed.Skip(1).Take(4).Reverse().ToArray(), 0);

                var reader = new ArrayPacketReader(receivedSeed);
                reader.Skip(5);
                encryptionVersion = new Version(reader.ReadInt(), reader.ReadInt(), reader.ReadInt(), reader.ReadInt());

                if (requiresEncryption)
                {
                    receiveNewGameStream = new ClientNewGamePullStream(receivedSeed);
                    receiveNewGameStream.BaseStream = diagnosticPullStream;
                    sendNewGameStream = new ClientNewGamePushStream(receivedSeed);
                    NewGameEncryptionStarted?.Invoke(receivedSeed);
                }
                else if (encryption == EncryptionSetup.EncryptedServer)
                {
                    NewGameEncryptionStarted?.Invoke(receivedSeed);
                }
            }

            return byteReceived;
        }