Esempio n. 1
0
        public void Receive(IPullStream inputStream)
        {
            var processingStream = GetReceiveStream(inputStream);

            while (inputStream.DataAvailable)
            {
                var packetReader = new StreamPacketReader(processingStream, receiveBuffer);
                int packetId     = packetReader.ReadByte();
                if ((packetId < 0) || (packetId > 255))
                {
                    throw new EndOfStreamException();
                }

                diagnosticPullStream.StartPacket();
                var packetDefinition = PacketDefinitionRegistry.Find(packetId);
                var packetSize       = packetDefinition.GetSize(packetReader);
                packetReader.ReadBytes(packetSize - packetReader.Position);
                var payload = new byte[packetSize];
                Array.Copy(receiveBuffer, 0, payload, 0, packetSize);

                var packet = new Packet(packetId, payload);

                if (packetId == PacketDefinitions.ConnectToGameServer.Id)
                {
                    Status = ServerConnectionStatus.PreGame;
                }

                diagnosticPullStream.FinishPacket(packet);

                OnPacketReceived(packet);
            }
        }
Esempio n. 2
0
 public static IEnumerable <Packet> ParseBatch(IPullStream inputStream)
 {
     while (inputStream.DataAvailable)
     {
         yield return(ParsePacket(inputStream));
     }
 }
 public DiagnosticPacketReader(Stream inputStream, PacketDefinitionRegistry packetRegistry)
 {
     this.inputStream    = inputStream;
     this.packetRegistry = packetRegistry;
     inputStreamReader   = new BinaryReader(inputStream);
     pullStream          = new StreamToPullStreamAdapter(this.inputStream);
     packetLogParser     = new Parsers.PacketLogParser(packetRegistry);
 }
Esempio n. 4
0
        private void ReceiveSeed(IPullStream inputStream)
        {
            var payload = new byte[4];

            inputStream.Read(payload, 0, 4);
            var packet = new Packet(PacketDefinitions.LoginSeed.Id, payload);

            OnPacketReceived(packet);
        }
Esempio n. 5
0
        public void Process(IPullStream inputStream)
        {
            var processingStream = GetReceiveStream(inputStream);

            while (inputStream.DataAvailable)
            {
                var packet = Receive(processingStream);
                OnPacketReceived(packet);
            }
        }
        public void ReceiveBatch(IPullStream inputStream, int batchLength)
        {
            diagnosticPullStream.BaseStream = inputStream;
            IPullStream currentStream = diagnosticPullStream;

            switch (Status)
            {
                case UltimaClientConnectionStatus.Initial:
                    ReceiveSeed(diagnosticPullStream, batchLength, UltimaClientConnectionStatus.AfterInitialSeed);
                    currentStream = loginStream;
                    DetectEncryption(diagnosticPullStream);
                    break;
                case UltimaClientConnectionStatus.AfterInitialSeed:
                    DetectEncryption(diagnosticPullStream);
                    currentStream = loginStream;
                    break;
                case UltimaClientConnectionStatus.ServerLogin:
                    currentStream = loginStream;
                    break;
                case UltimaClientConnectionStatus.PreGameLogin:
                    ReceiveSeed(diagnosticPullStream, batchLength, UltimaClientConnectionStatus.GameLogin);
                    currentStream = receiveNewGameStream;
                    break;
                case UltimaClientConnectionStatus.GameLogin:
                case UltimaClientConnectionStatus.Game:
                    currentStream = receiveNewGameStream;
                    break;
            }

            foreach (var packet in packetLogParser.ParseBatch(currentStream))
            {
                OnPacketReceived(packet);

                switch (Status)
                {
                    case UltimaClientConnectionStatus.ServerLogin:
                        if (packet.Id == PacketDefinitions.SelectServerRequest.Id)
                            Status = UltimaClientConnectionStatus.PreGameLogin;
                        break;
                    case UltimaClientConnectionStatus.GameLogin:
                        if (packet.Id == PacketDefinitions.GameServerLoginRequest.Id)
                            Status = UltimaClientConnectionStatus.Game;
                        break;
                }
            }
        }
Esempio n. 7
0
        public static Packet ParsePacket(IPullStream inputStream)
        {
            byte[] buffer = new byte[65535];

            var reader = new StreamPacketReader(new PullStreamToStreamAdapter(inputStream), buffer);

            int packetId     = reader.ReadByte();
            int packetLength = GetPacketLength(reader, packetId);

            reader.ReadBytes(packetLength - reader.Position);

            var payload = new byte[packetLength];

            Array.Copy(buffer, 0, payload, 0, packetLength);

            return(new Packet(packetId, payload));
        }
