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); } }
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); }
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); }
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; } } }
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)); }
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}"); } }
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)); } }
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; } } }
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; }
public Packet Receive(IPullStream inputStream) => Receive(GetReceiveStream(inputStream));
public PullStreamToStreamAdapter(IPullStream baseStream) { BaseStream = baseStream; }
public DiagnosticPacketReader(Stream inputStream) { this.inputStream = inputStream; inputStreamReader = new BinaryReader(inputStream); pullStream = new StreamToPullStreamAdaptet(this.inputStream); }