Esempio n. 8
0
        private Stream GetReceiveStream(IPullStream inputStream)
        {
            diagnosticPullStream.BaseStream = inputStream;

            switch (Status)
            {
            case ServerConnectionStatus.PreLogin:
                return(preLoginStream);

            case ServerConnectionStatus.Game:
                receiveNewGameStream.BaseStream = diagnosticPullStream;

                return(huffmanStream);

            default:
                throw new NotImplementedException($"Unknown Status: {Status}");
            }
        }
Esempio n. 9
0
        public LoginEncryptionDetectionResult Detect(uint seed, IPullStream inputStream, Version defaultVersion)
        {
            var reader = new StreamPacketReader(new PullStreamToStreamAdapter(inputStream), rawBuffer);
            var length = 0;

            while (inputStream.DataAvailable && length < 62)
            {
                rawBuffer[length++] = reader.ReadByte();
            }

            rawBuffer.CopyTo(decryptedBuffer, 0);

            var versionsToTest = GetVersionsToTest(defaultVersion).GetEnumerator();

            LoginEncryptionKey?currentKey = null;
            LoginCrypt         loginCrypt = null;

            while (!IsGameServerPacket(decryptedBuffer))
            {
                if (!versionsToTest.MoveNext())
                {
                    break;
                }
                var version = versionsToTest.Current;

                currentKey = LoginEncryptionKey.FromVersion(version);
                loginCrypt = new LoginCrypt(seed, currentKey.Value);
                loginCrypt.Decrypt(rawBuffer, decryptedBuffer, 62);
            }

            if (currentKey.HasValue)
            {
                return(new LoginEncryptionDetectionResult(decryptedBuffer, loginCrypt, currentKey.Value));
            }
            else
            {
                return(new LoginEncryptionDetectionResult(decryptedBuffer));
            }
        }
Esempio n. 10
0
        public void ReceiveBatch(IPullStream inputStream)
        {
            diagnosticPullStream.BaseStream = inputStream;

            switch (Status)
            {
            case UltimaClientConnectionStatus.Initial:
                ReceiveSeed(diagnosticPullStream);
                Status = UltimaClientConnectionStatus.ServerLogin;
                break;

            case UltimaClientConnectionStatus.PreGameLogin:
                ReceiveSeed(diagnosticPullStream);
                Status = UltimaClientConnectionStatus.GameLogin;
                break;
            }

            foreach (var packet in PacketLogParser.ParseBatch(diagnosticPullStream))
            {
                OnPacketReceived(packet);
                switch (Status)
                {
                case UltimaClientConnectionStatus.ServerLogin:
                    if (packet.Id == PacketDefinitions.SelectServerRequest.Id)
                    {
                        Status = UltimaClientConnectionStatus.PreGameLogin;
                    }
                    break;

                case UltimaClientConnectionStatus.GameLogin:
                    if (packet.Id == PacketDefinitions.GameServerLoginRequest.Id)
                    {
                        Status = UltimaClientConnectionStatus.Game;
                    }
                    break;
                }
            }
        }
Esempio n. 11
0
        public Packet ParsePacket(IPullStream inputStream)
        {
            byte[] buffer = new byte[65535];

            var reader = new StreamPacketReader(new PullStreamToStreamAdapter(inputStream), buffer);

            int packetId = reader.ReadByte();

            try
            {
                int packetLength = GetPacketLength(reader, packetId);
                reader.ReadBytes(packetLength - reader.Position);

                var payload = new byte[packetLength];
                Array.Copy(buffer, 0, payload, 0, packetLength);

                return(new Packet(packetId, payload));
            }
            catch (Exception ex)
            {
                throw new EndOfStreamException($"EndOfStreamException occured when reading packet {packetId:X2}", ex);
            }
        }
        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;
        }
Esempio n. 13
0
 public Packet Receive(IPullStream inputStream)
 => Receive(GetReceiveStream(inputStream));
Esempio n. 14
0
 public PullStreamToStreamAdapter(IPullStream baseStream)
 {
     BaseStream = baseStream;
 }
Esempio n. 15
0
 public DiagnosticPacketReader(Stream inputStream)
 {
     this.inputStream  = inputStream;
     inputStreamReader = new BinaryReader(inputStream);
     pullStream        = new StreamToPullStreamAdaptet(this.inputStream);
 }